Tietojen pakkaus Apache Ignitessa. Sberin kokemus

Tietojen pakkaus Apache Ignitessa. Sberin kokemusKun työskentelet suuria tietomääriä, levytilan puute voi joskus syntyä. Yksi tapa ratkaista tämä ongelma on pakkaus, jonka ansiosta sinulla on varaa lisätä tallennustilaa samoilla laitteilla. Tässä artikkelissa tarkastellaan, kuinka tietojen pakkaus toimii Apache Ignitessa. Tässä artikkelissa kuvataan vain tuotteessa toteutetut levynpakkausmenetelmät. Muut tiedon pakkausmenetelmät (verkon yli, muistiin), riippumatta siitä, onko ne toteutettu tai eivät, jäävät soveltamisalan ulkopuolelle.

Joten, kun pysyvyystila on käytössä, Ignite alkaa kirjoittaa levylle välimuistien tietojen muutosten seurauksena:

  1. Välimuistien sisältö
  2. Kirjoita eteenpäin loki (tästä eteenpäin vain WAL)

WAL-pakkausmekanismi on ollut olemassa jo jonkin aikaa, nimeltään WAL-tiivistys. Äskettäin julkaistu Apache Ignite 2.8 esitteli kaksi muuta mekanismia, joiden avulla voit pakata tietoja levyllä: levysivun pakkaus välimuistien sisällön pakkaamiseen ja WAL-sivun tilannevedospakkaus joidenkin WAL-merkintöjen pakkaamiseen. Lisätietoja kaikista näistä kolmesta mekanismista alla.

Levysivun pakkaus

Kuinka tämä toimii

Katsotaanpa ensin hyvin lyhyesti, kuinka Ignite tallentaa tietoja. Sivumuistia käytetään tallennukseen. Sivun koko asetetaan solmun alussa, eikä sitä voi muuttaa myöhemmissä vaiheissa; myös sivun koon on oltava potenssilla kaksi ja tiedostojärjestelmän lohkokoon kerrannainen. Sivut ladataan RAM-muistiin levyltä tarpeen mukaan; levyllä olevien tietojen koko voi ylittää varatun RAM-muistin määrän. Jos RAM-muistissa ei ole tarpeeksi tilaa sivun lataamiseen levyltä, vanhat, enää käyttämättömät sivut poistetaan RAM-muistista.

Tiedot tallennetaan levylle seuraavassa muodossa: jokaiselle välimuistiryhmän osiolle luodaan oma tiedosto, jossa sivut näkyvät peräkkäin nousevassa hakemistojärjestyksessä. Koko sivun tunniste sisältää välimuistiryhmän tunnisteen, osion numeron ja tiedoston sivuhakemiston. Siten käyttämällä koko sivun tunnistetta voimme yksilöllisesti määrittää tiedoston ja tiedostossa olevan offsetin jokaiselle sivulle. Voit lukea lisää hakumuistista Apache Ignite Wiki -artikkelista: Ignite Persistent Store - konepellin alla.

Levysivun pakkausmekanismi, kuten nimestä voi arvata, toimii sivutasolla. Kun tämä mekanismi on käytössä, RAM-muistissa olevat tiedot käsitellään sellaisenaan ilman pakkausta, mutta kun sivut tallennetaan RAM-muistista levylle, ne pakataan.

Mutta jokaisen sivun pakkaaminen yksitellen ei ole ratkaisu ongelmaan; sinun on jotenkin pienennettävä tuloksena olevien tiedostojen kokoa. Jos sivun koko ei ole enää kiinteä, emme voi enää kirjoittaa sivuja tiedostoon peräkkäin, koska tämä voi aiheuttaa useita ongelmia:

  • Sivuhakemiston avulla emme voi laskea siirtymää, jolla se sijaitsee tiedostossa.
  • Ei ole selvää, mitä tehdä sivuille, jotka eivät ole tiedoston lopussa ja jotka muuttavat kokoaan. Jos sivun koko pienenee, sen vapauttama tila katoaa. Jos sivun koko kasvaa, sinun on etsittävä sille uusi paikka tiedostosta.
  • Jos sivu liikkuu tavumäärällä, joka ei ole tiedostojärjestelmän lohkokoon kerrannainen, sen lukeminen tai kirjoittaminen edellyttää vielä yhden tiedostojärjestelmän lohkon koskettamista, mikä voi johtaa suorituskyvyn heikkenemiseen.

Välttääkseen näiden ongelmien ratkaisemisen omalla tasollaan Apache Igniten levysivupakkaus käyttää tiedostojärjestelmämekanismia nimeltä harvat tiedostot. Harva tiedosto on tiedosto, jossa jotkin nollalla täytetyt alueet voidaan merkitä "reikiksi". Tässä tapauksessa tiedostojärjestelmälohkoja ei varata näiden reikien tallentamiseen, mikä säästää levytilaa.

On loogista, että tiedostojärjestelmälohkon vapauttamiseksi reiän koon on oltava suurempi tai yhtä suuri kuin tiedostojärjestelmälohko, mikä asettaa lisärajoituksen sivun kokoon ja Apache Ignite -ohjelmaan: jotta pakkauksella olisi vaikutusta, sivun koon on oltava ehdottomasti suurempi kuin tiedostojärjestelmälohkon koko. Jos sivun koko on yhtä suuri kuin lohkon koko, emme voi koskaan vapauttaa yhtä lohkoa, koska yhden lohkon vapauttamiseksi pakatun sivun on varattava 0 tavua. Jos sivun koko on yhtä suuri kuin 2 tai 4 lohkoa, voimme jo vapauttaa ainakin yhden lohkon, jos sivumme on pakattu vähintään 50 %:iin tai 75 %:iin.

Näin ollen lopullinen kuvaus mekanismin toiminnasta: Kun kirjoitetaan sivua levylle, sivu yritetään pakata. Jos pakatun sivun koko sallii yhden tai useamman tiedostojärjestelmälohkon vapauttamisen, sivu kirjoitetaan pakatussa muodossa ja vapautettujen lohkojen tilalle tehdään ”reikä” (järjestelmäkutsu suoritetaan fallocate() reiän lipun kanssa). Jos pakatun sivun koko ei salli lohkojen vapauttamista, sivu tallennetaan sellaisenaan, pakkaamattomana. Kaikki sivusiirrot lasketaan samalla tavalla kuin ilman pakkausta, kertomalla sivuindeksi sivukoolla. Sivuja ei tarvitse siirtää itse. Sivusiirrot, aivan kuten ilman pakkausta, putoavat tiedostojärjestelmälohkojen rajoihin.

Tietojen pakkaus Apache Ignitessa. Sberin kokemus

Nykyisessä toteutuksessa Ignite voi toimia vain harvoilla tiedostoilla Linux-käyttöjärjestelmässä; vastaavasti levysivun pakkaus voidaan ottaa käyttöön vain, kun Ignitea käytetään tässä käyttöjärjestelmässä.

Pakkausalgoritmit, joita voidaan käyttää levysivujen pakkaamiseen: ZSTD, LZ4, Snappy. Lisäksi on olemassa toimintatila (SKIP_GARBAGE), jossa vain sivun käyttämätön tila heitetään ulos ilman pakkausta jäljellä oleville tiedoille, mikä vähentää suorittimen kuormitusta verrattuna aiemmin lueteltuihin algoritmeihin.

Suorituskykyvaikutus

Valitettavasti en tehnyt varsinaisia ​​suoritusmittauksia oikeilla osastoilla, koska emme aio käyttää tuota mekanismia tuotannossa, mutta voimme teoriassa spekuloida missä häviämme ja missä voitamme.

Tätä varten meidän on muistettava, kuinka sivuja luetaan ja kirjoitetaan, kun niitä avataan:

  • Lukutoimintoa suoritettaessa se etsitään ensin RAM-muistista; jos haku epäonnistuu, sivu ladataan RAM-muistiin levyltä saman säikeen kautta, joka suorittaa lukemisen.
  • Kun kirjoitus suoritetaan, RAM-muistissa oleva sivu merkitään likaiseksi, mutta kirjoituksen suorittava säie ei tallenna sivua fyysisesti heti levylle. Kaikki likaiset sivut tallennetaan levylle myöhemmin tarkistuspisteprosessin aikana erillisinä säikeinä.

Joten vaikutus lukutoimintoihin on:

  • Positiivinen (levy IO), koska luettujen tiedostojärjestelmälohkojen määrä on vähentynyt.
  • Negatiivinen (CPU), koska käyttöjärjestelmä vaatii ylimääräistä kuormitusta toimiakseen harvassa tiedostossa. On myös mahdollista, että tässä implisiittisesti ilmestyy ylimääräisiä IO-toimintoja monimutkaisemman harvaan tiedostorakenteen tallentamiseksi (valitettavasti en ole perehtynyt kaikkiin harvalukuisten tiedostojen toiminnan yksityiskohtiin).
  • Negatiivinen (CPU), koska sivut on purettava.
  • Ei vaikutusta kirjoitustoimintoihin.
  • Vaikutus tarkistuspisteprosessiin (kaikki tässä on samanlaista kuin lukutoiminnot):
  • Positiivinen (levy IO), koska kirjoitettujen tiedostojärjestelmälohkojen määrä on vähentynyt.
  • Negatiivinen (CPU, mahdollisesti levyn IO), johtuen harvoista tiedostoista.
  • Negatiivinen (CPU), koska sivun pakkaus on tarpeen.

Kumpi puoli vaa'alla kallistaa vaa'an? Tämä kaikki riippuu hyvin paljon ympäristöstä, mutta olen taipuvainen uskomaan, että levysivun pakkaus johtaa todennäköisesti suorituskyvyn heikkenemiseen useimmissa järjestelmissä. Lisäksi testit muilla DBMS-järjestelmillä, jotka käyttävät samanlaista lähestymistapaa harvassa tiedostossa, osoittavat suorituskyvyn heikkenemistä, kun pakkaus on käytössä.

Kuinka ottaa käyttöön ja määrittää

Kuten edellä mainittiin, Apache Igniten vähimmäisversio, joka tukee levysivun pakkausta, on 2.8 ja vain Linux-käyttöjärjestelmää tuetaan. Ota käyttöön ja määritä seuraavasti:

  • Luokkapolussa on oltava sytytyspakkausmoduuli. Oletusarvoisesti se sijaitsee Apache Ignite -jakelussa libs/optional-hakemistossa, eikä se sisälly luokkapolkuun. Voit yksinkertaisesti siirtää hakemiston yhden tason ylöspäin libsiin ja sitten kun suoritat sen ignite.sh-tiedoston kautta, se otetaan automaattisesti käyttöön.
  • Pysyvyys on otettava käyttöön (Käytössä kautta DataRegionConfiguration.setPersistenceEnabled(true)).
  • Sivun koon on oltava suurempi kuin tiedostojärjestelmän lohkokoko (voit asettaa sen käyttämällä DataStorageConfiguration.setPageSize() ).
  • Jokaiselle välimuistille, jonka tiedot on pakattava, sinun on määritettävä pakkausmenetelmä ja (valinnaisesti) pakkaustaso (menetelmät CacheConfiguration.setDiskPageCompression() , CacheConfiguration.setDiskPageCompressionLevel()).

WAL-tiivistys

Kuinka tämä toimii

Mikä on WAL ja miksi sitä tarvitaan? Hyvin lyhyesti: tämä on loki, joka sisältää kaikki tapahtumat, jotka lopulta muuttavat sivun tallennustilaa. Sitä tarvitaan ensisijaisesti pystyäkseen toipumaan kaatumisen sattuessa. Kaikki toiminnot, ennen kuin annat ohjauksen käyttäjälle, on ensin tallennettava tapahtuma WAL:iin, jotta epäonnistumisen sattuessa se voidaan toistaa lokiin ja palauttaa kaikki toiminnot, joihin käyttäjä on saanut onnistuneen vastauksen, vaikka nämä toiminnot ei ehtinyt näkyä sivun levytallennustilassa (jo edellä On kuvattu, että varsinainen kirjoittaminen sivusäilöön tapahtuu "checkpointing"-nimisessä prosessissa jossain viiveellä erillisillä säikeillä).

WAL-merkinnät on jaettu loogisiin ja fyysisiin. Boolen arvot ovat itse avaimia ja arvoja. Fyysinen - heijastaa muutoksia sivukaupan sivuille. Vaikka loogiset tietueet voivat olla hyödyllisiä joissakin muissa tapauksissa, fyysisiä tietueita tarvitaan vain palautumiseen kaatuessa ja tietueita tarvitaan vasta viimeisen onnistuneen tarkistuspisteen jälkeen. Tässä emme mene yksityiskohtiin ja selitä miksi se toimii tällä tavalla, mutta kiinnostuneet voivat viitata jo mainittuun Apache Ignite Wikin artikkeliin: Ignite Persistent Store - konepellin alla.

Yhtä loogista tietuetta kohden on usein useita fyysisiä tietueita. Eli esimerkiksi yksi välimuistiin laittaminen vaikuttaa useisiin sivuihin sivumuistissa (sivulle, jossa on itse tiedot, sivuille, joissa on hakemistoja, sivuille, joissa on vapaa lista). Joissakin synteettisissä testeissä huomasin, että fyysiset tietueet veivät jopa 90 % WAL-tiedostosta. Niitä tarvitaan kuitenkin hyvin lyhyen ajan (oletusarvoisesti tarkistuspisteiden välinen aika on 3 minuuttia). Olisi loogista päästä eroon näistä tiedoista, kun ne ovat menettäneet merkityksensä. Juuri tätä WAL-tiivistysmekanismi tekee: se poistaa fyysisistä tietueista ja pakkaa jäljellä olevat loogiset tietueet zip-tiedoston avulla, kun taas tiedostokoko pienenee erittäin merkittävästi (joskus kymmeniä kertoja).

Fyysisesti WAL koostuu useista kiinteän kokoisista segmenteistä (oletusarvoisesti 10) (oletusarvoisesti 64 Mt), jotka kirjoitetaan päälle pyöreällä tavalla. Heti kun nykyinen segmentti on täytetty, seuraava segmentti määritetään nykyiseksi ja täytetty segmentti kopioidaan arkistoon erillisellä säikeellä. WAL-tiivistys toimii jo arkistosegmenttien kanssa. Lisäksi se valvoo erillisenä säietenä tarkistuspisteen suorittamista ja aloittaa pakkaamisen arkistosegmenteissä, joissa fyysisiä tietueita ei enää tarvita.

Tietojen pakkaus Apache Ignitessa. Sberin kokemus

Suorituskykyvaikutus

Koska WAL-tiivistys toimii erillisenä kierteenä, sillä ei pitäisi olla suoraa vaikutusta suoritettaviin toimiin. Mutta se silti lisää taustakuormitusta suorittimelle (pakkaus) ja levylle (lukee jokaisen WAL-segmentin arkistosta ja kirjoittaa pakatut segmentit), joten jos järjestelmä toimii suurimmalla kapasiteetilla, se johtaa myös suorituskyvyn heikkenemiseen.

Kuinka ottaa käyttöön ja määrittää

Voit ottaa WAL-tiivistyksen käyttöön ominaisuuden avulla WalCompactionEnabled в DataStorageConfiguration (DataStorageConfiguration.setWalCompactionEnabled(true)). DataStorageConfiguration.setWalCompactionLevel()-menetelmän avulla voit myös asettaa pakkaustason, jos et ole tyytyväinen oletusarvoon (PARAS_SPEED).

WAL-sivun tilannekuvan pakkaus

Kuinka tämä toimii

Olemme jo havainneet, että WAL:ssa tietueet jaetaan loogisiin ja fyysisiin. Jokaiselle sivulle tehtävää muutosta varten sivumuistiin luodaan fyysinen WAL-tietue. Fyysiset tietueet puolestaan ​​​​jaetaan myös kahteen alatyyppiin: sivun tilannekuvatietue ja deltatietue. Joka kerta kun muutamme jotain sivulla ja siirrämme sen puhtaasta tilasta likaiseen tilaan, tämän sivun täydellinen kopio tallennetaan WAL:iin (sivun tilannekuvatietue). Vaikka muutimme vain yhden tavun WAL:ssa, tietue on hieman sivukokoa suurempi. Jos muutamme jotain jo likaiselle sivulle, muodostuu WAL:iin deltatietue, joka heijastaa vain muutokset sivun edelliseen tilaan verrattuna, mutta ei koko sivua. Koska sivujen tila nollataan likaisesta puhtaaksi tarkistuspisteprosessin aikana, heti tarkistuspisteen alkamisen jälkeen, lähes kaikki fyysiset tietueet koostuvat vain sivujen tilannekuvista (koska kaikki sivut välittömästi tarkistuspisteen alun jälkeen ovat puhtaita) , sitten kun lähestymme seuraavaa tarkistuspistettä, deltatietueen murto-osa alkaa kasvaa ja nollata uudelleen seuraavan tarkistuspisteen alussa. Joidenkin synteettisten testien mittaukset osoittivat, että sivukuvien osuus fyysisten tietueiden kokonaismäärästä on 2 %.

WAL-sivun tilannevedospakkauksen ideana on pakata sivun tilannevedokset valmiilla sivunpakkaustyökalulla (katso levysivun pakkaus). Samanaikaisesti WAL:ssa tietueet tallennetaan peräkkäin vain liite -tilassa, eikä tietueita tarvitse sitoa tiedostojärjestelmälohkojen rajoihin, joten tässä, toisin kuin levysivun pakkausmekanismissa, emme tarvitse harvat tiedostot kaikki; vastaavasti tämä mekanismi ei toimi vain OS Linuxissa. Lisäksi meille ei ole enää väliä kuinka paljon pystyimme pakkaamaan sivua. Vaikka vapautimme 1 tavun, tämä on jo positiivinen tulos ja voimme tallentaa pakatut tiedot WAL-muodossa, toisin kuin levysivupakkauksessa, jossa tallennamme pakatun sivun vain, jos vapautimme enemmän kuin 1 tiedostojärjestelmälohkon.

Sivut ovat erittäin pakattavissa olevaa dataa, niiden osuus WAL-kokonaisvolyymista on erittäin suuri, joten ilman WAL-tiedostomuotoa muuttamatta sen kokoa voidaan pienentää merkittävästi. Pakkaus, mukaan lukien loogiset tietueet, vaatisi muotomuutosta ja yhteensopivuuden menetystä esimerkiksi ulkopuolisille kuluttajille, jotka saattavat olla kiinnostuneita loogisista tietueista, mutta se ei johtaisi tiedostokoon merkittävään pienenemiseen.

Kuten levysivun pakkauksessa, WAL-sivun tilannevedospakkaus voi käyttää ZSTD-, LZ4-, Snappy-pakkausalgoritmeja sekä SKIP_GARBAGE-tilaa.

Suorituskykyvaikutus

Ei ole vaikeaa huomata, että WAL-sivun tilannevedospakkauksen ottaminen suoraan käyttöön vaikuttaa vain säikeisiin, jotka kirjoittavat tietoja sivumuistiin, eli säikeisiin, jotka muuttavat tietoja välimuistissa. Fyysisten tietueiden lukeminen WAL:sta tapahtuu vain kerran, sillä hetkellä, kun solmu nostetaan putoamisen jälkeen (ja vain jos se putoaa tarkistuspisteen aikana).

Tämä vaikuttaa säikeisiin, jotka muuttavat tietoja seuraavalla tavalla: saamme negatiivisen vaikutuksen (CPU), koska sivu on pakattava joka kerta ennen kirjoittamista levylle, ja positiivisen vaikutuksen (levyn IO), koska sivujen määrä vähenee. kirjoitettu data. Vastaavasti täällä kaikki on yksinkertaista: jos järjestelmän suorituskykyä rajoittaa CPU, saamme pienen heikkenemisen, jos sitä rajoittaa levyn I/O, saamme lisäyksen.

Epäsuorasti WAL-koon pienentäminen vaikuttaa (positiivisesti) virtoihin, jotka upottavat WAL-segmenttejä arkistoon ja WAL-tiivistysvirtoihin.

Todelliset suorituskykytestit ympäristössämme synteettisellä datalla osoittivat pientä kasvua (suorituskyky kasvoi 10%-15%, latenssi väheni 10%-15%).

Kuinka ottaa käyttöön ja määrittää

Apache Igniten vähimmäisversio: 2.8. Ota käyttöön ja määritä seuraavasti:

  • Luokkapolussa on oltava sytytyspakkausmoduuli. Oletusarvoisesti se sijaitsee Apache Ignite -jakelussa libs/optional-hakemistossa, eikä se sisälly luokkapolkuun. Voit yksinkertaisesti siirtää hakemiston yhden tason ylöspäin libsiin ja sitten kun suoritat sen ignite.sh-tiedoston kautta, se otetaan automaattisesti käyttöön.
  • Pysyvyys on otettava käyttöön (Käytössä kautta DataRegionConfiguration.setPersistenceEnabled(true)).
  • Pakkaustila on asetettava menetelmällä DataStorageConfiguration.setWalPageCompression(), pakkaus on oletusarvoisesti poissa käytöstä (DISABLED-tila).
  • Valinnaisesti voit asettaa pakkaustason menetelmällä DataStorageConfiguration.setWalPageCompression(), katso javadocissa menetelmä kunkin tilan kelvollisille arvoille.

Johtopäätös

Apache Igniten harkittuja tiedonpakkausmekanismeja voidaan käyttää toisistaan ​​riippumatta, mutta mikä tahansa niiden yhdistelmä on myös hyväksyttävä. Niiden toiminnan ymmärtäminen antaa sinun määrittää, kuinka sopivat ne tehtäviisi ympäristössäsi ja mitä sinun on uhrattava käyttäessäsi niitä. Levysivun pakkaus on suunniteltu pakkaamaan päämuisti ja se voi antaa keskitason pakkaussuhteen. WAL-sivun tilannevedospakkaus antaa WAL-tiedostoille keskimääräisen pakkausasteen ja todennäköisesti jopa parantaa suorituskykyä. WAL-tiivistyksellä ei ole positiivista vaikutusta suorituskykyyn, mutta se pienentää WAL-tiedostojen kokoa niin paljon kuin mahdollista poistamalla fyysisiä tietueita.

Lähde: will.com

Lisää kommentti