Translate

domingo, 7 de abril de 2019

Memtables, SSTables y Commit Logs en Apache Cassandra


Veamos como es la estructura interna y archivos de apache cassandra. Cassandra guarda datos en memoria y en disco, uno que provee alta performance y el otro durabilidad. Cassandra tiene 3 estrucuras de guardado, memtables, sstables y commit logs.

Cuando realiza una operación de escritura, se escribe inmediatamente en commit logs. Commit logs es un mecanismo de recuperación ante errores. Permite volver a cassandra al estado anterior del error.

Una escritura no se considerará exitosa hasta que se escriba en el commit logs, para garantizar que si una operación de escritura no llega al almacén en memoria, aún será posible recuperar la datos. Si cierra la base de datos o se bloquea inesperadamente, el registro de confirmación puede garantizar que no se pierdan los datos. Esto se debe a que la próxima vez que inicie el nodo, el commit logs se volverá a reproducir. De hecho, esa es la única vez que se lee el registro de confirmación; los clientes nunca leen.

Después de que se escriba en el commit logs, el valor se escribe en una estructura de datos residente en la memoria llamada memtable. Cada memtable contiene datos para una tabla específica. En las primeras implementaciones de Cassandra, las memtables se almacenaban en el heap de JVM, pero las mejoras a partir de la versión 2.1 han trasladado la mayoría de los datos memtables a la memoria nativa. Esto hace que Cassandra sea menos susceptible a las fluctuaciones en el rendimiento debido a la recolección de basura de Java.

Cuando el número de objetos almacenados en la memtable alcanza un umbral, el contenido de la memtable se vacía en el disco en un archivo llamado SSTable. Entonces se crea una nueva memtable. Este lavado es una operación sin bloqueo; pueden existir múltiples memtables para una sola tabla, una actual y el resto a la espera de que se vacíe. Por lo general, no deberían tener que esperar mucho tiempo, ya que el nodo debería limpiarlos muy rápidamente a menos que esté sobrecargado.

Cada commit logs mantiene un indicador de bit interno para indicar si necesita vaciarse. Cuando se recibe una operación de escritura por primera vez, se escribe en el commit logs y su marca de bit se establece en 1. Solo hay una marca de bit por tabla, porque solo se escribe un commit logs en todo el servidor. Todas las escrituras en todas las tablas entrarán en el mismo commit logs, por lo que el indicador de bit indica si un commit logs en particular contiene algo que no se haya vaciado para una tabla en particular. Una vez que el memtable se ha colocado correctamente en el disco, el indicador de bit del commit logs correspondiente se establece en 0, lo que indica que el commit logs ya no tiene que mantener esos datos por motivos de durabilidad. Al igual que los archivos de registro normales, los commit logs tienen un umbral de transferencia configurable, y una vez que se alcanza este umbral de tamaño de archivo, el registro se reiniciará, llevando consigo los indicadores de bits sucios existentes.

El SSTable es un concepto tomado de Bigtable de Google. Una vez que un memtable se vacía en el disco como un SSTable, es inmutable y no puede ser cambiado por la aplicación. Luego las SSTables son compactadas, esta compactación cambia su representación en el disco y realiza el paso de "fusión" de una combinación en nuevos archivos y elimina los archivos antiguos en caso de éxito.

Desde la versión 1.0, Cassandra ha admitido la compresión de SSTables para maximizar el uso del almacenamiento disponible. Esta compresión es configurable por tabla. Cada SSTable también tiene un filtro Bloom asociado, que se utiliza como un mejorador de rendimiento adicional.

Todas las escrituras son secuenciales, esta es la razón principal por que las escrituras funcionan tan bien en Cassandra. No se requieren lecturas ni búsquedas de ningún tipo para escribir un valor a Cassandra porque todas las escrituras son operaciones de adición. Esto hace que una limitación clave en el rendimiento sea la velocidad de su disco. La compactación está destinada a amortizar la reorganización de datos, pero utiliza I/O secuencial para hacerlo. Así que el beneficio de rendimiento se obtiene mediante la división; la operación de escritura es solo un apéndice inmediato, y luego la compactación ayuda a organizar para un mejor rendimiento de lectura en el futuro.

En las lecturas, Cassandra leerá tanto SSTables como memtables para encontrar valores de datos, ya que la memtable puede contener valores que aún no se han vaciado en el disco. Los memtables son implementados por la clase org.apache.cassandra.db.Memtable.