fájlok tárolása adatbázisban

Egy futó másik témához hasonlóan nekem is ez a problémám én viszont nem akarom ott tárolni a fájlokat. :)

Adott egy katalógus szerű rendszer, ami valójában csak kényszerűségből katalógus, valójában egy kutatási célszoftver (kódexeket kutat). Az oldalaknak a fizikai manifesztációja háromféle. Első az eredeti kép, a második egy PDF amiben x méretre butítva ülnek a képek, a harmadik pedig osm tileokra bontott formátumban sok kicsi csempe. Ezek a képek kezdetben fontosak, aztán ahogy feltérképezik a rajtuk található információt egyre kevéssé érdekesek. Ez így 4-5 TB adat a filerendszeren, amíg a belőlük kinyert adatok nem több mint 70 mb (jelenleg) relációs adatbázisban.
Tegnap volt egy meetingem ahol eléggé vágta a pofákat az illető, mikor kiderült, hogy a képek nincsenek adatbázisban tárolva a kutatási eredményekkel együtt. Eddig eléggé ódzkodtam a gondolattól, és nem is látom indokoltnak, hogy a 70 mb-os adatbázisból csináljak egy 5 TB-os, nehez(ebb)en backuppolható, nehezen mozgatható relációs adatbázist, csak azért, hogy a forrásanyag mindenáron együtt legyen a metaadatokkal és a feldolgozás végtermékével. A relációs adatbázis egy adatbázis, a fájlrendszer pedig fájlrendszer. Külön-külön mindkettő lehet annyira fontos (és az is), hogy a maga területén a mentés, snapshotolás működjön megfelelő sebességgel, ami csorbulhat ha összekeverem a kettőt.
Az adatok "összekapcsolását" akár az adatbázis fejlesztésével is meg lehetne oldani és akkor még mindig nem binárist tárolok adatbázisban (pl eredeti képek hashelése és azok visszaellenőrzés sérülés/elveszés esetére).
A kérdésem az, hogy ezt hogyan oldják meg? Lehet, hogy csak én gondolom túl ezt a bináris adattárolást relációs adatbázisban?

Hozzászólások

Ha azok a bináris fájlok nem lennének összetett keresésekkel, lekérdezésekkel kezelve, akkor ebben az esetben szerintem nem valók az adatbázisba. Az adatbázis kezelő is végül kirakná fájlokba, csak még lehet nagyobb lenne az eredmény, mint most nyersen (és irhatnál/kereshetnél hozzá egy olyan changelog-ot, amit tudsz archiválni darabokban).

Nem tudom az "illető" mennyire döntéshozó, és mennyire hozzáértő, de én jelenleg simán azt mondom, hogy az adott kezelőfelületen kösd össze a fájlt és a db-ben levő adatot, és nevezd a fájl rendszert egy "speciális NoSQL adatbázis"-nak. Mert nagyjából az is :). Ha a fájlok helyett az elérési útvonalakat tárolod az adatbázisban méretileg se fog elszállni, és kapcsolat is lesz a kettő között.

Útvonal tárolása sincs szükség, csak az útvonal előállításához szükséges információra (id, akármi).
Az illető onnan közelítette meg, hogy ezek a dolgok szerves egységet képeznek, és ahonnan ő jön ott ez a szemlélet. Leginkább arra vagyok kíváncsi, hogy ezzel kapcsolatban én vagyok ufó és egyébként mindenki minden összetartozó dolgot becsűr az adatbázisba? Ahol ezt teszik, katalógus szoftverek adatbázisában, ott jelentkezik-e a teljesítmény vonzata ennek a viselkedésnek, és ezért kell mindenféle indexelő és kereső szolgáltatást futtatni a metaadatokon (solr), mert a db tele van fájlokkal (jó, nyilván nem csak ezért, sok adatban kell a gyors fulltextsearch)?

Szerintem egészitsd ki a nyitó posztot ezzel, igy már értem, mire gondolsz. És egyúttal nem tudok válaszolni, én sose jutottam el odáig, hog y be kellett volna lapátolni DB-be fájlokat, a fájlrendszer gyorsabb volt arra az egyszerű tárolásra, amire kellett, kevés kapcsolódással, egyféle struktúrával.

Elvi szinten: nem tudom van-e különbség aközött, hogy van egy fájlrendszered, amiben minimálisan struktúrálva van az adat, és van egy NoSQL-ed, ahol lehet még ennyire se, vagy megközelitőleg ennyire, szerintem a különbség ott kezdődik, ha valamire használod is a db-t, pl. ahogy irtad keresésre, amihez index-et készittetsz, de erre is van fájlrendszeres megoldás is.

szerk.: rosszul fogalmaztam, a NoSQL alatt dokumentum tárolókra gondoltam (nem a mostanában népszerű json-szerű tárolókra), a másik témában elég jól körbejárták ezt ( http://hup.hu/node/152075 )

"Az illető onnan közelítette meg, hogy ezek a dolgok szerves egységet képeznek, és ahonnan ő jön ott ez a szemlélet."

Furcsa egy szemlélet. Csapj vissza azzal, hogy a "szerves egység" eleve (pl.) merevlemezen van könyvtárakban, fájlokban. Ergo a szerves felépítés ezt a vonalat követi akkor is, ha a fájlok strukturáltan egy könyvtárban vannak. Az adatbázist dagasztani állományokkal pedig lassulást okoz. <- Gondolj csak bele, lesz egy (vagy több) baromi nagy fájlotok, amiben az állományok vannak.

Világos. Akár szakmabéli, akár nem, azzal a felvezetéssel meg lehet vele értetni, amit körvonalaztam. Ha nagyon csökönyös, akkor érdemes időt szánni egy kis demonstrációra (aminek az előkészítése sajnos nagy munkával jár). Viszont a vezetőség felé elég bizonyító erejű.

Első körben az állományokat seaweed-fs vagy mogilefs vagy hasonló rendszerben tárolnám. Elosztott, redundáns, gyors.

Ha már mindenképp relációs adatbázisban akarod tárolni, akkor azt én úgy csinálnám hogy a képek másik adatbázisban, de legalábbis másik tablespace-ben lennének. Akkor lehetne úgy dump-olni hogy kép részét nem dumpolod, csak azt a részt ami változik. (Mert ha jól értettem meg a feladatot, akkor a bináris képek statikusak, a többi adat az amit folyamatosan szerkesztenek.) De még arra is lehet viszonylag hatékony megoldást találni, hogy ha a képekhez mindig csak újakat adnak hozzá, de a régieket nem módosítják. Ez nem nehéz.

Ami a pofák vágását illeti: ez nem annyira érzelmi alapú kérdés kellene hogy legyen. Fel kell tárni az egyes megoldások előnyeit és hátrányait. Ezeket összehasonlítani a követelményekkel. (Követelmény rendszer nélkül tényleg csak érzelmi alapon lehet döntést hozni de annak nincs sok értelme.)

Feltételezhetően az adatokat sok ember akarja elérni egyszerre (kutatási terület!) és fontosnak tűnik hogy hibatűrő legyen. Ez +1 pont az elosztott állomány rendszernek. Az egyetlen relációs adatbázisban való tárolás is jár előnyökkel: atomi műveletek lehetősége tranzakcióban - de erre szerintem a képekkel kapcsolatban nincs szükség mert azok szkennelés után nem módosulnak. Ez tehát nem plusz pont. Kompakt tárolás - egyetlen dump-ban benne van az összes adat. Ez azoknál a rendszereknél lehet fontos amit sok helyre kell terjeszteni, vagy gyakran kell átmozgatni, meg még más esetekben amik közül szerintem erre a problémára egyik sem igaz.

Persze nem tudhatjuk az összes követelményt, de a probléma leírásod alapján úgy tűnik hogy a bináris adatok és az adatbázis ketté választása több előnnyel jár mint hátránnyal.

Én általában ódzkodom attól, hogy bármit fájlrendszerben tároljak, amiből később nem lesz stream. Egyszerűen azért, mert a fájlrendszerben mindenféle védelmet kell kiépítened arra, hogy az fájlok integritása megmaradjon módosítás közben és közben rendesen kezeld a jogosultságokat, illetve a rendelkezésre állás biztosításánál külön szívás az, hogy ezt redundánsan tedd és persze egyáltalán legyen valami garantált rendelkezésre állás. Kicsit több erőforrás az adatbázis, de annyi előnye van, hogy a minimálisan több erőforrásigényt megéri...

...ha ezekkel a leírt dolgokkal nem szívtál és nem is szívsz, akkor ez egy rejtett és máig görgetett üzemeltetési kockázat, ami most részben a felszínre jött.

Az adatbázisban tárolásnak is vannak előnyei:
- könnyen el lehet érni távolról, ugyanazon módon, mint az adatbázis adatokat, nem kell külön protokoll, auth(r).
- cluster
- indexelhetőség
- különféle lekérdezéseket hajthatsz végre
- kezeli a tranzakciókat és a konkurens elérést

Láttam egy videót, ahol készíttek egy kis Web-es programot (Scala-ban). Itt a fájlok feltöltésénél blokkonként (2-4kB) hash-elték, és key-value adatbázisba (Riak) töltötték be a blokkokat, ahol a key a hash volt, a value a blokk, majd az összes hash-t ami egy fájlhoz tartozott, azt szintén hash-elték és ez lett a fájl azonosító hash-e, aminél a value a hash-ek listája volt.
Demo-ként feltöltöttek egy több száz Megás videót, majd VLC-vel http-n keresztül streamelve játszották le.

Szerk.: megtaláltam a videót, eszerint pontosítottam a leírást.

> könnyen el lehet érni távolról

seaweed-fs is tudja.

> , ugyanazon módon, mint az adatbázis adatokat, nem kell külön protokoll, auth(r).

a normál megvalósítás legalább három rétegű, az authentikációt és az authorizációt az alkalmazás szervernek illik csinálni. ilyen szempontból szerintem nem lényeges szempont, hogy az alkalmazás szerver hány fajta protokollal éri el az adatokat. (Egyébként az elosztott fs "protokolja" szinte nem is protokol, bele van építve a rendszerbe...)

> cluster

egy elosztott fs ezt még sokkal jobban tudja mint egy relációs adatbázis, ami (atomi tranzakciós műveleteket feltételezve) csak korlátozottan tud elosztott lenni.

Ami pedig a konkurens elérést illeti: ha jól értelmezem a feladat kiírást, akkor a képek egyszer be vannak szkennelve és azok többé nem módosulnak. Tehát itt nincs szükség konkurens módosításra. A konkurens olvasás része meg még jobb is, mint egy relációs adatbázisnak.

> seaweed-fs is tudja.

Ahogy nézem ez nem fájlrendszer, hanem inkább NoSQL adatbázis, amit http protokollal érsz el.

> egy elosztott fs ezt még sokkal jobban tudja mint egy relációs adatbázis

Én nem kifejezetten relációs adatbázisról beszéltem, de relációsnál vélhetően igazad van.

Egy kicsit mindkettő, de egyik sem teljesen. Az igaz hogy egy API-n keresztül kell elérni, de ez olyan "adatbázis" amit kifejezetten állományok tárolására találtak ki. Pont arra, amire a kérdezőnek szüksége van. Az állományok nem elérési úttal vannak azonosítva, hanem egy egyszerű hash-el, és nem csak a tárolás elosztott hanem az adatok lekérése is az. Belső hálózaton akár átalakítás nélkül lehet CDN-ként használni (web-es kliensekhez) anélkül hogy bármi mást telepíteni kellene hozzá.

Simán mindent bele egy adatbázisba.
A kérdés az, hogy mennyi adat változik, milyen sűrűn, illetve számít-e bármit bármiféle válaszidő?

Ha DB-be teszed, akkor kell egyszer egy full backup és utána inkrementálisok vagy differenciálisok (ízlés szerint).
Illetve tutira konzisztens lesz, könnyű elé tenni valamilyen megjelentítő/módosító/feltöltő interface-t és autentikációt illetve a logolás is sima ügy.