hali,
épp egy tárolási problémával küszködök, és kéne némi tapasztalati vélemény.
az van, hogy van 50E+ user, nekik pedig vannak kapcsolataik egymással -- kivel leveleztek, ki nézett meg kit, ki kedvel kicsodát, stb. ez kb. 3-4M kapcsolati rekord.
mivel igen aggresszíven cache-elek (hogy ne kelljen átnézni állandóan ezeket a kapcsolati rekordokat), így az van, hogy tároláskor és cache-újraépítéskor kell csak a backendhez nyúlnom, ami jelenleg megosztva file (userenként 4 file) és mysql tábla (kapcsolatonként (típusok szerint is) 1 rekord).
mivel nemrég clusteresedtünk, ezért a file backend nfs-re került, de az nagyon omladozik a terhelés alatt (mivel leginkább írási műveletek történnek), így átmenetileg visszakoznom kellett a terheléselosztásos php módszertől. innentől eléggé egyértelmű, hogy a file backendet meg kell szüntetnem, és át kell raknom valamilyen db alapra. a mongot gondoltam kipróbálni erre, főleg, mert memóriában tudja tárolni az igazán aktív rekordokat.
a nagy gondom az, hogy melyik tárolási forma lenne a célszerű.
ha user/kapcsolattípus alapján 1-1 rekordot tárolnék (mint a klasszikus sql alapon), akkor legalább 3-4 millió rekordról lenne szó, ahol minimum 3 indexet kéne fenntartanom (user1 id, user2 id, típus) a hatékony lekéréshez -- ez viszont a cache-elés miatt nem tűnik annyira fontosnak.
a másik variáció az, hogy userenként 1 rekordot tartok fent, amin belül mondjuk json-ba kódolva a jelenlegi fájlok (illetve sql-ben tárolt adatok) tartalma kerül. ez kb. 50E+ rekordot jelent. így csak egy indexet kellene fenntartanom, a user ID-t. így persze vesztem azt, hogy szabadon csináljak lekéréseket a db-ben, de mint az a fentiekből látható, ez most sem lenne megoldható, és nincs is rá szükség. viszont így egy-egy entry viszonylag nagyobb méretű lehet, és kell némi logikát alkalmaznom a betöltéskor/mentéskor, plusz saját logikával kell átnéznem és módosítanom a "file" tartalmát.
per pillanat hajlok az utóbbi felé, mert attól tartok, az előbbinél a rekordok száma miatt az indexek nagyon sok operatív memóriát falnának fel, és eléggé fontos lenne, hogy minél több minden férjen be a ramba.
ti melyiket választanátok?
- 6191 megtekintés
Hozzászólások
Kapcsolatokat leirni nem lenne celszerubb graffal? Pl.: Neo4j
- A hozzászóláshoz be kell jelentkezni
nem igazán, mivel sem a kapcsolati távolságok, sem a bebarangolható utak nem érdekesek, kizárolag az 1-1 kapcsolatok.
- A hozzászóláshoz be kell jelentkezni
Jogos, de 1-1 kapcsolat is kapcsolat es az a db pont erre valo, ergo szamomra az kovetkezik, hogy optimalizalt ilyen tipusu tarolasra, lekerdezesre. A dokumentacio alapjan pedig jol clusterezheto.
- A hozzászóláshoz be kell jelentkezni
Bocs, rájöttem, hogy nem értem. Illetve kapizsgálom, de nem tudom megragadni a problémát, mert nekem egy rakat kérdőjel az, hogy egyáltalán miért alakult így a rendszer.
- A hozzászóláshoz be kell jelentkezni
Egy file megnyitasa es benyalasa diszk-rol kb. 10x gyorsabb, mint egy mysql select.
Mi egy alkalommal, amikor egy gyors, perzisztens es egyszeru "adatbazis"-ra volt szukseg, siman raktunk 2-3M softlinket egy konyvtarba. Miert? Mert ha tudod a pontos nevet az entry-nek a konyvtarban (a.k.a. a hash "kulcsat"), akkor az ext3/4 bazigyorsan megtalalja a dir_index miatt, a hash "erteke" pedig a softlink miatt az inode-ban van, tehat a readlink() mar memoriabol tudja rogton kiszedni. Ez igy egy bazigyors hash-t eredmenyez, ahol az adat az ext3 inode-jaban tarolodik, es 1 db inode lookup az eleres koltsege (amit raadasul kernelben megy, okosan cache-elve, szoval bazigyors).
Backup/restore/stb... ertelemszeruen megoldott tar-ral.
Ugyanezt megprobaltuk mysql-lel is: 10-50x lassubb, 10-50x tobb diszket foglal, backup/restore nehezkes a hulye mysqldump miatt, es a mysql + client lib egy halom eroforrast eleszik meg monitorozni is kell.
Tanulsag: ne becsuld ala az egyszeru megoldasokat. :)
- A hozzászóláshoz be kell jelentkezni
Nehéz elképzelni, hogy ebben a rendszerben a bottleneck egy jól indexelt key->value lookup az SQL-ben. Feltételezem, hogy a 4 fájllal-, illetve a jövőben a mongodb-vel való munka nagyságrendekkel költségesebb.
De igazából mindegy, azért is töröltem a hozzászólást, mert nagyon sok lenne a feltételezés, bármit is javasolnék.
Esetleg annyi, hogy azt írja, hogy rengeteg írás van, ez okozta a problémát. Ha összevonja az objektumokat, nem lesz mégtöbb fölösleges írás? Ha a 4 fájl eddig is egyszerre volt felülírva akkor nem, de ha külön-külön, akkor most a módosítás jóval több írással jár mint eddig. De mennyi adatot jelentenek a fájlok összesen egyáltalán? Kitudja..
- A hozzászóláshoz be kell jelentkezni
"a mongot gondoltam kipróbálni erre, főleg, mert memóriában tudja tárolni az igazán aktív rekordokat."
Másodszor átolvasva is itt döccentem meg.
Nem vagyok egy univerzális db-látó, de azért merem állítani, hogy minden motornak tulajdonsága és kötelessége, hogy az általad neki szentelt memóriában/cache-ben/bufferpoolban/ahogyépphívjákban az igazánb aktív rekordokat tartsa (lévén azoknak nagyobb az esélyük arra, hogy az (n-1). utasítás tárgyai is voltak.
Ez a hitem meg arra a gondolatra vezetne, hogy a mongo pont annyira jó választás, mint bármelyik, ahol a bpool adjusztálható. Azaz, a mongo esetében ez pont nem igaz, mert viszi, amit talál, de ha egyedül játszik a pályán, ez nem gond.
Hogy én 10* előbb olyan megoldást választanék, amelyben SQL a lekérdezőnyelv, és csak nyomós ok esetén egyebet, azt betudom az őszülő szakállamnak.
- A hozzászóláshoz be kell jelentkezni
Mongo-nak nincs sajat cache-e. Egyszeruen mmap()-et hasznal, es a kernelre bizza a cache-elest. Ebbol jon az is, hogy ennel gyorsabb cache nincs :), meg az is, hogy a te feladatod, hogy mindig legyen eleg memoria a gepben.
SQL egy fos elosztott kornyezetben a szigoru ACID miatt.
- A hozzászóláshoz be kell jelentkezni
Amúgy "a viszi amit talál" a cgroups korában nem igazán áll, a page cache is bekorlátozható.
- A hozzászóláshoz be kell jelentkezni
Esetleg mysql cluster? (nem a Percona, hanem az ndb backendes)
Nem látom, hogy mi szól a Mongo mellett, ha noSQL-t kéne élőben használnom, inkább mennék valami olyan irányba amit élesben is sokan használnak. (Cassandra?)
- A hozzászóláshoz be kell jelentkezni
Azért a mongonak elég komoly juzerbázisa van világszerte. Mi használjuk egy 30TB-os adatbázissal kb 700Mbps forgalom mellett és szépen muzsikál, bár a teljesítménye itt-ott hagy kívánnivalót maga után, elvben és gyakorlatban is van gyenge pontja, de előnye is akad.
- A hozzászóláshoz be kell jelentkezni
ndb tetu lassu az SQL miatt. pl. write lock kerul egy rekordra, es maris bejatszik egy network roundtrip latency.
- A hozzászóláshoz be kell jelentkezni
1) nfs-t felejtsed el gyorsan, bármi is van mögötte storage-nek. home-ot felrakni jó, bármi másra, ami terhel is: halál.
2) json-t ne tárolj mezőben, mert igen szopó lesz select-ben szűrni az alapján.
3) Mekkora az adatbázis? Él leírásánál a 4M rekord (int,int,enum) esetén kb 50 mega lehet, + 3 index az fejenként köbö ugyanennyi. Ennek röhögve el kéne férnie a kernel bufferbe. Emellett a select-jeidet nézzed meg, hogy _TényleG_ használják-e az indexeket, ég és föld a két véglet.
4) mysql külön gépre.
Ezek után kezdd a mysql-t clusterezni.
- A hozzászóláshoz be kell jelentkezni
na de épp ez az, hogy igazándiból nincs szükségem szűrésre, kondíciós selectekre, ezért gondoltam valami nosql-es megoldásra.
az 50 mega túl optimista szám. jelenleg a file backenddel a csak ezzel foglalkozó rész du -s -h-ra 3GB-ot ad, amin egy sql-ben a kapcsolat típusa mint enum persze spórolhatna, de jó eséllyel úgy max 1GB-ot.
- A hozzászóláshoz be kell jelentkezni
Értem. Nos, ez esetben Apache Cassandra, vagy Mongo (mint említetted) amit megnézhetnél.
- A hozzászóláshoz be kell jelentkezni
Mongo-ek csinalnak free online mongo kurzusokat, javaslom erosen, mert nagyon jok! (nekem mar megvan)
Van egy kulon szekcio dedikalva pont a kerdesednek: hogyan a legcelszerubb az adatokat mongo-ba pakolni?
Javaslat az, hogy 1 objektumot tegyel egy dokumentumba (regiesen rekordba). Az osszes kapcsolataval egyutt, amire altalaban szukseged lesz. Igen, ez igy nagyobb, de akkor is csak 1 objektum, nem 4000. Mongo jobb szereti, ha visszaad neked egy blob-ot es te csinalod a tobbi melot.
Na persze ez csak okolszabaly. Az iskolapelda egy blog bejegyzes volt: ott a blogentry melle beletettek az osszes kommentet. tehat kb. igy:
{
blogpost: {},
comments: [{},{}]
}
Ha uj komment jott, siman push a comments-be, megjeleniteshez meg ugyis kell az osszes komment.
Mint a peldabol lathato, gondolkodni kell: hogyan tudod ugy szervezni az adatokat, hogy minimalizald a muveleteket es a lekerdezett dokumentumokat a leggyakoribb hozzaferesi mintaknal.
- A hozzászóláshoz be kell jelentkezni
BTW mukodhet a 4000 rekordos megoldas is az aggregate framework miatt, ha kellokepp el tudod osztani a terhelest (=nincs order meg hasonlo a pipeline-ban, ami kikenyszeritene az egynode-os feldolgozast). Viszont az aggregate framework teljesitmenye nem osszemerheto egy compiler-evel, ugye, a lehetosegei meg plane nem.
YMMV.
- A hozzászóláshoz be kell jelentkezni
tulképp itt bejátszik még a PECL-ös mongo db driver PHP alatt is. ha a mongo natív json/bsonját használom, akkor a en/dekóding tereh a mongón van (gondolom), viszont ha sima blobot dobok bele, akkor elvileg a PHP oldalon kell majd birkózni ezzel, ami nekem első blikkre szimpatikusabb, mert több app szerver van (2), mint db backend (1).
- A hozzászóláshoz be kell jelentkezni
blob alatt nem a "binary blob"-ot ertettem, hanem egy monolitikus batar allat JSON/BSON dokumentumot.
Ha tenyleg sok nagy binary blobot akarsz fault tolerant/load balanced modon tarolni, akkor HDFS-el jarsz legjobban.
- A hozzászóláshoz be kell jelentkezni
BTW, gondolkozhatsz egy HDFS-en is. Igen, tudom, hadoop borzalmas, de a hdfs resze meg nem kifejezetten (van hozza fuse modul is), viszont distributed es megbizhato. Egy gyors probat meger nfs helyett, mielott beleasod magad egy mongo cluster-be. :)
- A hozzászóláshoz be kell jelentkezni
Megtörtént már az átállás?
Ha igen, akkor mik a tapasztalatok?
- A hozzászóláshoz be kell jelentkezni