Memóriában dolgozás

Fórumok

Sziasztok,

Némi információra van szükségem. Egy adatbázist beakarok tölteni a memóriába és szeretnék onnan dolgozni, hogy még gyorsabb legyen. Ezt a cat paranccsal szépen be is tudom tölteni és látom, is hogy bekerült. Ugyan akkor én úgy érzem, hogy nem onnan dolgozik az adatbázis, hanem csak betöltöttem az adatbázis fájlokat és ott vannak, de az adatbázis továbbra is a diszken lévő fájlokat használja.
Nem tudok konkrét adatbáziskezelőt mondani, mert független.
A kérdésem igazából, csak annyi, hogy ha cat-el valamit beteszek a /dev/null-ba akkor az csak ott van, de nem történik vele semmi. Jól sejtem?

Hozzászólások

nem tudom eldonteni hogy ez most komoly vagy kesoi aprilis 1.

ha arra gondolsz hogy cache-ben benne van, akkor onnan fogja olvasni, de a lockolasok es az iras muveletek a diskre mennek es mivel az adatbazis altalaban nem jo ha serul ez ki is szoktak syncelni, ami miatt meg is kell varni mig a diskre tenylegesen kiirodik... ha nem fontos akkor csinalj egy ramdisket vagy tmpfs es masold at oda

A'rpi

Bármit betehetsz a /dev/nullba, és biztos lehetsz abban, hogy a műveletek nem fognak lemezműveletet eredményezni.

Én már az egész internetet belemásoltam, és meg se döccent tőle a lemez.

Konkrét adatbáziskezelővel is ez a helyzet, nálam a Konkrét v3.141 fut.

Ha memóriában akarsz dolhozni, akkor tmpfs vagy ramfs kell neked. Az fstabban kell felhúzni.

Meg tudnád adni azt a parancsot, amivel kiolvasod az adatbázist a /dev/null-ból?

És tényleg.


karesz@server1:~$ echo "[ {id:1,name:'John Doe'},{id:2,name:'Kovács István'} ]" > /var/database/source.mdf
karesz@server1:~$ cat /var/database/source.mdf > /dev/null
karesz@server1:~$ cat /dev/null > /var/database/production.mdf
[
{
"id": 1,
"name": "John Doe"
},
{
"id": 2,
"name": "Kovács István"
}
]
karesz@server1:~$ for r in $( cat /dev/null ); do; [ r.id -eq 1 ] && echo r.name; done
Kovács István
karesz@server1:~$

> A kérdésem igazából, csak annyi, hogy ha cat-el valamit beteszek a /dev/null-ba
> akkor az csak ott van, de nem történik vele semmi. Jól sejtem?

Ez a mondat elérhető valami publikus licenc alatt? Mert kinyomtatnám, bekeretezném és kiraknám a falra.

Hát ha csak ezen múlik nyomtathatod.
Kifejtve, van egy német anyacég, aki vállalatirányítási rendszert készít/fejleszt. Ha nagyon gyorsítani szeretnénk azt javasolták, hogy töltsük be a memoriába az adatbázis fájlokat.
A parancs:
cat /xxx/xxx/xxx/adatbazisfájl.xxx >/dev/null

Nem kérdőjelezni akarom hanem csak megerősítést szeretnék, hogy így valóban gyorsulnak-e a lekérdezések. Mikor kipróbáltam, nem vettem észre érdemleges változást. A kérdés tehát, hogy ez valóban gyorsulást kellene, hogy eredményezzen?

A bekeselés miatt akkor esetleg érzékelhető, ha nagy memóriaigényű (a memóriát cakkpakk átíró) munka, vagy friss indítás után, a dbfájlok használata előtt csinálod meg (ergo benyomod a memóriába).

Ha enélkül végigcsinálod az adatbázis első használatát, az részben vagy egészben pont úgy betuszkolja a cache-be az adataidat, az ugyanazon adathalmazra irányuló 2., 3., ... művelet között már nem lesz érdemi különbség (hacsak sok egyéb nem történik a gépen).

Viszont itt jön az, ami konkrétan megerősítette bennem, hogy hülyülsz a kérdéssel: KONKRÉT adatbáziskezelők KONKRÉTAN eltérő sebességkülönbségeket képesek elérni a memóriába (ott: cache v. pool v. bufferpool) leképezett adatbázissal a KONKRÉTAN eltérő módszereikkel.
Itt se megy, hogy "vogel, vogel, vogel..."

Pesze, még nem zárható ki a hoax, de a háttérinfo leírása után tudok hinni, mint Neo az ugráspróba előtt.

Mivel egyáltalán nem megy eseményszámba olyan adatbázishátteres megoldás, amit úgy optimalizáltak, hogy a fejlesztő gép memóriáját tuningolták mind feljebb, ha lassúcska lett a szoft: nem tudom kizárni, hogy van az a devtím (elnézést minden tisztességgel dolgozótól!), ahol az az alapfeltételezés, hogy ha 10ezer rekordot fel lehet olvastatni tempónövelés gyanánt, akkor ez 10millió rekordnál is működik, és ennek a mikéntje kerül a júzergájdba.

Persze, lehet próbálkozni mindenfélével, de a kolléga nem egy tmpfs-re vagy ramfs-re akar írni, hanem a /dev/null-ra... Na, ez a kandikamera téma. :D :D Még mindig nem tudom elhinni, hogy egy fejlesztő ennyire ne tudja, milyen speciális fájlok vannak Unix (szerű) rendszereken. (Vagy van esetleg olyan Unix derivátum, ahol a /dev/null egy ramfs, csak sose hallottam róla? :D)
--
Coding for fun. ;)

Még mielőtt ennyire nagyon engem támadtok itt az eredeti válasz.

Answer of the operating department:
-------------------------------------

Only the ekslogdb* files are relevant for performance, which is why we
recommend the cron call as follows:

30 5 * * * cat xxx/xxxbase/db.dat/ekslogdb* >/dev/null

Note: The cronjob should start after the nightly backup, and the main memory
should be large enough so that the data can be stored in the RAM.

To ensure that the data are transfered to the memory immediately after a
reboot/new start, the following lines can also be added to the startup
script /etc/rc.d/rc.local:

cat xxx/xxxbase/db.dat/ekslogdb* >/dev/null &

Nem téged támadunk, hanem azt, aki ilyen idiótaságot írt le. Ha legalább az lenne, hogy a /dev/null-ról cat-olok egy logfájlra esetleg, ami villámgyorsan nő, és amúgy se kell (?), az más lenne, de így... Szerintem az irodalmárok ezt a megoldást úgy neveznék, hogy "pusztába kiáltott szó".
--
Coding for fun. ;)

Ne ragadj le a /dev/nullnál, mert nem az a lényeg, hanem az olvasás. Mivel a fene se akarja a fájlokat megduplázni, az olvasás mehet a semmibe.

ELMÉLETILEG, speciális esetekben tényleg segíthet, ahogy már taglaltuk.

Attól tartok, gyakorlatilag viszont tényleg arról van szó, hogy azzal akarnak teljesítményt tuningolni, amit ismernek, és ez innen édeskevésnek látszik.

Ez nagyon kemény!

Tényleg jó lenne egy cégnév is ehhez a remek adatbázis tuning javaslathoz.
Lehet hogy szabadalmaztatták is a megoldásukat? :D

Ez 'megoldás' lagalább annyit ér mint ennek a szerencsétlennek az internetgyorsítási videói:

http://www.youtube.com/watch?v=lG5cEik2ABY

--
zrubi.hu

Azt értem, hogy disk cache-be kerül a felolvasott adat, amit null device-ra küldenek, csak ezzel az a bajom, hogy nem dedikált foglalás, a kernel bármikor kivághatja RAM-ból. Szóval hiába értem, ez nagyon béna, gány megoldás, ami semmire sem garancia.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Valószínűleg egy dedikált gépük van, ahol a szabadfelhasználású cache-be tolt fájlokat nem tolja szét bármi egyéb folyamat, ami arra jár. Ha nem így volna, nem tapasztalhatnának érdemi gyorsulást a cateletlenséghez képest.

Szintén valószínű, hogy a munka során gyakran kell más-más rekordot beolvasniuk. Ha nem így volna, akkor a gyakran érintett adatok úgyis nagyobb eséllyel tapadnának a cache-be, akár catelnek, akár nem, ezért szintén nem tapasztalnának változást.

Továbbá azt sem zárom ki, hogy szó sincs a hagyományos értelemben vett adatbáziskezelőről (mert annak volna komolyan vehető módszere a memóriahasználat hangolására), hanem valami házi tákolmány.

De ezek még mindig a legjobb forgatókönyvek, és a valószínűtlenebbek.
Sajnos a valószínűbb az, hogy a cuccod fejlesztői úgy tudják, hogy az adatbáziskezelés egy installból, néhány create table-ből, és sok-sok select/insert/update/delete parancsból áll, és még senki se szólt nekik, hogy nem egészen.

Elkepzelheto esetleg olyan specialis eset amikor lehet haszna, pl dedikalt adatbazis szerver ami cache-nek filerendszer cache-t hasznalja es db service indulasa (clusterben elesbe allitasa elott) elott fel akarod tolteni a cache-t hogy ne hidegen induljon.
Bar nem lattam meg hogy ilyenre cat > /dev/null-t hasznaltak volna, sokkal inkabb table scan es tarsai adatbazison belul.

Nem is kétlem, csak ez pont olyan, mint valami tuti megoldásként árulni az undelete funkciót filerendszerekhez. Ha éppen még nem írták felül a szabadnak bejegyzett foglalási egységeket, ha éppen folytonos volt a HDD-n a file foglalása, akkor vissza lehet szedni, miután az le lett törölve. Ha meg már kellett a hely, felülíródott, akkor meg nem.

Szóval nem kételkedem abban, hogy bizonyos körülmények között működik a módszer, de azért erre nem bíznék semmit, mint ahogyan a fontos adataimat sem tárolnám letörölt file-ok után felszabadított szektorokban. :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Erre akar startupot is erdemes lehet epiteni - rengeteg helyen hasznosithatnak a gyorsulast - a mobiltelefonoktol kezdve a nagy adatkozpontokig.

Hol a tanulmany, amely bemutatja mit tud a "CatDevNull Anywhere", "CatDevNull Enterprise" ?

Nos, barmilyen hihetetlenul hangzik, esetenkent tenyleg hasznalhato:
http://blog.coelho.net/database/2013/08/14/postgresql-warmup/

Tegyük fel, hogy nem trollkodás volt a kérdés, hanem komoly. Olyan naiv alapja lehetne a gondolatnak, hogyha egyszer beolvasta a file-t (és kiírta akárhová, mondjuk /dev/null -ba), akkor annak tartalma bekerül az oprendszer file cache-ébe. Azt gondolhatnánk, hogy onnantól gyorsabbal lesznek a query-k, hiszen már az egész adatbázis file RAM-ban van, nem kell I/O műveletet végezni.

De ez a legtöbb relációsadatbázis-kezelő esetén nem igaz, ugyanis szándékosan olyan az architektúrájuk, hogy saját maguk csinálják ezt a cache-elést. Fenntartanak egy memóriaterületet, ahová ők maguk az oprendszertől függetlenül explicit cache-elik a file tartalmát, tipikusan adatbázis laponként. Az adatbázis file-t pedig direkt olyan rendszerhívással nyitják meg, hogy az oprendszer ne cache-elje az olvasásokat és írásokat. Ha az adatbázis mérete kisebb, mint a rendelkezésre álló RAM, akkor lényegében az egész adatbázis előbb-utóbb úgyis a RAM-ban lesz. Ha pedig nagyobb az adatbázis (tipikusan ez szokott lenni), akkor valószínűleg az adatbázis-kezelő egy jobb cache-elést tud elérni, mint az oprendszer file cache-e.

Lásd még:
http://dev.mysql.com/doc/refman/5.5/en/innodb-buffer-pool.html
http://docs.oracle.com/cd/B19306_01/server.102/b14220/memory.htm
http://msdn.microsoft.com/en-us/library/ms178067.aspx

Igen, ez így van. Én épp azt írtam, hogy ezzel felesleges is foglalkozni, hiszen az adatbázis-kezelő eleve olyan rendszerhívással nyitja meg a file-jait, hogy az ezen végzett I/O műveleteket nem használják az oprendszer file cache-ét.

Egy tipikus adatbázis szerveren alig van oprendszer file cache használva, és a RAM 80-90%-át az adatbázis-kezelő saját in-process cache-e foglalja el.

Ezt fél év múlva kellett volna... Április akkor lesz ugyanis. De ahogy olvasom, ez valós kérdés, akkor meg egy méretes DFP-t érdemel.

Nem lehetsz túl koros, egy olvasnivaló. A pokoli operátor naplója

Az első mondatot ki is emelném.

"Mivel ma mentési nap van, eléggé tele van a hócipőm. De sebaj, elvégre én lennék ugye a pokoli operátor, ezért azt hiszem igazán kellemes a helyzetem. A szalagos egységet nullára irányítom - így sokkal gazdaságosabb minden szempontomból: nem kell a szalagokat ötpercenként cserélgetni, ráadásul még gyorsítja is a mentési folyamatot, tehát csak jó lehet. "

Komolyra fordítva, megoldható
Készítesz egy ramdisket kb így http://www.jamescoyle.net/how-to/943-create-a-ram-disk-in-linux ide mindent bemásolsz, és itt dolgozol, de mindezek előtt mevásároljátok a lehető legjobb szünetmentes tápot. Kivéve persze ha csak tesztről van szó.

------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.

> A kérdésem igazából, csak annyi, hogy ha cat-el valamit beteszek a /dev/null-ba akkor az csak ott van, de nem történik vele semmi. Jól sejtem?

Rosszul, ugyanis nincs ott, nem csinál vele semmit (ez egyébként elég alap tudás...). Ez alapján magad is láthatod, mit csinál:
http://lxr.free-electrons.com/source/drivers/char/mem.c

troll

ha valamit a /dev/null -ba teszel (csak írható memória ), akkor azt a /dev/zero -ból tudod kiolvasni.
Az ott lévő adatokkal történik valami: minden byte átkonvertálódik 0x00-ra.

/troll

ha tényleg memóriában akarsz dolgozni:
mkdir /mnt/memoria
mount -t tmpfs none /mnt/memoria
cp adatbazis /mnt/memoria

ha végeztél a memóriában dolgozással:
umount /mnt/memoria

-fs-
Az olyan tárgyakat, amik képesek az mc futtatására, munkaeszköznek nevezzük.
/usr/lib/libasound.so --gágágágá --lilaliba

Na, elsőre nagyon jót mulattam a kérdésen.

Én napi szinten dolgozom több millió soros logokal. Van egy referenciafájlom amivel tesztelni szoktam. Azt már én is régen észrevettem, hogy egy ilyen fájl feldolgozása során teljesen más futási sebességet kapok az első feldolgozás során, mint az összes többinél. Utóbb többszörös (nálam kb. 4x) sebességet mérek. Ezt én a bufferelés számlájára írtam.

Vissza a kérdéshez:
Mivel a cat-ot nem érdekli, hogy egyébként a kimenete a /dev/null-ba van irányítva az egésznek semmi más értelme nincs, mint az általam is tapasztalt rendszerbufferek feltöltése.

Ebből a szempontból azt kell mondjam, nem teljesen hülyeség a kérdés. Ha valaki kipróbálja - én megtettem -, hogy egy jó nagy méretű fájlt kétszer egymás után küld a fenti módszerrel a /dev/null-ba, akkor meg fog lepődni ennek a műveletnek a a sebességkülönbségén. Én kipróbáltam egy fájllal, amivel a cat először kb. 3-4 másodperc alatt végzett, másodszor pedig szinte azonnal visszakaptam a promtot, tehát tizedmásodpercek alatt (1-2) végzett az egésszel.

Mindez azt mutatja, hogy fájl szinten működik a dolog. Ettől még nem gondolom, hogy minden adatbázisnál és minden esetben működnie kell, de el tudok képzelni olyan esetet, amikor a post felvetőjének igaza van és adott esetben gyorsulás érhető el.

Nyilván nem 100%-os megoldás, de előfordulhat, hogy adott esetben, adott feladatnál, adott konfigurációval, hogy ez a gyakorlat nagyon jól beválik. Erre még rá is lehet játszani, ha telerakják a szervert "felesleges" rammal. Amíg van hely bőven a memóriában - és forgalom az adott fájlon -, addig valószínűleg úgysem szabadítja fel a rendszer a részére lefoglalt memóriát.

Ha az utoljára írt, olvasott anyagot hagyja a cache-ben a korábbi helyett, valamint az alkalmazás által foglalt, majd használni kívánt memórialapot az alkalmazás alá lapozza a kernel, az nem bug, hanem feature. Ez a dolga. Mégis honnan kellene tudnia a kernelnek, hogy az adatbázis maradjon a cache-ben, míg frissebb, más meg ne? Ha dedikált cache kell, azt az adatbázis software-en belül kell implementálni. Éppen ezért mondtam, hogy ez a cat adatbázisfile >/dev/null elég béna „megoldás”.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Rendben. És mégis mi a garancia arra, hogy a néhány GB-os adatbázis minden része, vagy csak akár kis része is gyakrabban lesz olvasva, mint egy másik process által írt, olvasott file, valamint mi a garancia arra, hogy más process - vagy akár épp az adatbázis kezelő - nem kér egy rakás RAM-ot, amit használ, s a kernel kénytelen alálapozni fizikai memóriát netán épp a disk cache rovására?

A kernel optimalizál, de nem dedikált memória az adatbázis file-jaira nézvést a lefoglalt disk cache.

De írtam hasonlatot. Ez szerintem olyasmi, mint a törölt file-ok visszahozása. Semmi garancia nincs a sikerre, de sikerülhet, tehát arra sincs garancia, hogy az adat elveszett. Éppen ezért, ha az a cél, hogy tűnjön el az adat, kevés a sima törlés, ha meg az, hogy megmaradjon, akkor meg túl sok.

Ez is ilyen. Lehet ez jó, csak nem garantált megoldás.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Mi is használjuk a /dev/null-ba másolás trükköt adat előtöltésre. Igaz a mi esetünk teljesen más, nem adatbázisról van szó. Akkor tudsz nyerni vele nettó időt, ha a konkrét adatlekérés előtt van egy kis szabad ideje a gépnek a cache-t feltölteni (preload az éles használat előtt), vagy pedig ha az adatfelolvasás nem lenne lineáris (indexekben turkálás tipikusan ilyen). A random access olvasás HDD esetén sokkal lassabb, mint ha lineárisan olvasnánk fel ugyanazt az adatot. A lineáris olvasás megvalósulásához persze az is kell, hogy a fájlok ne legyenek nagyon töredezettek.

Ha vannak konkrét számok, akkor lehet mérni és ebből számolni: mennyi az összes adat (befér-e RAM-ba)? Mennyi idő lenne ezt lineárisan felolvasni diszkről(mérés, vagy becslés táblázat adatok alapján)? Mennyi idő a jelenlegi (nemlineáris) feldolgozás? Az adatbázis lekérdezésnek biztosan a diszk elérés a szűk keresztmetszete? Ha ezekre van válasz, akkor látszik, hogy van-e értelme ilyen jellegű optimalizációval foglalkozni.

Persze múlhat az adott rendszer konfigurációján, de alapból a Linux kernel ameddig elegendő fizikai memória lap van, addig nem dob ki egyetlen már felolvasott lapot sem, hanem cache-ként használja a memóriát. Ezért ha még azelőtt olvassuk a fájl adott darabját, hogy kikerülne a cache-ből, akkor jelentős időt lehet nyerni ezzel a trükkel.

"A kérdésem igazából, csak annyi, hogy ha cat-el valamit beteszek a /dev/null-ba akkor az csak ott van, de nem történik vele semmi. Jól sejtem?"

A kérdés szempontjából a /dev/null mellékes. Lehetne a cat kimenete más is, de akkor pl. helyet foglalna... Mivel az adatbázist nem akarják a kollegák duplikálni (nem is lenne tanácsos cat-tel) így ezért a /dev/null-ba irányítják. Ott pedig a "másolt" információ elvész.

A művelet lényegében értelmetlen. Annak viszont, hogy a cat kénytelen végigolvasni a fájlt, az lesz az eredménye, hogy ennek nyoma marad a memóriában. A rendszer buffer(eket) tölt fel a fájlall. Így amikor pl. legközelebb - pl. élesben -, olvasni akar a fájlból úgy azt megtalálja a memóriában és így nem kell a diszkhez fordulnia.

Ha más I/O igényes feladat is fut párhuzamosan, akkor persze van esélye, hogy egy idő után kikerül a memóriából. Ez függ az éppen futó folyamatok memóriaigényétől és a rendszernek rendelkezésére álló memóriaméretétől is. Azaz attól, hogy az operációs rendszer mekkora memóriaterületet használhat I/O buffernek.

A lényeg, hogy a megoldás kulcsát ne a /dev/null-ban keresd, mert az csak egy "fekete lyuk", aminek az a feladata, hogy lenyeljen mident. A folyamat lényege a fenti "mellékhatás", amit a cat általi - de lehetne más program is - olvasás okoz.

Két legyet egy csapásra, mert a /dev/null-ba másolás tömörít is, oda mozgatva a poreszgyűjtemény/adatbázis már nem foglal annyi helyet.

A memória, ha nem ECC, akkor elég sérülékeny, rossz esetben naponta több bit is sérülhet ha több gigabájtról beszélünk.

Elerheto mar NVRAM modul, onallo tapellatassal es ssd backuppal, ha nagyon memoriaba akarsz dolgozni...

FYI:

http://blog.coelho.net/database/2013/08/14/postgresql-warmup/

Conclusion

"Warming-up a database for good cache behavior can really take a long time with pretty low performance. You must take that into account when running a benchmark. A rough estimate of the warmup time is to count how many pages must be loaded multiplied by the time to read a random page from the disk. Some ability to hint PostgreSQL about preloading index and table pages would be nice. Otherwise, resort to the above manual methods, or be patient!"

Az esettanulmány conclusionja nagyon-nagyon szabad fordításban: ha élünk azzal a feltételezéssel, hogy a fizikai memória pariban van az adatbázis méretével, és hogy az első pillanatól kezdve, és aztán feszt teljes táblaszkenekre van kényszerítve a motor, akkor zéróról indulás után negyed óráig van nyereség a db io-n átfolyatásán.

Aztán ott vagyunk, ahonnan elindultunk a fentebb német licenszeléssel jegyzett be- ill. ráolvasásos ravaszkodás nélkül is.

Nah sikerült beszélnem azzal a céggel, ahol ez ki lett próbálva. Nálunk ez amiatt nem hozott eredményt, mert nagyon kevés adatokkal dolgozunk, nem úgy mint ők. A legnagyobb probléma, hogy nincs egyelőre szálasítva az adatbázis. A cat /dev/null cache-lés valóban gyorsít valamennyit az adatbázison. Köszönöm, mindenkinek a hozzászólását, ebből is sokat tanultam már. Mindenkinek szép hétvégét.

Jó, de a forrás helyen megmarad az adatbázisa, valamint mellékhatásként a disk cache-be kerül, ez a módszer lényege. Más kérdés, hogy nem marad mindig a cache-ben, mert kellhet a cache is másnak, meg a RAM is úgy általában.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Tegyük hozzá hogy a fikázást azért kapta, mert a kiírás szerint az adatbázis gyorsítására lett kitalálva, nem a coldstart - warmupra és nem arra, hogy a mentés után kisikált memóriát újból felöltse. Ezek az apró, jelentételen részletek kicsit árnyalták volna a képet.

Valszeg kisebbségben vagyok, de van egy 300 megás sqlite adatbázisom amit mielőtt a python 3.3 behozta az os.posix_fadvise() függvényt kézzel catoltam indításkor /dev/null-ba, szóval nekem elejétől leesett hogy mi van.

Emellett threadhez függ hogy igen, gnu tar nagyon intelligencs, csak file descriptorokat olvas be ha /dev/null a kimenet, bsdtar kell ha esetleg tényleg cache-be töltenéd a /var/db/pkg /usr/portage /var/lib/layman /usr/local/portage könyvtárakat, ha csak a portage agyalágyult függésfeloldását szeretnéd kivárni.