Compressió de dades a Apache Ignite. L'experiència de Sber

Compressió de dades a Apache Ignite. L'experiència de SberQuan es treballa amb grans volums de dades, de vegades pot sorgir el problema de la manca d'espai al disc. Una manera de resoldre aquest problema és la compressió, gràcies a la qual, en el mateix equip, podeu permetre el luxe d'augmentar els volums d'emmagatzematge. En aquest article, veurem com funciona la compressió de dades a Apache Ignite. Aquest article descriu només els mètodes de compressió de disc implementats al producte. Altres mètodes de compressió de dades (a la xarxa, a la memòria), implementats o no, romandran fora de l'abast.

Per tant, amb el mode de persistència activat, com a resultat dels canvis en les dades a la memòria cau, Ignite comença a escriure al disc:

  1. Contingut de la memòria cau
  2. Write Ahead Log (d'ara endavant simplement WAL)

Hi ha un mecanisme per a la compressió WAL des de fa força temps, anomenat compactació WAL. L'Apache Ignite 2.8, publicat recentment, va introduir dos mecanismes més que us permeten comprimir dades al disc: compressió de pàgines de disc per comprimir el contingut de la memòria cau i compressió d'instantànies de pàgines WAL per comprimir algunes entrades WAL. Més detalls sobre aquests tres mecanismes a continuació.

Compressió de pàgines de disc

Com funciona això

Primer, fem una ullada molt breu a com emmagatzema Ignite les dades. La memòria de la pàgina s'utilitza per a l'emmagatzematge. La mida de la pàgina s'estableix a l'inici del node i no es pot canviar en etapes posteriors; també, la mida de la pàgina ha de ser una potència de dos i un múltiple de la mida del bloc del sistema de fitxers. Les pàgines es carreguen a la memòria RAM des del disc segons sigui necessari; la mida de les dades del disc pot superar la quantitat de memòria RAM assignada. Si no hi ha prou espai a la memòria RAM per carregar una pàgina des del disc, les pàgines antigues que ja no s'utilitzen es desallotjaran de la memòria RAM.

Les dades s'emmagatzemen al disc de la forma següent: es crea un fitxer separat per a cada partició de cada grup de memòria cau; en aquest fitxer, les pàgines apareixen una darrere l'altra en ordre d'índex ascendent. L'identificador de pàgina completa conté l'identificador del grup de memòria cau, el número de partició i l'índex de pàgina al fitxer. Així, utilitzant l'identificador de pàgina completa, podem determinar de manera única el fitxer i el desplaçament del fitxer per a cada pàgina. Podeu llegir més informació sobre la memòria de paginació a l'article de l'Apache Ignite Wiki: Ignite Persistent Store - sota el capó.

El mecanisme de compressió de la pàgina del disc, com podeu endevinar pel nom, funciona a nivell de pàgina. Quan aquest mecanisme està activat, les dades de la memòria RAM es processen tal com estan, sense cap tipus de compressió, però quan les pàgines es guarden de la memòria RAM al disc, es comprimeixen.

Però comprimir cada pàgina individualment no és una solució al problema; cal reduir d'alguna manera la mida dels fitxers de dades resultants. Si la mida de la pàgina ja no es fixa, ja no podem escriure pàgines al fitxer una darrere l'altra, ja que això pot crear una sèrie de problemes:

  • Mitjançant l'índex de pàgina, no podrem calcular el desplaçament amb el qual es troba al fitxer.
  • No està clar què fer amb les pàgines que no estan al final del fitxer i canvien la seva mida. Si la mida de la pàgina disminueix, l'espai que va alliberar desapareix. Si la mida de la pàgina augmenta, cal que cerqueu un lloc nou al fitxer.
  • Si una pàgina es mou un nombre d'octets que no és un múltiple de la mida del bloc del sistema de fitxers, per llegir-la o escriure-la caldrà tocar un bloc més del sistema de fitxers, cosa que pot provocar una degradació del rendiment.

Per evitar resoldre aquests problemes al seu propi nivell, la compressió de pàgines de disc a Apache Ignite utilitza un mecanisme del sistema de fitxers anomenat fitxers dispersos. Un fitxer escàs és aquell en què algunes regions plenes de zero es poden marcar com a "forats". En aquest cas, no s'assignarà cap bloc del sistema de fitxers per emmagatzemar aquests forats, la qual cosa suposarà un estalvi d'espai en disc.

És lògic que per alliberar un bloc del sistema de fitxers, la mida del forat ha de ser superior o igual al bloc del sistema de fitxers, la qual cosa imposa una limitació addicional a la mida de la pàgina i Apache Ignite: perquè la compressió tingui algun efecte, la mida de la pàgina ha de ser estrictament més gran que la mida del bloc del sistema de fitxers. Si la mida de la pàgina és igual a la mida del bloc, aleshores mai podrem alliberar un sol bloc, ja que per alliberar un únic bloc, la pàgina comprimida ha d'ocupar 0 bytes. Si la mida de la pàgina és igual a la mida de 2 o 4 blocs, ja podrem alliberar almenys un bloc si la nostra pàgina està comprimida com a mínim al 50% o al 75%, respectivament.

Així doncs, la descripció final de com funciona el mecanisme: En escriure una pàgina al disc, s'intenta comprimir la pàgina. Si la mida de la pàgina comprimida permet alliberar un o més blocs del sistema de fitxers, la pàgina s'escriu en forma comprimida i es fa un "forat" en lloc dels blocs alliberats (s'executa una crida al sistema). fallocate() amb la bandera del forat). Si la mida de la pàgina comprimida no permet alliberar els blocs, la pàgina es desa tal com està, sense comprimir. Tots els desplaçaments de pàgina es calculen de la mateixa manera que sense compressió, multiplicant l'índex de pàgina per la mida de la pàgina. No cal reubicar les pàgines pel vostre compte. Els desplaçaments de pàgina, igual que sense compressió, cauen als límits dels blocs del sistema de fitxers.

Compressió de dades a Apache Ignite. L'experiència de Sber

En la implementació actual, l'Ignite només pot funcionar amb fitxers escassos sota el sistema operatiu Linux; per tant, la compressió de pàgines de disc només es pot activar quan s'utilitza Ignite en aquest sistema operatiu.

Algorismes de compressió que es poden utilitzar per a la compressió de pàgines de disc: ZSTD, LZ4, Snappy. A més, hi ha un mode de funcionament (SKIP_GARBAGE), en què només s'elimina l'espai no utilitzat de la pàgina sense aplicar compressió a les dades restants, la qual cosa redueix la càrrega de la CPU en comparació amb els algorismes enumerats anteriorment.

Impacte en el rendiment

Malauradament, no he realitzat mesures reals de rendiment en estands reals, ja que no pensem utilitzar aquest mecanisme a la producció, però teòricament podem especular on perdrem i on guanyarem.

Per fer-ho, hem de recordar com es llegeixen i s'escriuen les pàgines quan s'hi accedeix:

  • Quan es realitza una operació de lectura, primer es cerca a la RAM; si la cerca no té èxit, la pàgina es carrega a la RAM des del disc pel mateix fil que realitza la lectura.
  • Quan es realitza una operació d'escriptura, la pàgina de la memòria RAM es marca com a bruta, però el fil que realitza l'escriptura no desa la pàgina físicament al disc immediatament. Totes les pàgines brutes es guarden al disc més tard en el procés del punt de control en fils separats.

Per tant, l'impacte en les operacions de lectura és:

  • Positiu (E/S de disc), a causa d'una disminució del nombre de blocs del sistema de fitxers de lectura.
  • Negatiu (CPU), a causa de la càrrega addicional que requereix el sistema operatiu per treballar amb fitxers escassos. També és possible que les operacions d'E/S addicionals apareguin implícitament aquí per desar una estructura de fitxers escassa més complexa (per desgràcia, no estic familiaritzat amb tots els detalls de com funcionen els fitxers dispersos).
  • Negatiu (CPU), per la necessitat de descomprimir pàgines.
  • No hi ha cap impacte en les operacions d'escriptura.
  • Impacte en el procés del punt de control (tot aquí és semblant a les operacions de lectura):
  • Positiu (E/S de disc), a causa d'una disminució del nombre de blocs del sistema de fitxers escrits.
  • Negatiu (CPU, possiblement E/S de disc), a causa del treball amb fitxers escassos.
  • Negatiu (CPU), a causa de la necessitat de compressió de la pàgina.

Quin costat de la balança inclinarà la balança? Tot això depèn molt de l'entorn, però m'inclino a creure que la compressió de pàgines de disc probablement comportarà una degradació del rendiment a la majoria dels sistemes. A més, les proves en altres SGBD que utilitzen un enfocament similar amb fitxers escassos mostren una caiguda del rendiment quan la compressió està activada.

Com habilitar i configurar

Com s'ha esmentat anteriorment, la versió mínima d'Apache Ignite que admet la compressió de pàgines de disc és la 2.8 i només s'admet el sistema operatiu Linux. Activeu i configureu de la següent manera:

  • Hi ha d'haver un mòdul d'encesa-compressió a la ruta de classe. Per defecte, es troba a la distribució Apache Ignite al directori libs/opcional i no s'inclou a la ruta de classe. Només podeu moure el directori un nivell cap a libs i després, quan l'executeu a través d'ignite.sh, s'habilitarà automàticament.
  • La persistència s'ha d'habilitar (habilitat mitjançant DataRegionConfiguration.setPersistenceEnabled(true)).
  • La mida de la pàgina ha de ser més gran que la mida del bloc del sistema de fitxers (podeu configurar-la utilitzant DataStorageConfiguration.setPageSize() ).
  • Per a cada memòria cau les dades de la qual cal comprimir, heu de configurar el mètode de compressió i (opcionalment) el nivell de compressió (mètodes). CacheConfiguration.setDiskPageCompression() , CacheConfiguration.setDiskPageCompressionLevel()).

Compactació WAL

Com funciona això

Què és WAL i per què es necessita? Molt breument: aquest és un registre que conté tots els esdeveniments que finalment canvien l'emmagatzematge de la pàgina. Es necessita principalment per poder recuperar-se en cas de caiguda. Qualsevol operació, abans de donar-li el control a l'usuari, primer ha d'enregistrar un esdeveniment a WAL, de manera que en cas de fallada es pugui reproduir al registre i restaurar totes les operacions per les quals l'usuari ha rebut una resposta correcta, encara que aquestes operacions. no va tenir temps de reflectir-se en l'emmagatzematge de la pàgina al disc (ja més amunt S'ha descrit que l'escriptura real a la botiga de pàgines es fa en un procés anomenat "punt de comprovació" amb cert retard per fils separats).

Les entrades a WAL es divideixen en lògiques i físiques. Els booleans són les claus i els mateixos valors. Física: reflecteix els canvis a les pàgines de la botiga de pàgines. Tot i que els registres lògics poden ser útils per a alguns altres casos, els registres físics només es necessiten per a la recuperació en cas d'error i només es necessiten des de l'últim punt de control satisfactori. Aquí no entrarem en detalls i explicarem per què funciona d'aquesta manera, però els interessats poden consultar l'article ja esmentat a l'Apache Ignite Wiki: Ignite Persistent Store - sota el capó.

Sovint hi ha diversos registres físics per registre lògic. És a dir, per exemple, una operació de posada a la memòria cau afecta diverses pàgines de la memòria de la pàgina (una pàgina amb les dades en si, pàgines amb índexs, pàgines amb llistes lliures). En algunes proves sintètiques, vaig trobar que els registres físics ocupaven fins al 90% del fitxer WAL. Tanmateix, es necessiten durant molt poc temps (per defecte, l'interval entre punts de control és de 3 minuts). Seria lògic desfer-se d'aquestes dades després de perdre la seva rellevància. Això és exactament el que fa el mecanisme de compactació WAL: elimina els registres físics i comprimeix els registres lògics restants mitjançant zip, mentre que la mida del fitxer es redueix molt significativament (de vegades en desenes de vegades).

Físicament, WAL consta de diversos segments (10 per defecte) de mida fixa (64 MB per defecte), que es sobreescriuen de manera circular. Tan bon punt s'omple el segment actual, el següent segment s'assigna com a actual i el segment omplert es copia a l'arxiu mitjançant un fil separat. La compactació WAL ja funciona amb segments d'arxiu. A més, com a fil independent, supervisa l'execució del punt de control i comença la compressió en segments d'arxiu per als quals ja no es necessiten registres físics.

Compressió de dades a Apache Ignite. L'experiència de Sber

Impacte en el rendiment

Atès que la compactació WAL s'executa com un fil independent, no hi hauria d'haver cap impacte directe en les operacions que es realitzen. Però encara posa una càrrega de fons addicional a la CPU (compressió) i al disc (llegint cada segment WAL de l'arxiu i escrivint els segments comprimits), de manera que si el sistema s'executa a la seva màxima capacitat, també comportarà una degradació del rendiment.

Com habilitar i configurar

Podeu habilitar la compactació WAL mitjançant la propietat WalCompactionEnabled в DataStorageConfiguration (DataStorageConfiguration.setWalCompactionEnabled(true)). A més, amb el mètode DataStorageConfiguration.setWalCompactionLevel(), podeu establir el nivell de compressió si no esteu satisfet amb el valor predeterminat (BEST_SPEED).

Compressió d'instantànies de la pàgina WAL

Com funciona això

Ja hem descobert que a WAL els registres es divideixen en lògics i físics. Per a cada canvi a cada pàgina, es genera un registre WAL físic a la memòria de la pàgina. Els registres físics, al seu torn, també es divideixen en 2 subtipus: registre d'instantània de pàgina i registre delta. Cada vegada que canviem alguna cosa en una pàgina i la transferim d'un estat net a un estat brut, una còpia completa d'aquesta pàgina s'emmagatzema a WAL (registre de la instantània de la pàgina). Fins i tot si només canviem un byte a WAL, el registre serà una mica més gran que la mida de la pàgina. Si canviem alguna cosa en una pàgina ja bruta, es forma un registre delta a WAL, que només reflecteix els canvis en comparació amb l'estat anterior de la pàgina, però no tota la pàgina. Com que el restabliment de l'estat de les pàgines de brut a net es realitza durant el procés del punt de control, immediatament després de l'inici del punt de control, gairebé tots els registres físics consistiran només en instantànies de pàgines (ja que totes les pàgines immediatament després de l'inici del punt de control estan netes). , aleshores a mesura que ens acostem al següent punt de control, la fracció de registre delta comença a créixer i es reinicia de nou al començament del següent punt de control. Les mesures d'algunes proves sintètiques van mostrar que la quota de les instantànies de la pàgina en el volum total de registres físics arriba al 90%.

La idea de la compressió de les instantànies de la pàgina WAL és comprimir les instantànies de la pàgina mitjançant una eina de compressió de pàgines preparada (vegeu la compressió de la pàgina del disc). Al mateix temps, a WAL, els registres es guarden seqüencialment en mode només d'afegir i no cal lligar els registres als límits dels blocs del sistema de fitxers, de manera que aquí, a diferència del mecanisme de compressió de pàgines de disc, no necessitem fitxers dispersos a tot; en conseqüència, aquest mecanisme funcionarà no només al sistema operatiu Linux. A més, ja no ens importa quant hem pogut comprimir la pàgina. Fins i tot si hem alliberat 1 byte, aquest ja és un resultat positiu i podem desar dades comprimides a WAL, a diferència de la compressió de pàgines de disc, on desem la pàgina comprimida només si hem alliberat més d'1 bloc del sistema de fitxers.

Les pàgines són dades altament compressibles, la seva participació en el volum total de WAL és molt elevada, de manera que sense canviar el format del fitxer WAL podem aconseguir una reducció important de la seva mida. La compressió, inclosos els registres lògics, requeriria un canvi de format i una pèrdua de compatibilitat, per exemple, per als consumidors externs que poden estar interessats en els registres lògics, però no comportaria una reducció significativa de la mida del fitxer.

Igual que amb la compressió de pàgines de disc, la compressió d'instantànies de la pàgina WAL pot utilitzar els algorismes de compressió ZSTD, LZ4, Snappy, així com el mode SKIP_GARBAGE.

Impacte en el rendiment

No és difícil notar que activar directament la compressió d'instantànies de la pàgina WAL només afecta els fils que escriuen dades a la memòria de la pàgina, és a dir, aquells fils que canvien les dades a la memòria cau. La lectura dels registres físics de WAL només es produeix una vegada, en el moment en què el node s'aixeca després d'una caiguda (i només si cau durant un punt de control).

Això afecta els fils que canvien les dades de la següent manera: obtenim un efecte negatiu (CPU) per la necessitat de comprimir la pàgina cada cop abans d'escriure al disc, i un efecte positiu (E/S de disc) per una disminució de la quantitat de dades escrites. En conseqüència, aquí tot és senzill: si el rendiment del sistema està limitat per la CPU, obtenim una lleugera degradació, si està limitat per l'E/S del disc, obtenim un augment.

Indirectament, reduir la mida de WAL també afecta (positivament) els fluxos que aboquen segments WAL a l'arxiu i els fluxos de compactació WAL.

Les proves de rendiment real al nostre entorn amb dades sintètiques van mostrar un lleuger augment (el rendiment va augmentar entre un 10% i un 15%, la latència va disminuir entre un 10% i un 15%).

Com habilitar i configurar

Versió mínima d'Apache Ignite: 2.8. Activeu i configureu de la següent manera:

  • Hi ha d'haver un mòdul d'encesa-compressió a la ruta de classe. Per defecte, es troba a la distribució Apache Ignite al directori libs/opcional i no s'inclou a la ruta de classe. Només podeu moure el directori un nivell cap a libs i després, quan l'executeu a través d'ignite.sh, s'habilitarà automàticament.
  • La persistència s'ha d'habilitar (habilitat mitjançant DataRegionConfiguration.setPersistenceEnabled(true)).
  • El mode de compressió s'ha d'establir mitjançant el mètode DataStorageConfiguration.setWalPageCompression(), la compressió està desactivada per defecte (mode DISABLED).
  • Opcionalment, podeu establir el nivell de compressió mitjançant el mètode DataStorageConfiguration.setWalPageCompression(), consulteu el javadoc del mètode per obtenir valors vàlids per a cada mode.

Conclusió

Els mecanismes de compressió de dades considerats a Apache Ignite es poden utilitzar independentment els uns dels altres, però també és acceptable qualsevol combinació d'ells. Entendre com funcionen us permetrà determinar fins a quin punt són adequats per a les vostres tasques al vostre entorn i què haureu de sacrificar en utilitzar-los. La compressió de la pàgina de disc està dissenyada per comprimir l'emmagatzematge principal i pot donar una relació de compressió mitjana. La compressió de les instantànies de la pàgina WAL donarà un grau mitjà de compressió per als fitxers WAL i, molt probablement, fins i tot millorarà el rendiment. La compactació WAL no tindrà un efecte positiu en el rendiment, però reduirà la mida dels fitxers WAL tant com sigui possible eliminant els registres físics.

Font: www.habr.com

Afegeix comentari