Ezt most nem ertem. deb/lenny alatt, ext3fs: ha egy konyvtarat feltoltok file-okkal, szep sorrendben, majd egyesevel probalom elerni (masolas, feldolgozas, `ls -U`, barmi), akkor teljesen veletlenszeruen jonnek a file-ok. Mondhatni, kriptografiailag is megbizhato veletlenszamgeneratort kapunk... (najo talan nem, de annyira random hogy semmi rendszert nem ve'lek felfedezni benne). Ez viszont igy nyilvan nem az igazi es ez nem kifejezes (lasd: szekvencialis eleres; random seekek; uninterruble sleep, reszponzivitas hianya; diszk elettartama; ...)
Tehat ezt most igy hogy?
Pelda:
#!/bin/sh
mkdir files
for f in `seq -w 1 1000` ; do echo $f > files/$f.dat ; done
ls -U files | sed 's/\.dat//g' > out
gnuplot> plot 'out' u 0:1 w p pt 2
Hozzászólások
E? senki sem tapasztalt ilyesmit? miert nem irnak a man-ok errol semmit?
Ha jol emlekszem az ext3 manualbol, akkor a dir_index mount opcioval lehet kapcsolgatni, hogy hash-be tegye-e a dir. entryket. Defaultbol persze be van kapcsolva, es ez megmagyarazna, hogy miert is jon total random minden alkalommal.
man mount, es az ext3 kornyeken nezz korbe.
Ha nem, akkor paff, nemtom, google.
Egen, ez az. Koszi. Csakhat ez az opcio mar ket debiannal korabban is megvolt, es akkor nem kavarta ossze. Mindegy, most akkor lehet vegigmenni a sok ext3-on hogy ne csinaljon ilyet.
Eh, ez az etch => lenny atallas nagyon nyugos, sok aprosag jott elo" (portmap fagyas, lilo+raid, hwaddr forditva, ...).
Hozza kell tennem, ez igy ronda. Es ha egyszer mentesbol kell visszallitani a file-okat, akkor szejjelmegy az egesz rendszered? Tudtommal nincs olyan archivalo eszkoz, ami a file-ok sorrendjet is megtartana (mar a dump-ot kiveve).
Sokkal normalisabb ennel meg az is, hogy minden file ele odarakod a millisec pontossagu 64 bites epoch time-ot, vagy ilyesmi, es siman filenevre rendezel.
Ronda, ronda... oke. Csak ott a masik veglet is. Leirok egy konyvtarba 2000 db 5megas file-t (ez elofordul). Sorrendben, szepen lekeletkezik. Ha barmilyen modon el akarom erni, feldolgozni, ugy hogy a nyers sorrendre hagyatkozok (pl a program azt csinalja hogy "szaladj vegig ennek meg ennek a konyvtarnak a file-jain), akkor szarra'megy a diszk. hasonloan masolaskor, tar-ozaskor, biztonsagi menteskor, stb. detto.
7200rpm-es sata diszken az átlagos see ktime olvasásnál 9ms.
Átlagosan rosz esetben tehát lesz 18 másodperc seek time. Mentésnél másolásnál ekkora mennyiségű adatnál ez szerintem nem mérvadó.
Ha mégis, akkor irigylem a problémáidat. :)
Egyébként meg előbb utóbb a fájlrendszered úgyis fragmentálódik.
Ha tényleg olyan fontos az a pár másodperc, akkor jobban jársz 15k rpm-es diszkekkel, vagy SSD-vel.
A random eleres nagyon rossz minden diszknek. ha a file-meret kisebb vagy kb ugyanakkor mint a seekido szorozva a szekvencialis i/o sebesseggel, akkor ez a random eleres hazavagja a vasat. Ez neha elofordult, es me' elo" is fog fordulni, szoval szempont lehet.
Nem mondtam, hogy jó, csak azt, hogy nem fogod tudni értelmes és tartós módon elkerülni.
Illetve igen: használj SSD-t vagy ramdiszket.
Szemet szúrt a téma, és gyorsan rávetettem magam az Etch-re.
Létrehozási sorrend: 1.txt, 2.txt 6.txt 3.txt
ls- U sorrend: 2.txt, 1.txt, 3.txt, 6.txt
majd létrehoztam még: 4.txt, 5.txt
ls- U sorrend: 2.txt, 1.txt, 3.txt, 4.txt, 5.txt, 6.txt
Ugyanez Lenny-n: 1,3,2,6 majd 4,1,3,2,5,6
Szóval tényleg totál random. Jó ez a dolog amúgy valamire? Az is igaz, hogy ha nem merül fel a téma, nyugodtan éltem volna tovább :).
Etch-re.
etch? ott ezt nem csinalta... legalabbis nekem...
Jó ez a dolog amúgy valamire?
hat hogy mire _nem_ jo azt tudom. egyebkent nem ertem, amennyire en ismerem az ilyen tree-jellegu implementaciokat, eleg extrem ez a sorrend. bar ha hashtree-t hasznal, akkor mondjuk valahol meg lehet ideologizalni. mar egy crc32 is jol kever, ilyen celokra pont jo hash.
Hevenyészve, spekulálva, bizonyítékok nélkül,
-olsz egy file-t, akkor az adott könyvtárban meg kell keresni a megfelelő entry-t (ehhez a könyvtár-file blokkjait kell olvasni), majd a megtalált név->inode leképezés alapján el kell menni az inode-ot tartalmazó diszk blokkhoz a metaadatokért. Amikor egy
-t csinálsz, akkor a könyvtárat is végig kell olvasni, meg mindegyik hivatkozott inode-ot is meg kell nyitni.
A 3. lépésben leírtak már az
-nél is rángatták a fejet, részben ezért vezették be az ext2-nél a
opciót, ami a könyvtárbejegyzésben duplikálta az inode-ból a file típusát (az nem tud megváltozni az inode-ban, ezért nem gond, ha akárhány link van is az inode-ra). A directory-file blokkjainak végigolvasására alapból a
függvény szolgált (megfelelő megnyitás után, persze). Ha megnézed, hogy a visszaadott entry mit tartalmazott hordozhatóan, akkor csak egy nevet és egy inode number-t találsz. Ha viszont a linuxos (mint kernel)
manlapot nézed meg, ott látsz még egy
-ot is, ami pontosan a fenti
funkció miatt elérhető.
Régen a könyvtárak szervezése szekvenciális volt. Ebből két következmény fakadt:
-rel a bejegyzéseket, ahogy létrehoztad (legalábbis akkor, ha a könyvtárban korábban sosem volt több file, ezért mindig a végére ragasztott létrehozáskor),
A második felgyorsítására kitalálták, hogy fába szervezik (O(log(n)), vagy hash-be (ha ritkán módosul a könyvtár, akkor ez megéri, mert az újraszervezés ugyan drága, de utána a lookup O(1)), ez viszont agyonvágta az elsőt. Annak idején a reiserfs körül volt valami hiszti, még a különféle szabványok bizottságai is hozzászóltak, ha jól emlékszem: a felhasználók (userspace programozók) ragaszkodtak a szekvenciális végigolvasáshoz (
,
,
), az új fs fejlesztőinek viszont nyűg volt, mert az új implementációt visszafogta az, hogy kompatibilisnek kellett maradni a régi felülettel.
Egy 2005. nov. 30-ai feljegyzésem szerint egy régebbi (2.4.32) kernelen már volt
opció az ext2-nél is, de a kernel csak akkor vette figyelembe, ha ext3-ként volt mount-olva, és úgy is csak akkor, ha valóban ext3-ként volt használva, azaz
flaggal. Az újabb kerneleken (2.6) már önmagában is megy a
ext2-vel (és én a mai napig ext2-t használok). Tehát ha régi kernelen kapcsoltál be
-et, akkor hatástalan volt.
Gyakori feladat egy könyvtár végigolvasása, és minden egyes file megnyitása. Ez ugye a fentiek szerint miből tevődik össze:
függvényt. (Szerkesztés: ez baromság volt, az openat()-ot egyáltalán nem erre találták ki. Bocsánat.) Drepper mester bemutatja, hogyan kell használni. Az
által visszaadott fd-ből utána lehet
-nel stdio stream-et csinálni.
-os módszerrel is.
Ez irdatlan fejrángatást jelent. Egy kicsit azonban lehet trükközni (persze nem hordozhatóan), és állítom, hogy ez a negyedik alkalom, hogy ezt leírom a hupon.
Először is, a
sysctl-t vegyük le 1-re; így lényegében a directory blokkjai és az inode-ok blokkjai nem fognak kikerülni a kernelmemóriából, ha már egyszer bekerültek. Akárhogy érjük is el az entry-ket, legalább a fejet nem kell rángatni, csak az adatblokkokhoz.
Az adatblokkokon pedig azzal lehet segíteni, hogy az ext2 (ext3 is talán) meghálálja az alábbi tevékenységet:
és ezt ismételgetjük. Ilyenkor az új file létrehozásakor növekvő inode számot kapunk, az adatblokkok pedig nemcsak file-okon belül fognak egymás után elhelyezkedni a diszken, hanem a file-ok is szépen egymás mellé lesznek pakolva.
A felhasználás módja pedig az, hogy a könyvtárat beolvassuk úgy, ahogy (amúgy is dentry cache-ből jön), lerendezzük inode szám szerint, majd végigolvassuk a file-okat. Mivel az inode blokkok is cache-ben vannak, a fejnek el sem kell mozdulnia az adatblokkok fölül. Az adatblokkok pedig mind file-on belül szekvenciálisan helyezkednek el, mind (az inode szerint növekvő file-elérés miatt) file-ok között ugrándozás nélkül következnek.
Az lbzip2 teszteléséhez felhasználtam ezt a fuzz-olt test suite-ot. 321818 kerge bz2 file van benne, amelyeket egy könyvtárba bontott ki. Amikor egy ilyen könyvtárat letöröltem, alapból név szerint rendezve, ahol a név a tartalom SHA1-e volt, vagyis lényegében random, nagyon sokat kellett várnom. Inode szerint rendezve 1000*-es gyorsulást értem el (megmértem).
Szerkesztés: ellenőriztem a tavaly októberi post-omat, rosszul emlékeztem. Egyrészt nem (csak) rm volt, hanem előtte grep, másrészt az 1000*-es szorzót most a légből kaptam, nem mértem meg. Mindenesetre azt írtam, hogy "iszonyatos" volt a gyorsulás.
Vagyis ha tar-hoz kell a dolog, akkor
.
A fentieknek megfelelően, ha sparse file-t hozunk létre és össze-vissza seek-elve írjuk, vagy preallokáció nélkül írogatunk ötven file-nak mindig a végére, akkor azokat a file-okat szekvenciálisan végigolvasni lesz katasztrófa. Pont erre találták ki az extent-eket, hogy előre le lehessen foglalni az összefüggő területet kézi végigírás nélkül, és persze van hordozható API-ja is (ami nyilván nem beszél a lefoglalt terület összefüggőségéről (It is implementation-defined whether a previous posix_fadvise() call influences allocation strategy), de ettől az még minden épkézláb OS-en nyilván össze fog függeni).