Datakompressie in Apache Ignite. Sber se ervaring

Datakompressie in Apache Ignite. Sber se ervaringWanneer daar met groot volumes data gewerk word, kan die probleem van 'n gebrek aan skyfspasie soms ontstaan. Een manier om hierdie probleem op te los, is kompressie, waardeur jy op dieselfde toerusting kan bekostig om bergingsvolumes te verhoog. In hierdie artikel sal ons kyk hoe datakompressie in Apache Ignite werk. Hierdie artikel sal slegs die skyfkompressiemetodes beskryf wat binne die produk geïmplementeer is. Ander metodes van datakompressie (oor die netwerk, in geheue), hetsy geïmplementeer of nie, sal buite die bestek bly.

Dus, met volhardingsmodus geaktiveer, as gevolg van veranderinge in data in die kas, begin Ignite na skyf skryf:

  1. Inhoud van caches
  2. Skryf Vooruit-logboek (hierna eenvoudig WAL)

Daar is al 'n geruime tyd 'n meganisme vir WAL-kompressie, genaamd WAL-kompaksie. Die onlangs vrygestelde Apache Ignite 2.8 het nog twee meganismes bekendgestel wat jou toelaat om data op skyf saam te pers: skyfbladsy-kompressie vir die saampersing van die inhoud van kas en WAL-bladsy-snapshot-kompressie vir die saampersing van sommige WAL-inskrywings. Meer besonderhede oor al drie hierdie meganismes hieronder.

Skyfbladsy-kompressie

Hoe werk dit

Kom ons kyk eers baie kort na hoe Ignite data stoor. Bladgeheue word vir berging gebruik. Die bladsygrootte word aan die begin van die nodus gestel en kan nie op latere stadiums verander word nie; ook moet die bladsygrootte 'n mag van twee en 'n veelvoud van die lêerstelselblokgrootte wees. Bladsye word in RAM vanaf skyf gelaai soos nodig; die grootte van data op skyf kan die hoeveelheid toegekende RAM oorskry. As daar nie genoeg spasie in RAM is om 'n bladsy van skyf af te laai nie, sal ou bladsye wat nie meer gebruik word nie uit RAM verwyder word.

Die data word in die volgende vorm op skyf gestoor: 'n aparte lêer word vir elke partisie van elke kasgroep geskep; in hierdie lêer verskyn bladsye een na die ander in stygende indeksvolgorde. Die volledige bladsy-identifiseerder bevat die kasgroepidentifiseerder, partisienommer en bladsy-indeks in die lêer. Dus, deur die volledige bladsy identifiseerder te gebruik, kan ons die lêer en die afwyking in die lêer vir elke bladsy uniek bepaal. Jy kan meer lees oor blaaigeheue in die Apache Ignite Wiki-artikel: Ignite Persistent Store - onder die enjinkap.

Die skyfbladsy-kompressiemeganisme, soos u dalk uit die naam kan raai, werk op bladsyvlak. Wanneer hierdie meganisme geaktiveer is, word data in RAM verwerk soos dit is, sonder enige kompressie, maar wanneer bladsye van RAM na skyf gestoor word, word hulle saamgepers.

Maar om elke bladsy afsonderlik saam te pers is nie 'n oplossing vir die probleem nie; jy moet op een of ander manier die grootte van die resulterende datalêers verminder. As die bladsygrootte nie meer vasgestel is nie, kan ons nie meer bladsye na die lêer na die lêer skryf nie, aangesien dit 'n aantal probleme kan veroorsaak:

  • Deur die bladsy-indeks te gebruik, sal ons nie die offset waarmee dit in die lêer geleë is, kan bereken nie.
  • Dit is nie duidelik wat om te doen met bladsye wat nie aan die einde van die lêer is nie en hul grootte verander. As die bladsygrootte afneem, verdwyn die spasie wat dit vrygemaak het. As die bladsygrootte toeneem, moet jy 'n nuwe plek in die lêer daarvoor soek.
  • As 'n bladsy met 'n aantal grepe beweeg wat nie 'n veelvoud van die lêerstelselblokgrootte is nie, sal die lees of skryf daarvan vereis dat u nog een lêerstelselblok aangeraak het, wat kan lei tot prestasie-agteruitgang.

Om te verhoed dat hierdie probleme op sy eie vlak opgelos word, gebruik skyfbladsy-kompressie in Apache Ignite 'n lêerstelselmeganisme genaamd yl lêers. 'n Skaars lêer is een waarin sommige nul-gevulde streke as "gate" gemerk kan word. In hierdie geval sal geen lêerstelselblokke toegewys word om hierdie gate te stoor nie, wat lei tot besparings op skyfspasie.

Dit is logies dat om 'n lêerstelselblok te bevry, die grootte van die gat groter as of gelyk aan die lêerstelselblok moet wees, wat 'n bykomende beperking op die bladsygrootte en Apache Ignite stel: vir kompressie om enige effek te hê, die bladsygrootte moet streng groter as die grootte van die lêerstelselblok wees. As die bladsygrootte gelyk is aan die blokgrootte, sal ons nooit 'n enkele blok kan vrymaak nie, aangesien die saamgeperste bladsy 0 grepe moet beslaan om 'n enkele blok vry te maak. As die bladsygrootte gelyk is aan die grootte van 2 of 4 blokke, sal ons reeds ten minste een blok kan vrystel as ons bladsy saamgepers is tot ten minste 50% of 75% onderskeidelik.

Dus, die finale beskrywing van hoe die meganisme werk: Wanneer 'n bladsy na skyf geskryf word, word 'n poging aangewend om die bladsy saam te pers. As die grootte van die saamgeperste bladsy toelaat dat een of meer lêerstelselblokke vrygestel word, word die bladsy in saamgeperste vorm geskryf, en 'n "gat" word in die plek van die vrygestelde blokke gemaak ('n stelseloproep word uitgevoer fallocate() met die ponsgat-vlag). As die grootte van die saamgeperste bladsy nie toelaat dat die blokke bevry word nie, word die bladsy gestoor soos dit is, ongecomprimeerd. Alle bladsyafsettings word op dieselfde manier as sonder kompressie bereken deur die bladsyindeks met die bladsygrootte te vermenigvuldig. Geen hervestiging van bladsye word op jou eie vereis nie. Bladsyverskuiwings, net soos sonder kompressie, val op die grense van lêerstelselblokke.

Datakompressie in Apache Ignite. Sber se ervaring

In die huidige implementering kan Ignite slegs met yl lêers onder Linux OS werk; dienooreenkomstig kan skyfbladsy-kompressie slegs geaktiveer word wanneer Ignite op hierdie bedryfstelsel gebruik word.

Kompressie-algoritmes wat gebruik kan word vir skyfbladsy-kompressie: ZSTD, LZ4, Snappy. Daarbenewens is daar 'n bedryfsmodus (SKIP_GARBAGE), waarin slegs ongebruikte spasie op die bladsy uitgegooi word sonder om kompressie op die oorblywende data toe te pas, wat die las op die SVE verminder in vergelyking met die voorheen gelysde algoritmes.

Prestasie-impak

Ongelukkig het ek nie werklike prestasiemetings op werklike erwe gedoen nie, aangesien ons nie van plan is om hierdie meganisme in produksie te gebruik nie, maar ons kan teoreties spekuleer waar ons sal verloor en waar ons sal wen.

Om dit te doen, moet ons onthou hoe bladsye gelees en geskryf word wanneer toegang verkry word:

  • Wanneer 'n leesbewerking uitgevoer word, word dit eers in RAM gesoek; as die soektog onsuksesvol is, word die bladsy in RAM vanaf skyf gelaai deur dieselfde draad wat die lees uitvoer.
  • Wanneer 'n skryfbewerking uitgevoer word, word die bladsy in RAM as vuil gemerk, maar die bladsy word nie onmiddellik fisies op skyf gestoor deur die draad wat die skryfwerk uitvoer nie. Alle vuil bladsye word later in die kontrolepuntproses in aparte drade op skyf gestoor.

Die impak op leesbewerkings is dus:

  • Positief (skyf IO), as gevolg van 'n afname in die aantal gelees lêerstelsel blokke.
  • Negatief (CPU), as gevolg van die bykomende las wat deur die bedryfstelsel vereis word om met yl lêers te werk. Dit is ook moontlik dat addisionele IO-bewerkings implisiet hier sal verskyn om 'n meer komplekse yl lêerstruktuur te stoor (ongelukkig is ek nie vertroud met al die besonderhede van hoe yl lêers werk nie).
  • Negatief (CPU), as gevolg van die behoefte om bladsye te dekomprimeer.
  • Daar is geen impak op skryfbedrywighede nie.
  • Impak op die kontrolepuntproses (alles hier is soortgelyk aan leesbewerkings):
  • Positief (skyf IO), as gevolg van 'n afname in die aantal geskrewe lêerstelselblokke.
  • Negatief (CPU, moontlik skyf IO), as gevolg van werk met yl lêers.
  • Negatief (CPU), as gevolg van die behoefte aan bladsykompressie.

Watter kant van die skaal sal die skaal kantel? Dit hang alles baie af van die omgewing, maar ek is geneig om te glo dat skyfbladsy-kompressie heel waarskynlik sal lei tot prestasie-agteruitgang op die meeste stelsels. Boonop toon toetse op ander DBBS'e wat 'n soortgelyke benadering met yl lêers gebruik 'n daling in werkverrigting wanneer kompressie geaktiveer is.

Hoe om te aktiveer en op te stel

Soos hierbo genoem, is die minimum weergawe van Apache Ignite wat skyfbladsy-kompressie ondersteun 2.8 en slegs die Linux-bedryfstelsel word ondersteun. Aktiveer en konfigureer soos volg:

  • Daar moet 'n ontsteek-kompressie-module in die klas-pad wees. By verstek is dit in die Apache Ignite-verspreiding in die libs/opsionele gids geleë en is dit nie by die klaspad ingesluit nie. Jy kan eenvoudig die gids een vlak opskuif na libs en dan wanneer jy dit deur ignite.sh hardloop, sal dit outomaties geaktiveer word.
  • Volharding moet geaktiveer word (Aktiveer via DataRegionConfiguration.setPersistenceEnabled(true)).
  • Die bladsygrootte moet groter wees as die lêerstelselblokgrootte (jy kan dit stel deur DataStorageConfiguration.setPageSize() ).
  • Vir elke kas waarvan die data saamgepers moet word, moet jy die kompressiemetode en (opsioneel) die kompressievlak (metodes) opstel CacheConfiguration.setDiskPageCompression() , CacheConfiguration.setDiskPageCompressionLevel()).

WAL verdigting

Hoe werk dit

Wat is WAL en hoekom is dit nodig? Baie kort: dit is 'n logboek wat alle gebeure bevat wat uiteindelik die bladsyberging verander. Dit is hoofsaaklik nodig om te kan herstel in geval van 'n val. Enige bewerking, voordat beheer aan die gebruiker gegee word, moet eers 'n gebeurtenis in WAL opneem, sodat in geval van mislukking, dit in die log afgespeel kan word en alle bewerkings waarvoor die gebruiker 'n suksesvolle reaksie ontvang het, kan herstel, selfs al is hierdie bewerkings het nie tyd gehad om in die bladsyberging op skyf weerspieël te word nie (reeds hierbo Dit is beskryf dat die werklike skryf na die bladsystoor gedoen word in 'n proses genaamd "checkpointing" met 'n mate van vertraging deur aparte drade).

Inskrywings in WAL word in logies en fisies verdeel. Boolese is die sleutels en waardes self. Fisies - weerspieël veranderinge aan bladsye in die bladsywinkel. Alhoewel logiese rekords nuttig kan wees vir sommige ander gevalle, is fisiese rekords slegs nodig vir herstel in die geval van 'n ongeluk en rekords word slegs benodig sedert die laaste suksesvolle kontrolepunt. Hier gaan ons nie in detail ingaan en verduidelik hoekom dit so werk nie, maar belangstellendes kan na die reeds genoemde artikel oor die Apache Ignite Wiki verwys: Ignite Persistent Store - onder die enjinkap.

Daar is dikwels verskeie fisiese rekords per logiese rekord. Dit wil sê, byvoorbeeld, een plaasbewerking in die kas beïnvloed verskeie bladsye in bladsygeheue ('n bladsy met die data self, bladsye met indekse, bladsye met vrylyste). In sommige sintetiese toetse het ek gevind dat fisiese rekords tot 90% van die WAL-lêer beslaan. Hulle word egter vir 'n baie kort tydjie benodig (by verstek is die interval tussen kontrolepunte 3 minute). Dit sal logies wees om van hierdie data ontslae te raak nadat dit die relevansie daarvan verloor het. Dit is presies wat die WAL-kompaksiemeganisme doen: dit raak ontslae van fisiese rekords en komprimeer die oorblywende logiese rekords met behulp van zip, terwyl die lêergrootte baie aansienlik verminder word (soms met tientalle kere).

Fisies bestaan ​​WAL uit verskeie segmente (10 by verstek) van 'n vaste grootte (64MB by verstek), wat op 'n sirkelvormige wyse oorgeskryf word. Sodra die huidige segment gevul is, word die volgende segment as huidige toegeken, en die gevulde segment word deur 'n aparte draad na die argief gekopieer. WAL-verdigting werk reeds met argiefsegmente. Ook, as 'n aparte draad, monitor dit die uitvoering van die kontrolepunt en begin kompressie in argiefsegmente waarvoor fisiese rekords nie meer nodig is nie.

Datakompressie in Apache Ignite. Sber se ervaring

Prestasie-impak

Aangesien WAL-verdigting as 'n aparte draad loop, behoort daar geen direkte impak te wees op die bewerkings wat uitgevoer word nie. Maar dit plaas steeds addisionele agtergrondlading op die SVE (kompressie) en skyf (lees elke WAL-segment uit die argief en skryf die saamgeperste segmente), so as die stelsel op sy maksimum kapasiteit werk, sal dit ook lei tot prestasie-agteruitgang.

Hoe om te aktiveer en op te stel

U kan WAL-verdigting aktiveer deur die eiendom te gebruik WalCompactionEnabled в DataStorageConfiguration (DataStorageConfiguration.setWalCompactionEnabled(true)). Ook, deur die DataStorageConfiguration.setWalCompactionLevel() metode te gebruik, kan jy die kompressievlak stel as jy nie tevrede is met die verstekwaarde (BEST_SPEED) nie.

WAL bladsy momentopname kompressie

Hoe werk dit

Ons het reeds uitgevind dat in WAL rekords in logies en fisies verdeel word. Vir elke verandering aan elke bladsy word 'n fisiese WAL-rekord in bladsygeheue gegenereer. Fisiese rekords word op hul beurt ook in 2 subtipes verdeel: bladsy-momentopname-rekord en delta-rekord. Elke keer as ons iets op 'n bladsy verander en dit van 'n skoon toestand na 'n vuil toestand oordra, word 'n volledige kopie van hierdie bladsy in WAL (bladsy-kiekierekord) gestoor. Selfs as ons net een greep in WAL verander het, sal die rekord effens groter as die bladsygrootte wees. As ons iets op 'n reeds vuil bladsy verander, dan word 'n delta-rekord in WAL gevorm, wat slegs veranderinge in vergelyking met die vorige toestand van die bladsy weerspieël, maar nie die hele bladsy nie. Aangesien die terugstelling van die toestand van bladsye van vuil na skoon uitgevoer word tydens die kontrolepuntproses, onmiddellik na die begin van die kontrolepunt, sal byna alle fisiese rekords slegs uit momentopnames van bladsye bestaan ​​(aangesien alle bladsye onmiddellik na die begin van die kontrolepunt skoon is) , as ons dan die volgende kontrolepunt nader, begin die delta-rekordfraksie groei en weer aan die begin van die volgende kontrolepunt herstel. Metings in sommige sintetiese toetse het getoon dat die aandeel van bladsyfoto's in die totale volume fisiese rekords 90% bereik.

Die idee van WAL-bladsy-snapshot-kompressie is om bladsy-snapshots saam te pers met behulp van 'n klaargemaakte bladsy-kompressie-instrument (sien skyfbladsy-kompressie). Terselfdertyd, in WAL, word rekords opeenvolgend in byvoeg-alleen-modus gestoor en dit is nie nodig om rekords aan die grense van lêerstelselblokke te bind nie, so hier, anders as die skyfbladsy-kompressiemeganisme, het ons nie yl lêers nodig by almal; dienooreenkomstig sal hierdie meganisme nie net op die OS Linux werk nie. Boonop maak dit nie meer vir ons saak hoeveel ons die bladsy kon saamdruk nie. Selfs as ons 1 greep vrygemaak het, is dit reeds 'n positiewe resultaat en ons kan saamgeperste data in WAL stoor, anders as skyfbladsy-kompressie, waar ons die saamgeperste bladsy slegs stoor as ons meer as 1 lêerstelselblok vrygestel het.

Bladsye is hoogs saampersbare data, hul aandeel in die totale WAL-volume is baie hoog, so sonder om die WAL-lêerformaat te verander, kan ons 'n aansienlike vermindering in die grootte daarvan kry. Kompressie, insluitend logiese rekords, sal 'n verandering in formaat en verlies aan verenigbaarheid vereis, byvoorbeeld vir eksterne verbruikers wat dalk belangstel in logiese rekords, maar sal nie lei tot 'n beduidende vermindering in lêergrootte nie.

Soos met skyfbladsy-kompressie, kan WAL-bladsy-snapshot-kompressie ZSTD, LZ4, Snappy-kompressie-algoritmes gebruik, sowel as die SKIP_GARBAGE-modus.

Prestasie-impak

Dit is nie moeilik om op te let dat die direkte aktivering van WAL-bladsy-snapshot-kompressie slegs drade beïnvloed wat data na bladsygeheue skryf, dit wil sê daardie drade wat data in kas verander. Die lees van fisiese rekords vanaf WAL vind slegs een keer plaas, op die oomblik dat die nodus na 'n val opgelig word (en slegs as dit tydens 'n kontrolepunt val).

Dit beïnvloed drade wat data verander op die volgende manier: ons kry 'n negatiewe effek (CPU) as gevolg van die behoefte om die bladsy elke keer saam te komprimeer voordat dit na skyf geskryf word, en 'n positiewe effek (skyf IO) as gevolg van 'n vermindering in die hoeveelheid van data geskryf. Gevolglik is alles eenvoudig hier: as die stelselprestasie deur die SVE beperk word, kry ons 'n effense agteruitgang, as dit beperk word deur skyf-I/O, kry ons 'n toename.

Indirek beïnvloed die vermindering van die WAL-grootte ook (positief) strome wat WAL-segmente in die argief en WAL-verdigtingstrome stort.

Werklike prestasietoetse in ons omgewing met gebruik van sintetiese data het 'n effense toename getoon (deurset het met 10%-15% toegeneem, latensie het met 10%-15% afgeneem).

Hoe om te aktiveer en op te stel

Minimum Apache Ignite weergawe: 2.8. Aktiveer en konfigureer soos volg:

  • Daar moet 'n ontsteek-kompressie-module in die klas-pad wees. By verstek is dit in die Apache Ignite-verspreiding in die libs/opsionele gids geleë en is dit nie by die klaspad ingesluit nie. Jy kan eenvoudig die gids een vlak opskuif na libs en dan wanneer jy dit deur ignite.sh hardloop, sal dit outomaties geaktiveer word.
  • Volharding moet geaktiveer word (Aktiveer via DataRegionConfiguration.setPersistenceEnabled(true)).
  • Die kompressiemodus moet met die metode ingestel word DataStorageConfiguration.setWalPageCompression(), kompressie is by verstek gedeaktiveer (GEDEAKTIVEERDE modus).
  • Opsioneel kan u die kompressievlak met behulp van die metode instel DataStorageConfiguration.setWalPageCompression(), sien die javadoc vir die metode vir geldige waardes vir elke modus.

Gevolgtrekking

Die oorweegde datakompressiemeganismes in Apache Ignite kan onafhanklik van mekaar gebruik word, maar enige kombinasie daarvan is ook aanvaarbaar. Om te verstaan ​​hoe hulle werk, sal jou toelaat om te bepaal hoe geskik hulle is vir jou take in jou omgewing en wat jy sal moet opoffer wanneer jy dit gebruik. Skyfbladsy-kompressie is ontwerp om die hoofberging saam te pers en kan 'n medium kompressieverhouding gee. WAL-bladsy-kiekie-kompressie sal 'n gemiddelde mate van kompressie vir WAL-lêers gee, en sal heel waarskynlik selfs werkverrigting verbeter. WAL-kompaksie sal nie 'n positiewe uitwerking op werkverrigting hê nie, maar sal die grootte van WAL-lêers so veel as moontlik verminder deur fisiese rekords te verwyder.

Bron: will.com

Voeg 'n opmerking