Sjov med optimering af lagerplads på ekstern USB disk

Dette forum bruges på EGET ANSVAR til at lege med scripts og andre ting med risiko for at beskadige sit eget og andres systemer.
lath
Indlæg: 5095
Tilmeldt: 27. apr 2008, 02:16
IRC nickname: lars_t_h
Geografisk sted: Fyn

Sjov med optimering af lagerplads på ekstern USB disk

Indlæg af lath »

Jeg har lige lavet et spændende lille forsøg med at optimere diskpladsen på en 8 GB USB flash drev.

Den havde i starten et FAT32 filsystem, der ikke var så glad for en backup af nogle Git repositories, som benytter sig af soft-links.
Det var jeg ret så utilfreds med, så jeg måtte jo have et andet filstem i brug, det blev ext4 filsystemet, som jeg så tweakede ret kraftigt.

Lader man GParted bare lave et ext4fs filsystem med alle standardinstillinger, så får man 4KB sektorer, og der bruges lige under de 300 MB plads til husholdings-information om filsystemet.
Sandsynligvis bruges også et for lavt antal inodes, som er dem man bruger af hver gang man bruger mere plads i et filsystem.

Det måtte kunne gøres bedre, så jeg kørte den her kommando (forklaring følger til sidst):

Kode: Vælg alt

sudo mke2fs -t ext4 -m 0.01 -I 128 -i 1024 -D -b 1024 -O dir_index,filetype,sparse_super /dev/sdb1

Den svarer med det her:
mke2fs 1.42.5 (29-Jul-2012)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
7881192 inodes, 7881068 blocks
788 blocks (0.01%) reserved for the super user
First data block=1
Maximum filesystem blocks=75161856
963 block groups
8184 blocks per group, 8184 fragments per group
8184 inodes per group
Superblock backups stored on blocks:
8185, 24553, 40921, 57289, 73657, 204601, 220969, 401017, 662905,
1023001, 1988713, 2807113, 5115001, 5966137

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done


Så er man naturlig nysgerrig over hvor mange inodes der i brug, så man kører:

Kode: Vælg alt

df -i

... og får i mit tilfælde (pseudo filsystemerne /dev, /run, /run/lock, /run/shm, og run/user er udeladt):
Filsystem,Inoder,IBrugt,IFri,IBrug%,Monteret på
/dev/sda7,2097152,674894,1422258,33%,/
/dev/sda2,262144,331,261813 ,1%,/boot
/dev/sda3,15147008,314351,14832657,3%,/home
/dev/sdb1,7881192,11,7881181,1%,/media/lars/46a6c425-8c49-4148-811a-c3430822b685

inodes i brug er kun for de filer/og mapper der er i brug - og på det her tidspunkt har jeg ikke gemt noget i filsystemet endnu.

Bruger jeg lige GParted,så fortæller den mig at der bruges, 1000,17 MiB, sådan bare til at strte med - uden at der er gemt noget i filsystemet.
Det er meget mere end standard valgene, som giver et pladsforbrug lige under de 300 MB, men så har jeg også tweaket filsystemet , så det passer til min anvendelse: At gemme en masse små filer - effektivt.

Med oprettelsen af mit eget optimerede filsystem undgår jeg det der kaldes for intern fragmentering.
Intern fragmentering er den lagerplads der er spildt fordi der gemmes data i filer så har de meget få data i forhold til sektor størrelsen.
Feks. hvis du vil lagre en fil på lad os sige 123 bytes, og en inode peger på en 4 KiB=4096 bytes lagerplads, så er der en spildt plads (intern fragmentering) på 4096 - 123 bytes = 3.973 bytes for den fil.
Hvis nu en inode peger på en lagerplads der kun er 1 KiB=1024 bytes stor, så er den interne fragmentering for den fil kun på: 1024 -123 bytes = 901 bytes.
Dermed har jeg vundet 3.973 - 901 bytes = 3072bytes = 3KiB fri disk diskplads for den fil ved at benytte mig af en sektor størrelse på 1 KiB.

Nu gennemgår jeg argumenterne til mke2fs:
  • sudo: mke2fs er en superbruger kommando, så der kræves superbruger privilegerer for at kunne køre den.
  • mke2fs er selve kommandoen, der opretter filsystemer.
  • -t ext4 : t argumenter angiver det filsystem du vil bruge, her er det et ext4 filsystem.
  • -m 0.01: m argumentet angiver, hvor meget plads der skal reserveres til superbrugeren, root.
    Jeg har valgt mindst muligt (1%), da jeg bruger filsystemet til daglig backup af mine filer fra min alm uprivilegerede brugerkonto.
  • -I 128 : I argumenet er inode størrelsen i bytes.
    Manual siden beskriver I argumentet nærmere:
    Specify the size of each inode in bytes. mke2fs creates 256-byte inodes by default. In kernels after 2.6.10 and
    some earlier vendor kernels it is possible to utilize inodes larger than 128 bytes to store extended attributes
    for improved performance. The inode-size value must be a power of 2 larger or equal to 128. The larger the
    inode-size the more space the inode table will consume, and this reduces the usable space in the filesystem and
    can also negatively impact performance. Extended attributes stored in large inodes are not visible with older
    kernels, and such filesystems will not be mountable with 2.4 kernels at all. It is not possible to change this
    value after the filesystem is created.
  • -i 1024 : i argumentet er bytes per inode ratioen.
    Manualen om i argumentet:
    mke2fs creates an inode for every bytes-per-inode bytes of space on the disk.
    The larger the bytes-per-inode ratio, the fewer inodes will be created. This value generally shouldn't be
    smaller than the blocksize of the filesystem, since in that case more inodes would be made than can ever be used.
    Be warned that it is not possible to expand the number of inodes on a filesystem after it is created, so be care‐
    ful deciding the correct value for this parameter.
  • -D D argumentet er brug af direkte I/O, når kommandoen skal skrive til disken. Direkte I/O er meget langsommere.
    mke2fs uden brug af direkte I/O får diskbufferen til at blive 'beskidt', så nogle programmer kan køre langsommere.
    Du kan udelade -D argumentet.
  • -b 1024 b argumentet specificerer blokstørrelsen
    Manualen om b argumentet:
    Valid block-size values are 1024, 2048 and 4096 bytes per block. If omit ted, block-size is heuristically determined by the filesystem size and the expected usage of the filesystem (see the -T option). If block-size is preceded by a negative sign ('-'), then mke2fs will use heuristics to determine the appropriate block size, with the constraint that the block size will be at least block-size bytes. This is useful for certain hardware devices which require that the blocksize be a multiple of 2k.
  • -O (stort bogstav O, ikke tallet nul) er filstystem options, ekstra funktionalitet.
    Bemærk at flere værdier til O argumentet adskilles af et komma-uden mellemrumstegn imellem værdierne.
  • dir_index (værdi til -O argumentet): Brug et såkaldt treap binært søgetræ til fil og mappe navne i meget store mapper.
    Treap binært søgetræ: http://en.wikipedia.org/wiki/Treap
    • Treap binære søgetræer i filsystemet gør det ekstremt effektivt, når filsystemet skal finde/indsætte/ændre i/eller slette en bestemt fil eller mappe i mapper med mange filer og/eller under-mapper.
    • Et godt eksempel er /usr/bin som det tager intet mindre end hele 43 sekunder for min filmanager at kværne igennem, Min /usr/bin mappe indeholder 3.372 filer og/eller mapper.
    • Treap Binære søgetræer kan lave en søgning på noget der kaldes store-O(log2(n)), som er at den er 2-tals (binær) logaritmisk om en søgning/indsætning/og sletning operation i treap binær søgetræet. Best af alt så fylder den -store-O(n) - altså lige så meget som en helt almindelig liste af filer, som er meget langsommere at lave noget med.
    • Det vil sige at med 3.372 filer i /usr/bin vil et treap binært søgetræ kunne finde hver eneste af de 3.372 filer og/eller undermapper efter kun log2(3.372) søgninger = ln(3.372) /ln(2) søgninger = 12 søgninger.
    • Uden et binært søgetræ vil man i gennemsnit skulle lave store-O(n) søgninger = 3.372 søgninger. (linked list)
  • filetype (værdi til -O argumentet): Gem filtype information i mappe-indgange
  • sparse_super (værdi til -O argumentet): Lav et filsystem med færre superblock backups. sparer diskplads i store filsystemer.
    Min kommentar: Jeg har et lille filsystem og bruger den, fordi et når et flash drev fejler på grund wear-out, så fejler hel disken typisk, og så kan flere backups af super blocks være lige meget. Jeg bruger i stedet flere flash drev af forskelligt fabrikat (så de ikke fejler samtidigt af den samme årsag, f.eks. fabrikationsfejl).
  • /dev/sdb1 : partition som skal have det filsystem der angives med t argumentet.
    Vigtigt!: Tjek og dobbelt-tjek at du bruger det rigtige drev, /dev/sda er næsten altid harddisken med dit Ubuntu system på, så den skal du ikke bruge, medmindre du altså forbereder en harddisk for en total geninstallation af en nyere version af Ubuntu, f.eks. den kommende Ubuntu 14.04 LTS.
    Du skal også bruge en partition - ikke et drev. Du bruger et drev hvis der ikke er et tal.
    F.eks. så er /dev/sdb et drev, hvorimod /dev/sdb1 er 1. partition på deb/sdb, og /dev/sdb2 er 2. partition på /dev/sdb.

/Lars

Big-O Cheat Sheet: http://bigocheatsheet.com/
Jeg er Software ingeniør (Diplomingeniør) i Informationsteknologi og indlejede systemer, hvor indlejrede systemer er computer (microcontroller) + elektronik i for eksempel et TV, en router, en vaskemaskine og den slags