Kompresia dát v Apache Ignite. Sberova skúsenosť

Kompresia dát v Apache Ignite. Sberova skúsenosťPri práci s veľkými objemami dát môže občas nastať problém s nedostatkom miesta na disku. Jedným zo spôsobov, ako tento problém vyriešiť, je kompresia, vďaka ktorej si na rovnakom zariadení môžete dovoliť zväčšiť úložné objemy. V tomto článku sa pozrieme na to, ako funguje kompresia dát v Apache Ignite. Tento článok popisuje iba metódy kompresie disku implementované v rámci produktu. Ostatné metódy kompresie údajov (cez sieť, v pamäti), či už implementované alebo nie, zostanú mimo rozsahu pôsobnosti.

Takže so zapnutým režimom perzistencie v dôsledku zmien údajov vo vyrovnávacej pamäti začne Ignite zapisovať na disk:

  1. Obsah skrýš
  2. Write Ahead Log (ďalej len WAL)

Už nejaký čas existuje mechanizmus na kompresiu WAL, ktorý sa nazýva zhutňovanie WAL. Nedávno vydaný Apache Ignite 2.8 predstavil dva ďalšie mechanizmy, ktoré vám umožňujú komprimovať dáta na disku: kompresiu diskovej stránky na kompresiu obsahu vyrovnávacej pamäte a kompresiu snímok stránky WAL na kompresiu niektorých záznamov WAL. Viac podrobností o všetkých troch týchto mechanizmoch nižšie.

Kompresia stránky disku

Ako to funguje

Najprv sa pozrime veľmi krátko na to, ako Ignite ukladá dáta. Na ukladanie sa používa pamäť stránok. Veľkosť stránky je nastavená na začiatku uzla a nemôže byť zmenená v neskorších fázach; veľkosť stránky musí byť tiež mocninou dvoch a násobkom veľkosti bloku súborového systému. Stránky sa načítavajú do RAM z disku podľa potreby, veľkosť dát na disku môže presiahnuť množstvo pridelenej RAM. Ak v pamäti RAM nie je dostatok miesta na načítanie stránky z disku, staré, už nepoužívané stránky budú z pamäte RAM vyradené.

Dáta sú uložené na disku v nasledujúcej forme: pre každý oddiel každej skupiny vyrovnávacej pamäte sa vytvorí samostatný súbor; v tomto súbore sa stránky zobrazujú jedna za druhou vo vzostupnom indexovom poradí. Úplný identifikátor stránky obsahuje identifikátor skupiny vyrovnávacej pamäte, číslo oddielu a index stránky v súbore. Pomocou úplného identifikátora stránky teda môžeme jednoznačne určiť súbor a posun v súbore pre každú stránku. Viac o stránkovacej pamäti si môžete prečítať v článku Apache Ignite Wiki: Ignite Persistent Store – pod kapotou.

Mechanizmus kompresie stránky disku, ako by ste mohli uhádnuť z názvu, funguje na úrovni stránky. Keď je tento mechanizmus povolený, údaje v pamäti RAM sa spracúvajú tak, ako sú, bez akejkoľvek kompresie, ale keď sa stránky ukladajú z pamäte RAM na disk, sú komprimované.

Komprimácia každej stránky jednotlivo však nie je riešením problému; musíte nejako zmenšiť veľkosť výsledných dátových súborov. Ak veľkosť stránky už nie je pevná, už nemôžeme zapisovať stránky do súboru jednu po druhej, pretože to môže spôsobiť množstvo problémov:

  • Pomocou indexu stránky nedokážeme vypočítať posun, o ktorý sa v súbore nachádza.
  • Nie je jasné, čo robiť so stránkami, ktoré nie sú na konci súboru a menia svoju veľkosť. Ak sa veľkosť strany zmenší, priestor, ktorý uvoľnila, zmizne. Ak sa veľkosť strany zväčší, musíte pre ňu hľadať nové miesto v súbore.
  • Ak sa stránka posunie o počet bajtov, ktorý nie je násobkom veľkosti bloku súborového systému, jej čítanie alebo zápis si bude vyžadovať dotyk ešte jedného bloku súborového systému, čo môže viesť k zníženiu výkonu.

Aby sa predišlo riešeniu týchto problémov na vlastnej úrovni, kompresia stránky disku v Apache Ignite používa mechanizmus súborového systému nazývaný riedke súbory. Riedky súbor je taký, v ktorom niektoré oblasti s nulou môžu byť označené ako "diery". V tomto prípade nebudú na ukladanie týchto dier pridelené žiadne bloky súborového systému, čo vedie k úspore miesta na disku.

Je logické, že na uvoľnenie bloku súborového systému musí byť veľkosť diery väčšia alebo rovná bloku súborového systému, čo ukladá ďalšie obmedzenie veľkosti stránky a Apache Ignite: aby kompresia mala nejaký účinok, veľkosť stránky musí byť striktne väčšia ako veľkosť bloku súborového systému. Ak sa veľkosť stránky rovná veľkosti bloku, potom nikdy nebudeme môcť uvoľniť jeden blok, pretože na uvoľnenie jedného bloku musí komprimovaná stránka zaberať 0 bajtov. Ak sa veľkosť stránky rovná veľkosti 2 alebo 4 blokov, už budeme môcť uvoľniť aspoň jeden blok, ak je naša stránka komprimovaná aspoň na 50% alebo 75%.

Takže konečný popis fungovania mechanizmu: Pri zápise stránky na disk sa robí pokus o kompresiu stránky. Ak veľkosť komprimovanej stránky umožňuje uvoľnenie jedného alebo viacerých blokov súborového systému, stránka sa napíše v komprimovanej forme a namiesto uvoľnených blokov sa vytvorí „diera“ (vykoná sa systémové volanie fallocate() s vlajkou diery). Ak veľkosť komprimovanej stránky neumožňuje uvoľnenie blokov, stránka sa uloží tak, ako je, nekomprimovaná. Všetky posuny strán sa vypočítajú rovnakým spôsobom ako bez kompresie, a to vynásobením indexu strany veľkosťou strany. Nie je potrebné žiadne premiestňovanie stránok na vlastnú päsť. Odsadenie stránok, rovnako ako bez kompresie, spadá na hranice blokov súborového systému.

Kompresia dát v Apache Ignite. Sberova skúsenosť

V aktuálnej implementácii môže Ignite pracovať iba s riedkymi súbormi pod operačným systémom Linux; kompresiu stránky na disku je preto možné povoliť iba pri použití Ignite v tomto operačnom systéme.

Kompresné algoritmy, ktoré možno použiť na kompresiu diskových stránok: ZSTD, LZ4, Snappy. Okrem toho existuje prevádzkový režim (SKIP_GARBAGE), v ktorom sa vyhodí iba nevyužitý priestor na stránke bez použitia kompresie na zostávajúce údaje, čo znižuje zaťaženie CPU v porovnaní s predtým uvedenými algoritmami.

Vplyv na výkon

Skutočné merania výkonu na reálnych stojanoch som, žiaľ, neuskutočnil, keďže tento mechanizmus vo výrobe neplánujeme použiť, ale môžeme teoreticky špekulovať, kde prehráme a kde vyhráme.

Aby sme to dosiahli, musíme si pamätať, ako sa stránky čítajú a zapisujú pri prístupe:

  • Pri vykonávaní operácie čítania sa najskôr vyhľadá v RAM, ak je vyhľadávanie neúspešné, stránka sa načíta do RAM z disku tým istým vláknom, ktoré vykonáva čítanie.
  • Keď sa vykoná operácia zápisu, stránka v pamäti RAM je označená ako špinavá, ale vlákno, ktoré vykonáva zápis, stránku fyzicky neuloží na disk okamžite. Všetky nečisté stránky sa neskôr v procese kontroly uložia na disk v samostatných vláknach.

Takže vplyv na operácie čítania je:

  • Pozitívny (vstup disku) v dôsledku zníženia počtu čítaných blokov súborového systému.
  • Negatívne (CPU), kvôli dodatočnému zaťaženiu vyžadovanému operačným systémom na prácu s riedkymi súbormi. Je tiež možné, že sa tu implicitne objavia ďalšie IO operácie na uloženie zložitejšej štruktúry riedkych súborov (bohužiaľ nepoznám všetky detaily fungovania riedkych súborov).
  • Negatívne (CPU), kvôli potrebe dekomprimovať stránky.
  • Nemá žiadny vplyv na operácie zápisu.
  • Vplyv na proces kontrolného bodu (tu je všetko podobné operáciám čítania):
  • Pozitívny (vstup disku) v dôsledku zníženia počtu zapísaných blokov súborového systému.
  • Negatívne (CPU, prípadne IO disku), kvôli práci s riedkymi súbormi.
  • Negatívne (CPU), kvôli potrebe kompresie stránky.

Ktorá strana váhy prevráti váhu? To všetko do značnej miery závisí od prostredia, ale prikláňam sa k názoru, že kompresia stránky na disku s najväčšou pravdepodobnosťou povedie k zníženiu výkonu na väčšine systémov. Okrem toho testy na iných DBMS, ktoré používajú podobný prístup s riedkymi súbormi, ukazujú pokles výkonu, keď je povolená kompresia.

Ako povoliť a nakonfigurovať

Ako je uvedené vyššie, minimálna verzia Apache Ignite, ktorá podporuje kompresiu stránok na disku, je 2.8 a podporovaný je iba operačný systém Linux. Aktivujte a konfigurujte nasledovne:

  • V ceste triedy musí byť modul zapálenia kompresie. Štandardne sa nachádza v distribúcii Apache Ignite v adresári libs/voliteľné a nie je súčasťou cesty k triede. Môžete jednoducho presunúť adresár o jednu úroveň vyššie do libs a potom, keď ho spustíte cez ignite.sh, bude automaticky povolený.
  • Perzistencia musí byť povolená (povolené cez DataRegionConfiguration.setPersistenceEnabled(true)).
  • Veľkosť stránky musí byť väčšia ako veľkosť bloku súborového systému (môžete ju nastaviť pomocou DataStorageConfiguration.setPageSize() ).
  • Pre každú vyrovnávaciu pamäť, ktorej údaje je potrebné komprimovať, musíte nakonfigurovať metódu kompresie a (voliteľne) úroveň kompresie (metódy CacheConfiguration.setDiskPageCompression() , CacheConfiguration.setDiskPageCompressionLevel()).

Zhutňovanie WAL

Ako to funguje

Čo je to WAL a prečo je to potrebné? Veľmi stručne: toto je denník, ktorý obsahuje všetky udalosti, ktoré v konečnom dôsledku zmenia úložisko stránky. Potrebný je predovšetkým na to, aby sa mohol zotaviť v prípade pádu. Akákoľvek operácia pred odovzdaním kontroly používateľovi musí najprv zaznamenať udalosť vo WAL, aby sa v prípade zlyhania mohla prehrať v denníku a obnoviť všetky operácie, na ktoré používateľ dostal úspešnú odpoveď, aj keď tieto operácie nestihol sa prejaviť v ukladaní stránok na disku (už vyššie Bolo popísané, že samotný zápis do úložiska stránok prebieha v procese zvanom „checkpointing“ s určitým oneskorením samostatnými vláknami).

Záznamy vo WAL sú rozdelené na logické a fyzické. Booleovské sú samotné kľúče a hodnoty. Fyzické – odráža zmeny stránok v úložisku stránok. Zatiaľ čo logické záznamy môžu byť užitočné v niektorých iných prípadoch, fyzické záznamy sú potrebné len na obnovu v prípade havárie a záznamy sú potrebné len od posledného úspešného kontrolného bodu. Nebudeme tu zachádzať do detailov a vysvetľovať, prečo to takto funguje, ale záujemcovia môžu odkázať na už spomínaný článok na Apache Ignite Wiki: Ignite Persistent Store – pod kapotou.

Na jeden logický záznam často pripadá niekoľko fyzických záznamov. To znamená, že napríklad jedna operácia uloženia do vyrovnávacej pamäte ovplyvní niekoľko stránok v pamäti stránok (stránka so samotnými údajmi, stránky s indexmi, stránky s voľnými zoznamami). Pri niektorých syntetických testoch som zistil, že fyzické záznamy zaberajú až 90 % súboru WAL. Sú však potrebné na veľmi krátky čas (štandardne je interval medzi kontrolnými bodmi 3 minúty). Bolo by logické zbaviť sa týchto údajov po strate ich relevantnosti. To je presne to, čo robí mechanizmus zhutňovania WAL: zbavuje sa fyzických záznamov a komprimuje zostávajúce logické záznamy pomocou zip, pričom veľkosť súboru sa veľmi výrazne zmenšuje (niekedy až desaťkrát).

Fyzicky sa WAL skladá z niekoľkých segmentov (štandardne 10) s pevnou veľkosťou (štandardne 64 MB), ktoré sa prepisujú kruhovým spôsobom. Hneď ako sa vyplní aktuálny segment, nasledujúci segment sa priradí ako aktuálny a vyplnený segment sa skopíruje do archívu pomocou samostatného vlákna. Zhutňovanie WAL už funguje aj s archívnymi segmentmi. Ako samostatné vlákno tiež monitoruje vykonávanie kontrolného bodu a spúšťa kompresiu v segmentoch archívu, pre ktoré už nie sú potrebné fyzické záznamy.

Kompresia dát v Apache Ignite. Sberova skúsenosť

Vplyv na výkon

Keďže zhutňovanie WAL prebieha ako samostatné vlákno, nemalo by to mať priamy vplyv na vykonávané operácie. Stále však zaťažuje CPU (kompresia) a disk dodatočne (čítanie každého segmentu WAL z archívu a zápis komprimovaných segmentov), ​​takže ak systém beží na maximálnu kapacitu, povedie to aj k zníženiu výkonu.

Ako povoliť a nakonfigurovať

Pomocou vlastnosti môžete povoliť zhutňovanie WAL WalCompactionEnabled в DataStorageConfiguration (DataStorageConfiguration.setWalCompactionEnabled(true)). Tiež pomocou metódy DataStorageConfiguration.setWalCompactionLevel() môžete nastaviť úroveň kompresie, ak nie ste spokojní s predvolenou hodnotou (BEST_SPEED).

Kompresia snímok stránky WAL

Ako to funguje

Už sme zistili, že vo WAL sa záznamy delia na logické a fyzické. Pre každú zmenu každej stránky sa v pamäti stránok vygeneruje fyzický záznam WAL. Fyzické záznamy sa zase delia na 2 podtypy: záznam stránky a delta záznam. Zakaždým, keď na stránke niečo zmeníme a prenesieme ju z čistého stavu do nečistého, úplná kópia tejto stránky sa uloží do WAL (záznam stránky). Aj keby sme vo WAL zmenili iba jeden bajt, záznam bude o niečo väčší ako veľkosť stránky. Ak na už špinavej stránke niečo zmeníme, vo WAL sa vytvorí delta záznam, ktorý odráža len zmeny oproti predchádzajúcemu stavu stránky, ale nie celú stránku. Keďže resetovanie stavu stránok z nečistých na čisté sa vykonáva počas procesu kontrolného bodu, ihneď po spustení kontrolného bodu budú takmer všetky fyzické záznamy pozostávať iba zo snímok stránok (keďže všetky stránky bezprostredne po spustení kontrolného bodu sú čisté) , potom, ako sa blížime k ďalšiemu kontrolnému bodu, zlomok delta záznamu začne rásť a znova sa resetuje na začiatku ďalšieho kontrolného bodu. Merania na niektorých syntetických testoch ukázali, že podiel snímok stránok na celkovom objeme fyzických záznamov dosahuje 90 %.

Myšlienka kompresie snímok stránky WAL je komprimovať snímky stránky pomocou hotového nástroja na kompresiu stránky (pozri kompresiu stránky na disku). Zároveň sa vo WAL záznamy ukladajú postupne v režime iba pripájania a nie je potrebné viazať záznamy na hranice blokov súborového systému, takže tu na rozdiel od mechanizmu kompresie stránky na disku nepotrebujeme riedke súbory na všetko, teda tento mechanizmus bude fungovať nielen na OS Linux. Navyše nám už nezáleží na tom, ako veľmi sme stránku dokázali skomprimovať. Aj keď sme uvoľnili 1 bajt, je to už pozitívny výsledok a môžeme uložiť komprimované dáta vo WAL, na rozdiel od kompresie diskovej stránky, kde komprimovanú stránku uložíme iba ak sme uvoľnili viac ako 1 blok súborového systému.

Stránky sú vysoko komprimovateľné dáta, ich podiel na celkovom objeme WAL je veľmi vysoký, takže bez zmeny formátu súboru WAL môžeme dosiahnuť výrazné zmenšenie jeho veľkosti. Kompresia vrátane logických záznamov by si vyžadovala zmenu formátu a stratu kompatibility, napríklad pre externých spotrebiteľov, ktorí by mohli mať záujem o logické záznamy, ale neviedla by k výraznému zníženiu veľkosti súboru.

Rovnako ako pri kompresii stránky disku, kompresia snímok stránky WAL môže používať kompresné algoritmy ZSTD, LZ4, Snappy, ako aj režim SKIP_GARBAGE.

Vplyv na výkon

Nie je ťažké si všimnúť, že priame povolenie kompresie snímok stránky WAL ovplyvňuje iba vlákna, ktoré zapisujú údaje do pamäte stránky, teda vlákna, ktoré menia údaje v cache. Čítanie fyzických záznamov z WAL nastane iba raz, a to v momente, keď sa uzol po páde zdvihne (a iba ak spadne počas kontrolného bodu).

Toto ovplyvňuje vlákna, ktoré menia údaje nasledujúcim spôsobom: získame negatívny efekt (CPU) kvôli potrebe komprimovať stránku zakaždým pred zápisom na disk a pozitívny efekt (disk IO) kvôli zníženiu množstva zapísané údaje. V súlade s tým je tu všetko jednoduché: ak je výkon systému obmedzený CPU, dostaneme miernu degradáciu, ak je obmedzený diskovými I/O, dostaneme zvýšenie.

Zmenšenie veľkosti WAL nepriamo ovplyvňuje aj (pozitívne) toky, ktoré ukladajú segmenty WAL do archívu a toky komprimácie WAL.

Testy reálneho výkonu v našom prostredí s použitím syntetických údajov ukázali mierny nárast (priepustnosť sa zvýšila o 10 %-15 %, latencia klesla o 10 %-15 %).

Ako povoliť a nakonfigurovať

Minimálna verzia Apache Ignite: 2.8. Aktivujte a konfigurujte nasledovne:

  • V ceste triedy musí byť modul zapálenia kompresie. Štandardne sa nachádza v distribúcii Apache Ignite v adresári libs/voliteľné a nie je súčasťou cesty k triede. Môžete jednoducho presunúť adresár o jednu úroveň vyššie do libs a potom, keď ho spustíte cez ignite.sh, bude automaticky povolený.
  • Perzistencia musí byť povolená (povolené cez DataRegionConfiguration.setPersistenceEnabled(true)).
  • Režim kompresie musí byť nastavený pomocou metódy DataStorageConfiguration.setWalPageCompression(), kompresia je predvolene vypnutá (režim DISABLED).
  • Voliteľne môžete pomocou metódy nastaviť úroveň kompresie DataStorageConfiguration.setWalPageCompression(), pozrite si javadoc pre metódu pre platné hodnoty pre každý režim.

Záver

Uvažované mechanizmy kompresie údajov v Apache Ignite možno použiť nezávisle od seba, ale akceptovateľná je aj ich akákoľvek kombinácia. Pochopenie ich fungovania vám umožní určiť, nakoľko sú vhodné pre vaše úlohy vo vašom prostredí a čo všetko budete musieť obetovať pri ich používaní. Kompresia stránky disku je navrhnutá tak, aby komprimovala hlavné úložisko a môže poskytnúť stredný kompresný pomer. Kompresia snímok stránky WAL poskytne priemerný stupeň kompresie pre súbory WAL a s najväčšou pravdepodobnosťou dokonca zlepší výkon. Zhutnenie WAL nebude mať pozitívny vplyv na výkon, ale čo najviac zníži veľkosť súborov WAL odstránením fyzických záznamov.

Zdroj: hab.com

Pridať komentár