Compresión de datos en Apache Ignite. A experiencia de Sber

Compresión de datos en Apache Ignite. A experiencia de SberCando se traballa con grandes volumes de datos, ás veces pode xurdir o problema da falta de espazo no disco. Unha forma de resolver este problema é a compresión, grazas á cal, no mesmo equipo, pode permitirse o luxo de aumentar os volumes de almacenamento. Neste artigo, analizaremos como funciona a compresión de datos en Apache Ignite. Este artigo describirá só os métodos de compresión de disco implementados no produto. Outros métodos de compresión de datos (a través da rede, na memoria), implementados ou non, permanecerán fóra do ámbito.

Polo tanto, co modo de persistencia activado, como resultado dos cambios nos datos nos cachés, Ignite comeza a escribir no disco:

  1. Contido de cachés
  2. Write Ahead Log (en diante simplemente WAL)

Hai un tempo que existe un mecanismo para a compresión WAL, chamado compactación WAL. O Apache Ignite 2.8 lanzado recentemente introduciu dous mecanismos máis que permiten comprimir datos no disco: compresión de páxinas de disco para comprimir o contido das cachés e compresión de instantáneas de páxinas WAL para comprimir algunhas entradas WAL. Máis detalles sobre estes tres mecanismos a continuación.

Compresión da páxina do disco

Chat isto

En primeiro lugar, imos dar unha breve ollada a como Ignite almacena os datos. A memoria de páxina úsase para almacenar. O tamaño da páxina establécese ao inicio do nodo e non se pode cambiar en etapas posteriores; ademais, o tamaño da páxina debe ser unha potencia de dous e un múltiplo do tamaño do bloque do sistema de ficheiros. As páxinas cárganse na RAM desde o disco segundo sexa necesario; o tamaño dos datos do disco pode exceder a cantidade de RAM asignada. Se non hai espazo suficiente na memoria RAM para cargar unha páxina do disco, as páxinas antigas que xa non se usan serán expulsadas da memoria RAM.

Os datos gárdanse no disco da seguinte forma: créase un ficheiro separado para cada partición de cada grupo de caché; neste ficheiro, as páxinas aparecen unha tras outra en orde de índice ascendente. O identificador de páxina completa contén o identificador do grupo de caché, o número de partición e o índice de páxina no ficheiro. Así, usando o identificador de páxina completa, podemos determinar de forma única o ficheiro e a compensación do ficheiro para cada páxina. Podes ler máis sobre a memoria de paginación no artigo Apache Ignite Wiki: Ignite Persistent Store - baixo o capó.

O mecanismo de compresión da páxina do disco, como podes adiviñar polo nome, funciona a nivel de páxina. Cando este mecanismo está activado, os datos na RAM son procesados ​​como están, sen ningunha compresión, pero cando as páxinas se gardan da RAM ao disco, comprimen.

Pero comprimir cada páxina individualmente non é unha solución ao problema; cómpre reducir dalgún xeito o tamaño dos ficheiros de datos resultantes. Se xa non se corrixe o tamaño da páxina, xa non podemos escribir páxinas no ficheiro unha tras outra, xa que isto pode crear unha serie de problemas:

  • Usando o índice de páxina, non poderemos calcular a compensación pola que se atopa no ficheiro.
  • Non está claro que facer coas páxinas que non están ao final do ficheiro e cambian o seu tamaño. Se o tamaño da páxina diminúe, o espazo que liberou desaparece. Se o tamaño da páxina aumenta, cómpre buscar un novo lugar no ficheiro para el.
  • Se unha páxina se move por un número de bytes que non é un múltiplo do tamaño do bloque do sistema de ficheiros, a lectura ou a escritura requirirá tocar un bloque máis do sistema de ficheiros, o que pode provocar unha degradación do rendemento.

Para evitar resolver estes problemas no seu propio nivel, a compresión de páxinas de disco en Apache Ignite usa un mecanismo do sistema de ficheiros chamado ficheiros dispersos. Un ficheiro escaso é aquel no que algunhas rexións de cero poden marcarse como "buratos". Neste caso, non se asignarán bloques do sistema de ficheiros para almacenar estes buratos, o que supón un aforro de espazo no disco.

É lóxico que para liberar un bloque do sistema de ficheiros, o tamaño do burato debe ser maior ou igual ao bloque do sistema de ficheiros, o que impón unha limitación adicional ao tamaño da páxina e Apache Ignite: para que a compresión teña algún efecto, o tamaño da páxina debe ser estrictamente maior que o tamaño do bloque do sistema de ficheiros . Se o tamaño da páxina é igual ao tamaño do bloque, entón nunca poderemos liberar un só bloque, xa que para liberar un só bloque, a páxina comprimida debe ocupar 0 bytes. Se o tamaño da páxina é igual ao tamaño de 2 ou 4 bloques, xa poderemos liberar polo menos un bloque se a nosa páxina está comprimida polo menos ao 50 % ou 75 %, respectivamente.

Así, a descrición final de como funciona o mecanismo: ao escribir unha páxina no disco, téntase comprimir a páxina. Se o tamaño da páxina comprimida permite liberar un ou máis bloques do sistema de ficheiros, entón a páxina escríbese en forma comprimida e faise un "burato" no lugar dos bloques liberados (execútase unha chamada ao sistema fallocate() coa bandeira de perforación). Se o tamaño da páxina comprimida non permite liberar os bloques, a páxina gárdase como está, sen comprimir. Todos os desprazamentos de páxina calcúlanse do mesmo xeito que sen compresión, multiplicando o índice de páxina polo tamaño da páxina. Non é necesario desprazar páxinas por conta propia. As compensacións de páxina, igual que sen compresión, caen nos límites dos bloques do sistema de ficheiros.

Compresión de datos en Apache Ignite. A experiencia de Sber

Na implementación actual, Ignite só pode funcionar con ficheiros escasos baixo o sistema operativo Linux; polo tanto, a compresión de páxinas de disco só se pode activar cando se usa Ignite neste sistema operativo.

Algoritmos de compresión que se poden usar para a compresión de páxinas de disco: ZSTD, LZ4, Snappy. Ademais, existe un modo operativo (SKIP_GARBAGE), no que só se bota o espazo non utilizado na páxina sen aplicar compresión aos datos restantes, o que reduce a carga da CPU en comparación cos algoritmos listados anteriormente.

Impacto no rendemento

Desafortunadamente, non realicei medicións de rendemento reais en stands reais, xa que non pensamos usar este mecanismo na produción, pero teoricamente podemos especular onde perderemos e onde gañaremos.

Para iso, debemos lembrar como se len e escriben as páxinas ao acceder:

  • Cando se realiza unha operación de lectura, primeiro búscase na RAM; se a busca non ten éxito, a páxina cárgase na RAM desde o disco polo mesmo fío que realiza a lectura.
  • Cando se realiza unha operación de escritura, a páxina na RAM márcase como sucia, pero a páxina non se garda fisicamente no disco inmediatamente polo fío que realiza a escritura. Todas as páxinas sucias gárdanse no disco máis tarde no proceso do punto de verificación en fíos separados.

Polo tanto, o impacto nas operacións de lectura é:

  • Positivo (E/S de disco), debido á diminución do número de bloques do sistema de ficheiros lidos.
  • Negativo (CPU), debido á carga adicional que require o sistema operativo para traballar con ficheiros escasos. Tamén é posible que aparezan implicitamente aquí operacións de E/S adicionais para gardar unha estrutura de ficheiros máis complexa (desafortunadamente, non estou familiarizado con todos os detalles de como funcionan os ficheiros escasos).
  • Negativo (CPU), debido á necesidade de descomprimir páxinas.
  • Non hai impacto nas operacións de escritura.
  • Impacto no proceso do punto de control (todo aquí é semellante ás operacións de lectura):
  • Positivo (E/S de disco), debido á diminución do número de bloques do sistema de ficheiros escritos.
  • Negativo (CPU, posiblemente E/S do disco), debido ao traballo con ficheiros escasos.
  • Negativo (CPU), debido á necesidade de compresión da páxina.

Que lado da balanza inclinará a balanza? Todo depende moito do ambiente, pero inclínome a crer que a compresión das páxinas do disco probablemente levará a unha degradación do rendemento na maioría dos sistemas. Ademais, as probas noutros DBMS que usan un enfoque similar con ficheiros escasos mostran unha caída no rendemento cando se activa a compresión.

Como activar e configurar

Como se mencionou anteriormente, a versión mínima de Apache Ignite que admite a compresión de páxinas de disco é 2.8 e só se admite o sistema operativo Linux. Active e configure como segue:

  • Debe haber un módulo de compresión de ignite na ruta de clase. Por defecto, atópase na distribución Apache Ignite no directorio libs/optional e non se inclúe na ruta da clase. Podes simplemente mover o directorio un nivel a libs e despois, cando o executes a través de ignite.sh, activarase automaticamente.
  • A persistencia debe estar activada (Activada mediante DataRegionConfiguration.setPersistenceEnabled(true)).
  • O tamaño da páxina debe ser maior que o tamaño do bloque do sistema de ficheiros (pode configuralo usando DataStorageConfiguration.setPageSize() ).
  • Para cada caché cuxos datos se deben comprimir, debe configurar o método de compresión e (opcionalmente) o nivel de compresión (métodos CacheConfiguration.setDiskPageCompression() , CacheConfiguration.setDiskPageCompressionLevel()).

Compactación WAL

Chat isto

Que é WAL e por que é necesario? Moi brevemente: este é un rexistro que contén todos os eventos que finalmente cambian o almacenamento da páxina. Precísase sobre todo para poder recuperarse en caso de caída. Calquera operación, antes de darlle o control ao usuario, debe rexistrar primeiro un evento en WAL, para que, en caso de falla, poida reproducirse no rexistro e restaurar todas as operacións para as que o usuario recibiu unha resposta satisfactoria, aínda que estas operacións non tivo tempo de reflectirse no almacenamento da páxina no disco (xa arriba Describíronse que a escritura real no almacén de páxinas realízase nun proceso chamado "checkpointing" con certo atraso por fíos separados).

As entradas en WAL divídense en lóxicas e físicas. Os booleanos son as claves e os propios valores. Físico: reflicte os cambios nas páxinas da tenda de páxinas. Aínda que os rexistros lóxicos poden ser útiles nalgúns outros casos, os rexistros físicos son necesarios só para a recuperación en caso de fallo e só son necesarios desde o último punto de control exitoso. Aquí non entraremos en detalles e explicaremos por que funciona deste xeito, pero os interesados ​​poden consultar o artigo xa mencionado na Wiki Apache Ignite: Ignite Persistent Store - baixo o capó.

Moitas veces hai varios rexistros físicos por rexistro lóxico. É dicir, por exemplo, unha operación de colocación na caché afecta a varias páxinas da memoria de páxina (unha páxina cos datos en si, páxinas con índices, páxinas con listas libres). Nalgunhas probas sintéticas, atopei que os rexistros físicos ocupaban ata o 90 % do ficheiro WAL. Non obstante, son necesarios durante moi pouco tempo (por defecto, o intervalo entre puntos de control é de 3 minutos). Sería lóxico desfacerse destes datos despois de perder a súa relevancia. Isto é exactamente o que fai o mecanismo de compactación WAL: elimina os rexistros físicos e comprime os rexistros lóxicos restantes mediante zip, mentres que o tamaño do ficheiro redúcese de forma moi significativa (ás veces en decenas de veces).

Físicamente, WAL consta de varios segmentos (10 por defecto) de tamaño fixo (64 MB por defecto), que se sobrescriben de forma circular. En canto se enche o segmento actual, asígnase o segmento seguinte como actual e o segmento enchido cópiase no arquivo mediante un fío separado. A compactación WAL xa funciona con segmentos de arquivo. Ademais, como fío separado, supervisa a execución do punto de control e comeza a compresión en segmentos de arquivo para os que xa non son necesarios rexistros físicos.

Compresión de datos en Apache Ignite. A experiencia de Sber

Impacto no rendemento

Dado que a compactación WAL funciona como un fío separado, non debería haber ningún impacto directo nas operacións que se están a realizar. Pero aínda pon unha carga de fondo adicional na CPU (compresión) e no disco (lendo cada segmento de WAL do arquivo e escribindo os segmentos comprimidos), polo que se o sistema funciona á súa máxima capacidade, tamén provocará unha degradación do rendemento.

Como activar e configurar

Podes activar a compactación WAL usando a propiedade WalCompactionEnabled в DataStorageConfiguration (DataStorageConfiguration.setWalCompactionEnabled(true)). Ademais, usando o método DataStorageConfiguration.setWalCompactionLevel(), pode establecer o nivel de compresión se non está satisfeito co valor predeterminado (BEST_SPEED).

Compresión de instantáneas da páxina WAL

Chat isto

Xa descubrimos que en WAL os rexistros divídense en lóxicos e físicos. Para cada cambio en cada páxina, xérase un rexistro WAL físico na memoria da páxina. Os rexistros físicos, pola súa banda, tamén se dividen en 2 subtipos: rexistro de instantáneas de páxina e rexistro delta. Cada vez que cambiamos algo nunha páxina e o trasladamos dun estado limpo a un estado sucio, gárdase unha copia completa desta páxina en WAL (rexistro de instantáneas da páxina). Aínda que só cambiamos un byte en WAL, o rexistro será lixeiramente maior que o tamaño da páxina. Se cambiamos algo nunha páxina xa sucia, fórmase un rexistro delta en WAL, que só reflicte os cambios en comparación co estado anterior da páxina, pero non toda a páxina. Dado que o restablecemento do estado das páxinas de sucio a limpo realízase durante o proceso do punto de control, inmediatamente despois do inicio do punto de control, case todos os rexistros físicos consistirán só en instantáneas de páxinas (xa que todas as páxinas inmediatamente despois do inicio do punto de control están limpas). , entón a medida que nos achegamos ao seguinte punto de control, a fracción de rexistro delta comeza a crecer e restablecerse de novo ao comezo do seguinte punto de control. As medicións nalgunhas probas sintéticas mostraron que a proporción de instantáneas de páxinas no volume total de rexistros físicos alcanza o 90%.

A idea da compresión de instantáneas de páxinas WAL é comprimir as instantáneas de páxinas usando unha ferramenta de compresión de páxinas preparada (consulte a compresión de páxinas de disco). Ao mesmo tempo, en WAL, os rexistros gárdanse secuencialmente en modo de só adición e non hai necesidade de vincular os rexistros aos límites dos bloques do sistema de ficheiros, polo que aquí, a diferenza do mecanismo de compresión da páxina do disco, non necesitamos ficheiros escasos. todo; polo tanto, este mecanismo funcionará non só no SO Linux. Ademais, xa non nos importa canto fomos capaces de comprimir a páxina. Aínda que liberamos 1 byte, este xa é un resultado positivo e podemos gardar os datos comprimidos en WAL, a diferenza da compresión da páxina de disco, onde gardamos a páxina comprimida só se liberamos máis de 1 bloque do sistema de ficheiros.

As páxinas son datos altamente comprimibles, a súa participación no volume total de WAL é moi elevada, polo que sen cambiar o formato de ficheiro WAL podemos conseguir unha redución importante do seu tamaño. A compresión, incluídos os rexistros lóxicos, requiriría un cambio de formato e perda de compatibilidade, por exemplo, para os consumidores externos que poidan estar interesados ​​nos rexistros lóxicos, pero non suporía unha redución significativa do tamaño do ficheiro.

Do mesmo xeito que coa compresión de páxinas de disco, a compresión de instantáneas de páxinas WAL pode usar os algoritmos de compresión ZSTD, LZ4 e Snappy, así como o modo SKIP_GARBAGE.

Impacto no rendemento

Non é difícil notar que activar directamente a compresión de instantáneas de páxinas WAL só afecta aos fíos que escriben datos na memoria da páxina, é dicir, a aqueles fíos que cambian os datos da caché. A lectura de rexistros físicos de WAL ocorre só unha vez, no momento en que o nodo se eleva despois dunha caída (e só se cae durante un punto de control).

Isto afecta aos fíos que cambian datos do seguinte xeito: obtemos un efecto negativo (CPU) debido á necesidade de comprimir a páxina cada vez antes de escribir no disco, e un efecto positivo (IO do disco) debido á redución da cantidade de datos escritos. En consecuencia, aquí todo é sinxelo: se o rendemento do sistema está limitado pola CPU, obtemos unha lixeira degradación, se está limitado pola E/S do disco, obtemos un aumento.

Indirectamente, a redución do tamaño de WAL tamén afecta (de forma positiva) aos fluxos que volcan segmentos de WAL ao arquivo e aos fluxos de compactación de WAL.

As probas de rendemento real no noso contorno utilizando datos sintéticos mostraron un lixeiro aumento (o rendemento aumentou entre un 10 % e un 15 %, a latencia diminuíu entre un 10 % e un 15 %).

Como activar e configurar

Versión mínima de Apache Ignite: 2.8. Active e configure como segue:

  • Debe haber un módulo de compresión de ignite na ruta de clase. Por defecto, atópase na distribución Apache Ignite no directorio libs/optional e non se inclúe na ruta da clase. Podes simplemente mover o directorio un nivel a libs e despois, cando o executes a través de ignite.sh, activarase automaticamente.
  • A persistencia debe estar activada (Activada mediante DataRegionConfiguration.setPersistenceEnabled(true)).
  • O modo de compresión debe configurarse mediante o método DataStorageConfiguration.setWalPageCompression(), a compresión está desactivada por defecto (modo DESACTIVADO).
  • Opcionalmente, pode establecer o nivel de compresión usando o método DataStorageConfiguration.setWalPageCompression(), consulte o Javadoc para o método para os valores válidos para cada modo.

Conclusión

Os mecanismos de compresión de datos considerados en Apache Ignite pódense usar de forma independente uns dos outros, pero calquera combinación deles tamén é aceptable. Entender o seu funcionamento permitirache determinar o que son axeitados para as túas tarefas no teu entorno e o que terás que sacrificar ao utilizalos. A compresión da páxina de disco está deseñada para comprimir o almacenamento principal e pode dar unha relación de compresión media. A compresión de instantáneas da páxina WAL dará un grao medio de compresión para os ficheiros WAL e, probablemente, incluso mellorará o rendemento. A compactación de WAL non terá un efecto positivo no rendemento, pero reducirá o tamaño dos ficheiros WAL na medida do posible eliminando rexistros físicos.

Fonte: www.habr.com

Engadir un comentario