6.1 Rövidítések csatája: BASE vs. SAV
"A kémiában a pH a vizes oldatok relatív savasságát méri. A pH-skála 0-tól (erősen savas anyagok) 14-ig (erősen lúgos anyagok) tart; a tiszta víz pH-ja 25 °C-on 7, és semleges. Az adatmérnökök ezt a metaforát használták az adatbázisok összehasonlítására a tranzakciók megbízhatósága tekintetében." Valószínűleg ez volt az ötlet: minél magasabb a pH, pl. minél közelebb van az adatbázis az "alkaline"-hoz ("BASE"), annál kevésbé megbízhatóak a tranzakciók. |
A népszerű relációs adatbázisok, mint például a MySQL, csak az ACID alapján jelentek meg. De az elmúlt tíz évben az úgynevezett NoSQL-adatbázisok, amelyek több, nagyon különböző típusú adatbázist egyesítenek ezen a néven, meglehetősen jól működtek ACID nélkül. Valójában nagyon sok fejlesztő dolgozik NoSQL adatbázisokkal, és egyáltalán nem törődik a tranzakciókkal és azok megbízhatóságával. Lássuk, igazuk van-e.
Nem lehet általánosságban beszélni a NoSQL adatbázisról, mert ez csak egy jó absztrakció. A NoSQL adatbázisok az adattárolási alrendszerek kialakításában, sőt az adatmodellek kialakításában is különböznek egymástól: a NoSQL egyszerre dokumentum-orientált CouchDB és gráf Neo4J. De ha a tranzakciókkal összefüggésben beszélünk róluk, akkor egy dologban általában hasonlóak: az atomitás és az elszigeteltség korlátozott változatait biztosítják, ezért nem adnak ACID-garanciát. Hogy megértsük, mit jelent ez, válaszoljunk a kérdésre: mit kínálnak, ha nem SAVAT? Semmi?
Nem igazán. Hiszen a relációs adatbázisokhoz hasonlóan nekik is szép csomagban kell eladniuk magukat. És kitalálták a saját "kémiai" rövidítésüket - BASE.
6.2 A BASE mint antagonista
És itt megint nem a betűk sorrendjében megyek, hanem az alapvető kifejezéssel - a következetesség - kezdem. Egyenlíteni kell a felismerési hatásodat, mert ennek a konzisztenciának nem sok köze van az ACID konzisztenciájához. A probléma a következetesség kifejezéssel az, hogy túl sok összefüggésben használják. Ennek a konzisztenciának azonban sokkal szélesebb a felhasználási kontextusa, és valójában ez az a konzisztencia, amelyről az elosztott rendszerekről beszélünk.
A relációs adatbázisok, amelyekről fentebb beszéltünk, különböző szintű tranzakciós elkülönítést biztosítanak, és ezek közül a legszigorúbbak biztosítják, hogy egy tranzakció ne lássa a másik tranzakció által végrehajtott érvénytelen változtatásokat. Ha egy üzletben a pénztárnál áll, és abban a pillanatban a bérleti díjat levonják a számlájáról, de a bérleti díj átutalásával történő tranzakció meghiúsul, és a számlája visszaáll a korábbi értékére (a pénz nincs megterhelve), akkor a fizetési tranzakciója a pénztárnál nem mindenki veszi észre ezeket a gesztusokat - elvégre az a tranzakció soha nem ment át, és a tranzakció elkülönítésének követelménye alapján átmeneti változásait más tranzakciók nem vehetik észre.
Sok NoSQL-adatbázis lemond az elkülönítési garanciáról, és "esetleges konzisztenciát" kínál, amelynek révén végül érvényes adatokat fog látni, de fennáll annak az esélye, hogy a tranzakció érvénytelen értékeket fog olvasni - azaz ideiglenes, részben frissített vagy elavult. Lehetséges, hogy az adatok konzisztenssé válnak olvasás közben "lusta" módban ("lusta az olvasási időben").
A NoSQL-t valós idejű elemzési adatbázisnak tervezték, és a nagyobb sebesség elérése érdekében feláldozták a konzisztenciát. És Eric Brewer, ugyanaz a fickó, aki megalkotta a BASE kifejezést, megfogalmazta az úgynevezett "CAP-tételt", amely szerint:
Az elosztott számítástechnika bármely megvalósításához a következő három tulajdonság közül legfeljebb kettő biztosítható:
- adatkonzisztencia ( konzisztencia ) - a különböző csomópontokra (példányokra) vonatkozó adatok nem mondanak ellent egymásnak;
- rendelkezésre állás ( elérhetőség ) - az elosztott rendszerhez intézett bármely kérés helyes válasszal végződik, de nem garantálható, hogy az összes rendszercsomópont válasza megegyezik;
- partíciótűrés (partíciótűrés ) - Ha nincs is kapcsolat a csomópontok között, továbbra is egymástól függetlenül működnek.
Ha nagyon egyszerű magyarázatot szeretne a CAP-ról, akkor tessék.
Vannak olyan vélemények, hogy a CAP-tétel nem működik, és általában túl absztrakt módon van megfogalmazva. Így vagy úgy, a NoSQL-adatbázisok gyakran megtagadják a konzisztenciát a CAP-tétel kontextusában, amely a következő helyzetet írja le: az adatok frissítése megtörtént egy több példányos fürtben, de a változtatások még nem lettek szinkronizálva minden példányon. Emlékszel, fentebb említettem a DynamoDB példát, amely azt mondta, hogy a változtatások tartósak lettek – itt van egy HTTP 200 –, de én csak 10 másodperc után láttam a változásokat? Egy másik példa a fejlesztők mindennapi életéből a DNS, a domain névrendszer. Ha valaki nem tudja, akkor pontosan ez az a „szótár”, amely a http (s) címeket IP-címekké fordítja.
A frissített DNS-rekord a gyorsítótárazási időköz beállításai szerint kerül továbbításra a szerverekre – így a frissítések nem azonnal észrevehetők. Nos, hasonló időbeli inkonzisztencia (vagyis végső soron konzisztencia) előfordulhat egy relációs adatbázis-fürttel (mondjuk a MySQL-lel) – elvégre ennek a konzisztenciának semmi köze az ACID konzisztenciájához. Ezért fontos megérteni, hogy ebben az értelemben az SQL és a NoSQL adatbázisok valószínűleg nem nagyon különböznek egymástól, ha egy fürt több példányáról van szó.
Ezen túlmenően a végpontok közötti konzisztencia azt is jelentheti, hogy az írási kérelmek soron kívül történnek: azaz minden adat kiírásra kerül, de a végül beérkező érték nem lesz az utolsó az írási sorban.
A nem ACID NoSQL adatbázisok a végpontok közötti konzisztencia modellnek köszönhetően úgynevezett „soft state”-tel rendelkeznek, ami azt jelenti, hogy a rendszer állapota idővel akár bevitel nélkül is változhat. Az ilyen rendszerek azonban nagyobb hozzáférést biztosítanak. A 100%-os rendelkezésre állás biztosítása nem triviális feladat, ezért „alapvető rendelkezésre állásról” beszélünk. És ez a három fogalom együtt: „alapvetően elérhető”, „lágy állapot” („lágy állapot”) és „esetleges konzisztencia” alkotja a BASE mozaikszót.
Őszintén szólva számomra a BASE koncepciója üresebb marketing burkolónak tűnik, mint az ACID - mert nem ad semmi újat, és semmilyen módon nem jellemzi az adatbázist. A címkék (ACID, BASE, CAP) rögzítése pedig bizonyos adatbázisokhoz csak megzavarhatja a fejlesztőket. Azért döntöttem úgy, hogy mégis megismertessem Önnel ezt a kifejezést, mert az adatbázis tanulmányozása során nehéz megkerülni, de most, hogy tudod, mi az, szeretném, ha mielőbb felejtsd el. És térjünk vissza az elszigeteltség fogalmához.
6.3 Tehát a BASE adatbázisok egyáltalán nem felelnek meg az ACID kritériumoknak?
Lényegében az ACID adatbázisok különböznek a nem ACID adatbázisoktól, hogy a nem ACID adatbázisok valójában lemondanak az elkülönítésről. Ezt fontos megérteni. De még fontosabb, hogy olvassa el az adatbázis dokumentációját, és tesztelje le őket, ahogyan az Ermitázs projekt srácai teszik. Nem annyira fontos, hogy ennek vagy annak az adatbázisnak a készítői pontosan hogyan hívják agyszüleményeket - ACID vagy BASE, CAP vagy nem CAP. Az a fontos, hogy ez vagy az az adatbázis pontosan mit ad.
Ha az adatbázis készítői azt állítják, hogy ACID garanciákat nyújt, akkor ennek valószínűleg megvan az oka, de célszerű saját kezűleg tesztelni, hogy ez így van-e és milyen mértékben. Ha kijelentik, hogy adatbázisuk nem nyújt ilyen garanciákat, akkor ez a következőket jelentheti:
-
A DB nem garantálja az atomitást. Míg egyes NoSQL adatbázisok külön API-t kínálnak az atomi műveletekhez (pl. DynamoDB);
- A DB nem nyújt elszigetelési garanciát. Ez például azt jelentheti, hogy az adatbázis nem abban a sorrendben írja ki az adatokat, ahogyan azokat beírták.
Ami a tartóssági garanciát illeti, sok adatbázis kompromisszumot köt ezen a ponton a teljesítmény érdekében. A lemezre írás túl hosszú művelet, és többféleképpen is megoldható ez a probléma. Nem akarok nagyon belemenni az adatbázis-elméletbe, de hogy nagyjából megértsd, merre nézz, általánosságban leírom, hogy a különböző adatbázisok hogyan oldják meg a problémát a tartóssággal.
A különböző adatbázisok összehasonlításához többek között tudnia kell, hogy egy adott adatbázis adattárolási és visszakeresési alrendszere milyen adatstruktúrák alapja. Röviden: a különböző adatbázisok eltérő módon valósítják meg az indexelést - vagyis az adatokhoz való hozzáférést. Egyesek lehetővé teszik az adatok gyorsabb írását, mások - gyorsabban olvashatók. De általánosságban nem mondható el, hogy egyes adatstruktúrák növelik vagy csökkentik a tartósságot.
6.4 hogyan indexelik a különböző adatbázisok az adatokat, és ez hogyan befolyásolja a tartósságot stb
Az adatok tárolásának és visszakeresésének két fő módja van.
Az adatmentés legegyszerűbb módja, ha a fájl végére naplószerűen adunk hozzá műveleteket (vagyis mindig történik hozzáfűzési művelet): teljesen mindegy, hogy adatokat akarunk hozzáadni, módosítani vagy törölni - minden A CRUD műveletek egyszerűen a naplóba íródnak. A naplóban való keresés nem hatékony, és itt jön be az index – egy speciális adatstruktúra, amely metaadatokat tárol arról, hogy pontosan hol vannak az adatok. A naplók legegyszerűbb indexelési stratégiája egy hash-térkép, amely nyomon követi a kulcsokat és az értékeket. Az értékek a fájlba írt adatok bájteltolására vonatkoznak, amely a napló (napló) és a lemezen tárolódik. Ezt az adatstruktúrát teljes egészében a memóriában tárolják, míg maguk az adatok a lemezen vannak, és LSM fának (napló strukturált egyesítés) nevezik.
Valószínűleg azon töprengett: ha folyamatosan a folyóiratba írjuk a műveleteinket, akkor az iszonyúan meg fog nőni? Igen, és ezért találták ki a tömörítési technikát, amely bizonyos periodikusan „tisztítja” az adatokat, vagyis minden kulcsnál csak a legrelevánsabb értéket hagyja meg, vagy törli. Ha pedig több naplónk van a lemezen, de több is, és ezek mindegyike rendezve van, akkor egy új adatstruktúrát kapunk SSTable ("sorted string table") néven, és ez kétségtelenül javítja a teljesítményünket. Ha a memóriában szeretnénk rendezni, akkor egy hasonló struktúrát kapunk - az úgynevezett MemTable-t, de ezzel az a probléma, hogy ha végzetes adatbázis-összeomlás következik be, akkor az utoljára írt (memTable-ben található, de még nem írt adat) lemez) elvesznek. Tulajdonképpen,
Az indexelés másik megközelítése a B-fákon („B-fák”) alapul. A B-fában az adatok rögzített méretű oldalakon íródnak a lemezre. Ezek az adatblokkok gyakran körülbelül 4 KB méretűek, és kulcs-érték párjaik kulcs szerint vannak rendezve. Egy B-fa csomópont olyan, mint egy tömb, amely számos oldalra mutató hivatkozásokat tartalmaz. Max. egy tömbben lévő hivatkozások számát elágazási tényezőnek nevezzük. Minden oldaltartomány egy másik B-fa csomópont, amely más oldaltartományokra mutató hivatkozásokat tartalmaz.
Végül lapszinten találja meg az egyes oldalakat. Ez az ötlet hasonló az alacsony szintű programozási nyelvek mutatóihoz, azzal a különbséggel, hogy ezek az oldalhivatkozások nem a memóriában, hanem a lemezen vannak tárolva. Amikor INSERT és DELETE fordul elő az adatbázisban, akkor néhány csomópont két részfára osztható fel, hogy megfeleljen az elágazási tényezőnek. Ha az adatbázis bármilyen okból meghibásodik a folyamat közepén, az adatok sértetlensége veszélybe kerülhet. Ennek elkerülése érdekében a B-fákat használó adatbázisok egy "előreírási naplót" vezetnek, amely minden egyes tranzakciót rögzít. Ez a WAL a B-fa állapotának visszaállítására szolgál, ha az sérült. És úgy tűnik, hogy ez teszi jobbá a B-fákat használó adatbázisokat a tartósság szempontjából. De az LSM-alapú adatbázisok olyan fájlokat is karbantarthatnak, amelyek lényegében ugyanazt a funkciót látják el, mint a WAL. Ezért megismétlem, amit már mondtam, és talán többször is: értse meg az Ön által választott adatbázis működési mechanizmusait.
A B-fákkal kapcsolatban azonban biztos, hogy jók a tranzakciós célokra: minden kulcs csak egy helyen fordul elő az indexben, míg a naplózott tárolási alrendszerekben ugyanannak a kulcsnak több másolata is lehet különböző szilánkokban (például , amíg a következő tömörítés történik).
Az index kialakítása azonban közvetlenül befolyásolja az adatbázis teljesítményét. Az LSM-fánál a lemezre történő írás szekvenciális, és a B-fák többszörös véletlenszerű lemezelérést okoznak, így az írási műveletek gyorsabbak az LSM-mel, mint a B-fákkal. A különbség különösen jelentős a mágneses merevlemez-meghajtók (HDD) esetében, ahol a szekvenciális írás sokkal gyorsabb, mint a véletlenszerű írás. Az olvasás lassabb az LSM fákon, mert több különböző adatstruktúrát és SS-táblát kell átnéznie, amelyek a tömörítés különböző szakaszaiban vannak. Részletesebben így néz ki. Ha egy egyszerű adatbázis-lekérdezést végzünk LSM-mel, akkor először a kulcsot keressük meg a MemTable-ben. Ha nincs ott, nézzük meg a legújabb SSTable-t; ha nincs ott, akkor megnézzük az utolsó előtti SSTable-t stb. Ha a kért kulcs nem létezik, akkor az LSM-nél ezt utoljára tudjuk meg. Az LSM fákat például: LevelDB, RocksDB, Cassandra és HBase használják.
Annyira részletesen leírom az egészet, hogy megértsd, az adatbázis kiválasztásakor sokféle dolgot figyelembe kell venni: például elvárod-e, hogy többet írj vagy olvass adatokat. És még nem említettem az adatmodellek különbségét (kell-e bejárni az adatokat, ahogy a grafikonmodell megengedi? Van-e egyáltalán kapcsolat a különböző egységek között az adataidban - akkor a relációs adatbázisok jönnek a segítségedre?), és 2 típusú adatsémák - íráskor (mint sok NoSQL-ben) és olvasáskor (mint a relációs).
Ha visszatérünk a tartósság szempontjához, akkor a következtetés a következő: minden lemezre író adatbázis, függetlenül az indexelési mechanizmusoktól, jó garanciákat nyújthat az adatok tartósságára, de minden egyes adatbázissal foglalkozni kell. , mit kínál pontosan.
6.5 A memórián belüli DB-k működése
Egyébként a lemezre író adatbázisok mellett léteznek úgynevezett "memórián belüli" adatbázisok is, amelyek főleg RAM-mal működnek. Röviden, a memórián belüli adatbázisok általában alacsonyabb tartósságot kínálnak a gyorsabb írási és olvasási sebesség érdekében, de ez bizonyos alkalmazásoknál megfelelő lehet.
A tény az, hogy a RAM-memória régóta drágább, mint a lemezek, de az utóbbi időben rohamosan olcsóbbá vált, ami egy új típusú adatbázis létrejöttét eredményezte - ami logikus, tekintettel a RAM-ból történő adatolvasási és -írási sebességre. De joggal kérdezi majd: mi a helyzet ezen adatbázisok adatbiztonságával? Itt is meg kell nézni a megvalósítás részleteit. Általában az ilyen adatbázisok fejlesztői a következő mechanizmusokat kínálják:
- Használhat akkumulátorral működő RAM-ot;
- Lehetőség van változási naplók lemezre írására (olyan, mint a fent említett WAL-ok), de magát az adatot nem;
- Időnként másolatokat írhat az adatbázis állapotáról a lemezre (ami más opciók használata nélkül nem ad garanciát, csak javítja a tartósságot);
- Lemásolhatja a RAM állapotát más gépeken.
Például a memóriában lévő Redis adatbázis, amelyet főként üzenetsorként vagy gyorsítótárként használnak, hiányzik az ACID tartóssága: nem garantálja, hogy a sikeresen végrehajtott parancs a lemezen tárolódik, mivel a Redis az adatokat a lemezre üríti (ha a perzisztencia engedélyezve van) csak aszinkron módon, rendszeres időközönként.
Ez azonban nem minden alkalmazásnál kritikus: találtam egy példát az EtherPad kooperatív online szerkesztőjére, amely 1-2 másodpercenként kiürült, és potenciálisan a felhasználó elveszíthet néhány betűt vagy egy szót, ami aligha volt kritikus. Ellenkező esetben, mivel a memórián belüli adatbázisok jók abban, hogy olyan adatmodelleket biztosítanak, amelyeket nehéz lenne lemezindexekkel megvalósítani, a Redis használható tranzakciók megvalósítására - a prioritási sor lehetővé teszi ezt.