Datuen konpresioa Apache Ignite-n. Sber-en esperientzia

Datuen konpresioa Apache Ignite-n. Sber-en esperientziaDatu bolumen handiekin lan egitean, batzuetan diskoko espazio faltaren arazoa sor daiteke. Arazo hau konpontzeko modu bat konpresioa da, eta horri esker, ekipo berean, biltegiratze-bolumenak handitu ditzakezu. Artikulu honetan, datu-konpresioak Apache Ignite-n nola funtzionatzen duen aztertuko dugu. Artikulu honek produktuan inplementatutako disko-konpresioaren metodoak soilik deskribatuko ditu. Datuak konprimitzeko beste metodo batzuk (sarean, memorian), inplementatu edo ez, esparrutik kanpo geratuko dira.

Beraz, iraunkortasun modua gaituta, cacheetako datuen aldaketen ondorioz, Ignite diskoan idazten hasten da:

  1. Cacheen edukia
  2. Write Ahead Log (aurrerantzean WAL besterik gabe)

Aspalditik badago WAL konpresioaren mekanismo bat, WAL trinkotze izenekoa. Duela gutxi kaleratu den Apache Ignite 2.8-k beste bi mekanismo sartu zituen diskoan datuak konprimitzea ahalbidetzen dutenak: diskoko orrialdeen konpresioa cacheen edukia konprimitzeko eta WAL orrialdearen argazkien konpresioa WAL sarrera batzuk konprimitzeko. Hiru mekanismo hauei buruzko xehetasun gehiago jarraian.

Disko orriaren konpresioa

Nola egiten du lan

Lehenik eta behin, ikus dezagun Ignite-k datuak nola gordetzen dituen. Orrialdearen memoria biltegiratzeko erabiltzen da. Orrialdearen tamaina nodoaren hasieran ezartzen da eta ezin da aldatu ondorengo faseetan; gainera, orriaren tamaina biko potentzia eta fitxategi-sistema blokearen tamainaren multiploa izan behar du. Orrialdeak RAM memorian kargatzen dira diskotik behar den moduan; diskoko datuen tamainak esleitutako RAM kopurua gainditu dezake. RAM-n orri bat diskotik kargatzeko behar adina leku ez badago, jada erabiltzen ez diren orrialde zaharrak RAMtik kanporatuko dira.

Datuak diskoan gordetzen dira forma honetan: fitxategi bereizi bat sortzen da cache-talde bakoitzaren partizio bakoitzeko; fitxategi honetan, orriak bata bestearen atzetik agertzen dira indizearen ordena goranzkoan. Orrialde osoko identifikatzaileak cache-taldearen identifikatzailea, partizioaren zenbakia eta orri-indizea ditu fitxategian. Horrela, orrialde osoko identifikatzailea erabiliz, fitxategia eta fitxategiko desplazamendua modu esklusiboan zehaztu ditzakegu orrialde bakoitzeko. Orrialdeen memoriari buruz gehiago irakur dezakezu Apache Ignite Wiki artikuluan: Ignite Persistent Store - kanpaiaren azpian.

Disko-orriak konpresio-mekanismoak, izenetik asma dezakezun bezala, orrialde mailan funtzionatzen du. Mekanismo hau gaituta dagoenean, RAM-eko datuak dauden bezala prozesatzen dira, inolako konpresiorik gabe, baina orriak RAMetik diskora gordetzen direnean, konprimitu egiten dira.

Baina orrialde bakoitza banan-banan konprimitzea ez da arazoari irtenbidea; nolabait, ondoriozko datu-fitxategien tamaina murriztu behar duzu. Orrialdearen tamaina finkoa ez bada, ezingo ditugu orririk idatzi fitxategian bata bestearen atzetik, honek hainbat arazo sor ditzake eta:

  • Orriaren indizea erabiliz, ezin izango dugu kalkulatu fitxategian kokatuta dagoen desplazamendua.
  • Ez dago argi fitxategiaren amaieran ez dauden eta haien tamaina aldatzen duten orriekin zer egin. Orriaren tamaina txikitzen bada, askatu zuen espazioa desagertu egingo da. Orriaren tamaina handitzen bada, leku berri bat bilatu behar duzu fitxategian.
  • Orrialde bat fitxategi-sistemaren blokearen tamainaren multiploa ez den byte-kopurua mugitzen bada, fitxategi-sistemaren bloke bat gehiago ukitu beharko da irakurtzeko edo idazteko, eta horrek errendimendua hondatu dezake.

Arazo hauek bere mailan konpontzea saihesteko, Apache Ignite-n disko-orrien konpresioak fitxategi urriak izeneko fitxategi-sistemaren mekanismoa erabiltzen du. Fitxategi urri bat zeroz betetako eskualde batzuk "zulo" gisa markatu daitezkeen bat da. Kasu honetan, ez da fitxategi-sistemaren blokerik esleituko zulo horiek gordetzeko, eta ondorioz, diskoko espazioan aurreztuko da.

Logikoa da fitxategi-sistema bloke bat askatzeko, zuloaren tamaina fitxategi-sistema blokearena baino handiagoa edo berdina izan behar dela, eta horrek orriaren tamainari eta Apache Ignite-ri muga gehigarri bat ezartzen dio: konpresioak eraginik izan dezan. orriaren tamainak fitxategi sistema blokearen tamaina baino zorrozki handiagoa izan behar du . Orrialdearen tamaina blokearen tamainaren berdina bada, orduan ezingo dugu inoiz bloke bakar bat askatu, bloke bakar bat askatzeko, orrialde konprimituak 0 byte okupatu behar baititu. Orrialdearen tamaina 2 edo 4 blokeren tamainaren berdina bada, dagoeneko bloke bat gutxienez askatu ahal izango dugu gure orria gutxienez %50 edo %75era konprimituta badago, hurrenez hurren.

Horrela, mekanismoaren funtzionamenduaren azken deskribapena: Orri bat diskoan idaztean, orria konprimitzen saiakera egiten da. Konprimitutako orriaren tamainak fitxategi-sistemako bloke bat edo gehiago askatzea ahalbidetzen badu, orria konprimituta idatziko da, eta askatutako blokeen ordez "zulo" bat egiten da (sistema-deia egiten da. fallocate() zulatu zuloko banderarekin). Konprimitutako orriaren tamainak blokeak askatzen uzten ez badu, orria bere horretan gordeko da, konprimitu gabe. Orrialdeen desplazamendu guztiak konpresiorik gabeko modu berean kalkulatzen dira, orriaren indizea orriaren tamainaz biderkatuz. Ez da orriak lekuz aldatu behar zure kabuz. Orrialdeen desplazamenduak, konpresiorik gabe bezala, fitxategi-sistemaren blokeen mugetan erortzen dira.

Datuen konpresioa Apache Ignite-n. Sber-en esperientzia

Oraingo inplementazioan, Ignite-k Linux sistema eragilearen pean fitxategi urriekin bakarrik funtziona dezake; horren arabera, disko-orrien konpresioa sistema eragile honetan Ignite erabiltzen denean soilik gaitu daiteke.

Disko-orrien konpresioa egiteko erabil daitezkeen konpresio-algoritmoak: ZSTD, LZ4, Snappy. Horrez gain, funtzionamendu-modu bat dago (SKIP_GARBAGE), zeinean orrialdean erabiltzen ez den espazioa bakarrik botatzen den gainerako datuei konpresio aplikatu gabe, eta horrek CPUaren karga murrizten du lehen zerrendatutako algoritmoekin alderatuta.

Errendimendu-eragina

Zoritxarrez, ez dut benetako errendimenduaren neurketarik egin benetako standetan, ez baitugu mekanismo hori ekoizpenean erabiltzeko asmorik, baina teorikoki non galduko dugun eta non irabaziko dugun espekulatu dezakegu.

Horretarako, atzitzean orrialdeak nola irakurtzen eta idazten diren gogoratu behar dugu:

  • Irakurketa eragiketa bat egitean, lehenik RAM-n bilatzen da; bilaketak arrakastarik ez badu, orria diskotik RAM-era kargatzen da irakurketa egiten duen hari beraren bidez.
  • Idazketa-eragiketa bat egiten denean, RAM-eko orria zikin gisa markatzen da, baina orria ez da fisikoki diskoan berehala gordetzen idazketa egiten duen hariak. Orri zikin guztiak diskoan gordetzen dira geroago kontrol-puntuaren prozesuan hari bereizietan.

Beraz, irakurketa eragiketetan eragina hau da:

  • Positiboa (disko IO), irakurritako fitxategi-sistemaren blokeen kopuruaren murrizketa dela eta.
  • Negatiboa (CPU), sistema eragileak fitxategi urriekin lan egiteko eskatzen duen karga gehigarriaren ondorioz. Baliteke ere IO eragiketa gehigarriak hemen inplizituki agertzea fitxategi-egitura urri konplexuagoa gordetzeko (zoritxarrez, ez ditut ezagutzen fitxategi gutxien funtzionatzen duten xehetasun guztiak).
  • Negatiboa (CPU), orriak deskonprimitu beharragatik.
  • Ez dago eraginik idazketa eragiketetan.
  • Kontrol-puntuaren prozesuan eragina (hemen dena irakurketa eragiketen antzekoa da):
  • Positiboa (disko IO), idatzitako fitxategi-sistemaren blokeen kopurua gutxitu delako.
  • Negatiboa (CPU, agian diskoaren IO), fitxategi gutxiekin lan egiteagatik.
  • Negatiboa (CPU), orriaren konpresioaren beharragatik.

Balantzaren zein aldetan okertuko da balantza? Hau guztia oso ingurunearen araberakoa da, baina diskoko orrialdeen konpresioak sistema gehienetan errendimendua hondatzea ekarriko duela uste dut. Gainera, fitxategi urriekin antzeko ikuspegia erabiltzen duten beste DBMS batzuetan egindako probek errendimenduaren jaitsiera erakusten dute konpresioa gaituta dagoenean.

Nola gaitu eta konfiguratu

Goian esan bezala, disko-orrien konpresioa onartzen duen Apache Ignite-ren gutxieneko bertsioa 2.8 da eta Linux sistema eragilea bakarrik onartzen da. Gaitu eta konfiguratu honela:

  • Klase-bidean ignite-konpresio modulu bat egon behar da. Lehenespenez, Apache Ignite banaketan dago libs/aukerako direktorioa eta ez dago klase-bidean sartzen. Direktorioa maila bat igo dezakezu libsetara eta gero ignite.sh bidez exekutatzen duzunean automatikoki gaituko da.
  • Iraunkortasuna gaituta egon behar da (Gaitu bidez DataRegionConfiguration.setPersistenceEnabled(true)).
  • Orrialdearen tamaina fitxategi-sistema blokearen tamaina baino handiagoa izan behar da (erabiliz ezar dezakezu DataStorageConfiguration.setPageSize() ).
  • Datuak konprimitu behar dituen cache bakoitzeko, konpresio-metodoa eta (aukeran) konpresio-maila (metodoak) konfiguratu behar dituzu. CacheConfiguration.setDiskPageCompression() , CacheConfiguration.setDiskPageCompressionLevel()).

WAL trinkotzea

Nola egiten du lan

Zer da WAL eta zergatik behar da? Oso labur: orrialdearen biltegiratzea aldatzen duten gertaera guztiak biltzen dituen erregistroa da. Batez ere, erorketa gertatuz gero berreskuratu ahal izateko behar da. Eragiketa orok, erabiltzaileari kontrola eman baino lehen, WALen gertaera bat erregistratu behar du lehenik, hutsegiterik gertatuz gero, erregistroan erreproduzitu ahal izateko eta erabiltzaileak erantzun arrakastatsua jaso duen eragiketa guztiak berreskuratu ahal izateko, nahiz eta eragiketa horiek. ez zuen denborarik izan diskoan orrien biltegian islatzeko (dagoeneko goian Deskribatu da orrialdeen biltegian benetako idazketa "checkpointing" izeneko prozesu batean egiten dela zenbait hariren bidez atzerapenarekin).

WAL-en sarrerak logiko eta fisikoetan banatzen dira. Boolearrak gakoak eta balioak dira. Fisikoa - orrialdeen dendako orrialdeetan egindako aldaketak islatzen ditu. Erregistro logikoak beste kasu batzuetan erabilgarriak izan daitezkeen arren, erregistro fisikoak hutsegite bat gertatuz gero berreskuratzeko soilik behar dira eta azken kontrol-puntu arrakastatsutik soilik behar dira erregistroak. Hemen ez dugu zehatz-mehatz sartuko eta zergatik funtzionatzen duen horrela azalduko, baina interesa dutenek Apache Ignite Wiki-n lehen aipatutako artikulua jo dezakete: Ignite Persistent Store - kanpaiaren azpian.

Erregistro logiko bakoitzeko hainbat erregistro fisiko egon ohi dira. Hau da, adibidez, cachean jarritako eragiketa batek orrialdeen memoriako hainbat orrialderi eragiten die (datuak dituen orri batek, indizeak dituzten orrialdeak, zerrenda libreak dituzten orrialdeak). Proba sintetiko batzuetan, erregistro fisikoak WAL fitxategiaren % 90 okupatzen zuela ikusi nuen. Hala ere, oso denbora laburrerako behar dira (lehenespenez, kontrolguneen arteko tartea 3 minutukoa da). Logikoa izango litzateke datu hauek garrantzia galdu ondoren kentzea. Hau da, hain zuzen, WAL trinkotze mekanismoak egiten duena: erregistro fisikoak kentzen ditu eta gainerako erregistro logikoak konprimitzen ditu zip erabiliz, fitxategiaren tamaina oso nabarmen murrizten den bitartean (batzuetan hamarnaka aldiz).

Fisikoki, WALek tamaina finkoko hainbat segmentu ditu (10 lehenespenez) (64 MB lehenespenez), modu zirkularrean gainidazten direnak. Uneko segmentua bete bezain laster, hurrengo segmentua uneko gisa esleitzen da, eta betetako segmentua artxiboan kopiatzen da aparteko hari baten bidez. WAL trinkotzeak artxibo-segmentuekin funtzionatzen du jada. Gainera, aparteko hari gisa, kontrol-puntuaren exekuzioa kontrolatzen du eta erregistro fisikoak behar ez diren artxibo-segmentuetan konpresioa hasten du.

Datuen konpresioa Apache Ignite-n. Sber-en esperientzia

Errendimendu-eragina

WAL trinkotzea hari bereizi gisa exekutatzen denez, ez luke eragin zuzenik izan behar egiten ari diren eragiketetan. Baina oraindik atzeko planoko karga gehigarria jartzen du CPUan (konpresioa) eta diskoan (artxibotik WAL segmentu bakoitza irakurriz eta segmentu konprimituak idatziz), beraz, sistema gehienezko ahalmenean exekutatzen ari bada, errendimenduaren degradazioa ere ekarriko du.

Nola gaitu eta konfiguratu

WAL trinkotzea gaitu dezakezu propietatea erabiliz WalCompactionEnabled Π² DataStorageConfiguration (DataStorageConfiguration.setWalCompactionEnabled(true)). Gainera, DataStorageConfiguration.setWalCompactionLevel() metodoa erabiliz, konpresio maila ezar dezakezu balio lehenetsiarekin (BEST_SPEED) ase ez bazaude.

WAL orrialdearen argazkien konpresioa

Nola egiten du lan

Dagoeneko jakin dugu WALen erregistroak logiko eta fisikoetan banatzen direla. Orrialde bakoitzeko aldaketa bakoitzeko, WAL erregistro fisiko bat sortzen da orriaren memorian. Erregistro fisikoak, aldi berean, 2 azpimotatan banatzen dira: orrialdearen argazki-erregistroa eta delta-erregistroa. Orrialde batean zerbait aldatu eta egoera garbi batetik egoera zikin batera pasatzen dugun bakoitzean, orri honen kopia osoa WAL-en gordetzen da (orriaren argazki-erregistroa). WALen byte bakarra aldatu badugu ere, erregistroa orrialdearen tamaina baino zertxobait handiagoa izango da. Dagoeneko zikin dagoen orri batean zerbait aldatzen badugu, delta erregistro bat eratzen da WAL-en, eta horrek orriaren aurreko egoerarekin alderatuta aldaketak bakarrik islatzen ditu, baina ez orri osoa. Orrialdeen egoera zikinetik garbira berrezartzea kontrol-puntuaren prozesuan zehar egiten denez, kontrol-puntua hasi eta berehala, ia erregistro fisiko guztiak orrialdeen argazki-fotoz baino ez dira osatuko (kontrol-puntua hasi eta berehala orrialde guztiak garbiak baitira). , gero hurrengo kontrol-puntura hurbiltzen garen heinean, delta-erregistroaren frakzioa hazten eta berrezartzen hasten da hurrengo kontrol-puntuaren hasieran. Proba sintetiko batzuetan egindako neurketek erakutsi zuten orrialdeen argazkien kuota erregistro fisikoen bolumen osoko zatia % 90era iristen dela.

WAL orrien argazkien konpresioaren ideia orrien argazkiak konprimatzea da, prest egindako orrien konpresioaren tresna erabiliz (ikus diskoko orrialdeen konpresioa). Aldi berean, WAL-en, erregistroak sekuentzialki gordetzen dira eranskin-moduan soilik eta ez dago erregistroak fitxategi-sistema blokeen mugetara lotu beharrik, beraz, hemen, disko-orrialdearen konpresio-mekanismoa ez bezala, ez dugu fitxategi urriak behar. guztia; horrenbestez, mekanismo honek funtzionatuko du OS Linux-en ez ezik. Gainera, jada ez zaigu inporta orria zenbat konprimitu ahal izan genuen. Byte 1 askatu bagenuen ere, emaitza positiboa da dagoeneko eta konprimitutako datuak WALen gorde ditzakegu, diskoko orriaren konpresioa ez bezala, non fitxategi-sistema bloke 1 baino gehiago askatzen badugu soilik gordetzen dugun orrialdea konprimituta.

Orrialdeak oso datu konprimigarriak dira, WAL bolumen osoaren parte-hartzea oso handia da, beraz, WAL fitxategi formatua aldatu gabe bere tamainaren murrizketa nabarmena lor dezakegu. Konpresioak, erregistro logikoak barne, formatuan aldaketa eta bateragarritasuna galtzea eskatuko luke, adibidez, erregistro logikoetan interesa izan dezaketen kanpoko kontsumitzaileentzat, baina ez luke fitxategien tamaina nabarmen murriztea ekarriko.

Disko orriaren konpresioarekin gertatzen den bezala, WAL orrialdearen argazki-konpresioak ZSTD, LZ4, Snappy konpresio algoritmoak erabil ditzake, baita SKIP_GARBAGE modua ere.

Errendimendu-eragina

Ez da zaila ohartzea zuzenean WAL orrien argazkien konpresioa gaitzeak orriaren memorian datuak idazten dituzten haiei soilik eragiten diela, hau da, cacheetako datuak aldatzen dituzten hari horiei. WAL-en erregistro fisikoak irakurtzea behin bakarrik gertatzen da, nodoa erorketa baten ondoren altxatzen den unean (eta kontrol-puntu batean erortzen bada bakarrik).

Honek datuak aldatzen dituzten harietan eragiten du honako modu honetan: efektu negatiboa (CPU) lortzen dugu diskoan idatzi aurretik orrialdea konprimitu beharragatik, eta efektu positiboa (disko IO) kopurua murrizteagatik. idatzitako datuak. Horren arabera, dena erraza da hemen: sistemaren errendimendua CPUak mugatzen badu, degradazio apur bat lortzen dugu, diskoko I/O-k mugatzen badu, igoera lortuko dugu.

Zeharka, WAL tamaina murrizteak WAL segmentuak artxiboan eta WAL trinkotze korronteetan isurtzen dituzten korronteei ere eragiten die (positiboki).

Datu sintetikoak erabiliz gure inguruneko errendimendu errealen probek gorakada txikia izan dute (erdibidearen % 10-15 handitu da, latentzia % 10-15 jaitsi).

Nola gaitu eta konfiguratu

Gutxieneko Apache Ignite bertsioa: 2.8. Gaitu eta konfiguratu honela:

  • Klase-bidean ignite-konpresio modulu bat egon behar da. Lehenespenez, Apache Ignite banaketan dago libs/aukerako direktorioa eta ez dago klase-bidean sartzen. Direktorioa maila bat igo dezakezu libsetara eta gero ignite.sh bidez exekutatzen duzunean automatikoki gaituko da.
  • Iraunkortasuna gaituta egon behar da (Gaitu bidez DataRegionConfiguration.setPersistenceEnabled(true)).
  • Konpresio modua metodoa erabiliz ezarri behar da DataStorageConfiguration.setWalPageCompression(), konpresioa desgaituta dago lehenespenez (DESACTIVATUA modua).
  • Aukeran, konpresio-maila ezar dezakezu metodoa erabiliz DataStorageConfiguration.setWalPageCompression(), ikusi javadoc metodoa modu bakoitzerako baliozko balioetarako.

Ondorioa

Apache Ignite-n kontuan hartutako datuak konprimitzeko mekanismoak elkarrengandik independentean erabil daitezke, baina horien edozein konbinazio ere onargarria da. Nola funtzionatzen duten ulertzeak zure inguruneko zereginetarako zein egokiak diren eta horiek erabiltzean zer sakrifikatu beharko duzun zehazteko aukera emango dizu. Disko orriaren konpresioa biltegiratze nagusia konprimitzeko diseinatuta dago eta konpresio-erlazio ertaina eman dezake. WAL orriaren argazkien konpresioak WAL fitxategien batez besteko konpresio-maila emango du, eta ziurrenik errendimendua hobetuko du. WAL trinkotzeak ez du eragin positiborik izango errendimenduan, baina WAL fitxategien tamaina ahalik eta gehien murriztuko du erregistro fisikoak kenduz.

Iturria: www.habr.com

Gehitu iruzkin berria