Ir al contenido

Blog


Cassandra Unleashed: Cómo mejoramos la eficiencia y el rendimiento de Cassandra Fleet

30 de enero de 2024

|
Semilla Zeng

Semilla Zeng

En el ámbito de las bases de datos distribuidas, Apache Cassandra destaca como un actor importante. Ofrece una combinación de escalabilidad robusta y alta disponibilidad sin comprometer el rendimiento. Sin embargo, Cassandra también tiene fama de ser difícil de ajustar en cuanto a rendimiento y por las dificultades que pueden surgir durante ese proceso. La amplia flexibilidad del sistema, aunque es un punto fuerte clave, también significa que el aprovechamiento eficaz de todas sus capacidades a menudo implica navegar por un complejo laberinto de configuraciones y compensaciones de rendimiento. Si no se gestiona con cuidado, esta complejidad puede provocar comportamientos inesperados o un rendimiento inferior al óptimo.

En esta entrada del blog, recorremos el viaje de optimización de Cassandra de DoorDash. Compartiré lo que aprendimos mientras hacíamos que nuestra flota fuera mucho más eficiente y rentable. A través del análisis de nuestros casos de uso, esperamos compartir lecciones universales que puedan resultarle útiles. Antes de sumergirnos en esos detalles, hablemos brevemente sobre los fundamentos de Cassandra y sus pros y contras como base de datos NoSQL distribuida. 

¿Qué es Apache Cassandra?

Apache Cassandra es un sistema de gestión de bases de datos NoSQL distribuido y de código abierto diseñado para manejar grandes cantidades de datos en una amplia gama de servidores básicos. Ofrece alta disponibilidad sin un único punto de fallo. Inspirado en gran medida por Amazon DynamoDB en 2007, Facebook desarrolló Cassandra para impulsar su función de búsqueda en la bandeja de entrada y más tarde lo hizo de código abierto. Desde entonces, se ha convertido en uno de los almacenes distribuidos de valores clave preferidos. 

Cassandra pros

  • Escalabilidad: Una de las características más atractivas de Cassandra es su excepcional escalabilidad. Destaca tanto en el escalado horizontal como en el vertical, lo que le permite gestionar grandes volúmenes de datos sin esfuerzo.
  • Tolerancia a fallos: Cassandra ofrece una excelente tolerancia a fallos gracias a su arquitectura distribuida. Los datos se replican en varios nodos, lo que garantiza que no haya un único punto de fallo.
  • Alta disponibilidad: Con su estrategia de replicación y su naturaleza descentralizada, Cassandra garantiza una alta disponibilidad, lo que la convierte en una opción fiable para aplicaciones críticas.
  • Flexibilidad: Cassandra admite un diseño de esquema flexible, lo que supone una gran ayuda para las aplicaciones con estructuras de datos en evolución.
  • Eficiencia de escritura: Cassandra está optimizado para un alto rendimiento de escritura, manejando grandes volúmenes de escrituras sin problemas.

Contras de Cassandra

  • Rendimiento de lectura: Mientras que Cassandra sobresale en eficiencia de escritura, su rendimiento de lectura puede ser menos impresionante, especialmente en escenarios que involucran grandes conjuntos de datos con lecturas frecuentes con altas restricciones de consistencia.
  • Modificación de datos costosa: Debido a que Cassandra es un árbol de fusión con estructura de registro donde los datos escritos son inmutables, el borrado y las actualizaciones son caros. Especialmente en el caso de los borrados, se pueden generar tombstones que afectan al rendimiento. Si su carga de trabajo es de borrado y actualización pesada, una arquitectura sólo Cassandra podría no ser la mejor opción.
  • Complejidad en la puesta a punto: El ajuste de Cassandra para obtener un rendimiento óptimo requiere un profundo conocimiento de sus mecanismos internos, lo que puede resultar complejo y llevar mucho tiempo.
  • Compromiso de consistencia: De acuerdo con el teorema CAP, Cassandra a menudo sacrifica la consistencia por la disponibilidad y la tolerancia a las particiones, lo que puede no adaptarse a todos los casos de uso.

Los matices de Cassandra

Los matices que rodean la aplicación de Cassandra se hacen evidentes cuando se sopesan sus ventajas frente a los requisitos de casos de uso específicos. Aunque su escalabilidad y fiabilidad no tienen parangón para aplicaciones de escritura intensiva, hay que tener en cuenta la naturaleza de los datos y los patrones de acceso de su proyecto. Por ejemplo, si su aplicación requiere capacidades de consulta complejas, sistemas como MongoDB podrían ser más adecuados. Por otro lado, si la coherencia es un requisito fundamental, CockroachDB podría ser la opción más adecuada.

En nuestro viaje en DoorDash, navegamos por estas áreas grises evaluando cuidadosamente nuestras necesidades y alineándolas con las capacidades de Cassandra. Nos dimos cuenta de que, aunque ningún sistema es una solución única, con un ajuste y una comprensión meticulosos, el potencial de Cassandra podía maximizarse para satisfacer e incluso superar nuestras expectativas. Las siguientes secciones profundizan en cómo abordamos el ajuste de Cassandra -mitigando sus contras y aprovechando sus ventajas- para adaptarlo eficazmente a nuestros casos de uso intensivo de datos.

Manténgase informado con las actualizaciones semanales

Suscríbase a nuestro blog de ingeniería para estar al día de los proyectos más interesantes en los que trabaja nuestro equipo.

Atrévete a mejorar

Debido al rápido crecimiento de DoorDash, nuestro uso de Cassandra se ha expandido rápidamente. A pesar de mejorar nuestra velocidad de desarrollo, este rápido crecimiento dejó un rastro de oportunidades perdidas para ajustar el rendimiento de Cassandra. En un intento de aprovechar algunas de esas oportunidades, el equipo de Almacenamiento de Infraestructura trabajó estrechamente con los equipos de producto en un esfuerzo de ajuste de meses de duración. El proyecto ha dado algunos resultados sorprendentes, entre ellos: 

  • ~35% de reducción de costes para toda la flota Cassandra 
  • Por cada dólar que gastamos, podemos procesar 59 KB de datos por segundo frente a 23 KB, lo que supone una mejora económica unitaria del 154%.
Figura 1: Número total de nodos de la flota Cassandra

En la siguiente sección, exploraremos ejemplos concretos de nuestra flota que pueden ser aplicables a otros casos de uso. 

Diseñe bien su esquema desde el principio

El paso fundamental para asegurar un cluster Cassandra optimizado es tener un esquema bien diseñado. Las decisiones de diseño tomadas a nivel de esquema tienen implicaciones de gran alcance para el rendimiento, la escalabilidad y la facilidad de mantenimiento. Un esquema mal diseñado en Cassandra puede conducir a problemas como consultas ineficientes, puntos calientes en la distribución de datos y dificultades en el escalado. A continuación se presentan algunas consideraciones clave para el diseño de un esquema Cassandra eficaz:

  • Comprender los patrones de acceso a los datos: Antes de diseñar su esquema, es crucial tener una clara comprensión de los patrones de acceso a datos de su aplicación. Cassandra está optimizado para escrituras rápidas y lecturas eficientes, pero sólo si el modelo de datos se alinea con la forma en que se accederá a los datos. Diseñe sus tablas en función de sus consultas, no al revés.
  • Uso eficaz de las claves primarias: La clave primaria en Cassandra se compone de claves de partición y columnas de clustering. La clave de partición determina la distribución de los datos en el clúster, por lo que es esencial elegir una clave de partición que garantice una distribución uniforme de los datos a la vez que soporte sus patrones de acceso primario. Las columnas de agrupación determinan el orden de clasificación dentro de una partición y pueden utilizarse para realizar consultas de rango eficientes.
  • Evite particiones grandes: Las particiones extremadamente grandes pueden ser perjudiciales para el rendimiento de Cassandra. Pueden dar lugar a problemas como largas pausas en la recolección de basura, aumento de las latencias de lectura y problemas en la compactación. Diseñe su esquema para evitar puntos calientes y garantizar una distribución más uniforme de los datos.
  • Normalización vs. desnormalización: A diferencia de los sistemas tradicionales de gestión de bases de datos relacionales, o RDBMS, Cassandra no destaca en la unión de tablas. Como resultado, la desnormalización es a menudo necesaria. Sin embargo, es un equilibrio; mientras que la desnormalización puede simplificar las consultas y mejorar el rendimiento, también puede conducir a la redundancia de datos y mayores requisitos de almacenamiento. Considere cuidadosamente su caso de uso cuando decida cuánto desnormalizar.
  • Considere las implicaciones de los índices secundarios: Los índices secundarios en Cassandra pueden ser útiles pero tienen sus desventajas. Pueden añadir sobrecarga y puede que no siempre sean eficientes, especialmente si las columnas indexadas tienen una alta cardinalidad o si los patrones de consulta no aprovechan los puntos fuertes de los índices secundarios.
  • TTL y gestión de tombstones: Time-to-live, o TTL, es una potente característica de Cassandra para gestionar la caducidad de los datos. Sin embargo, es importante entender cómo el TTL y los tombstones resultantes afectan al rendimiento. Un manejo inadecuado de los tombstones puede llevar a una degradación del rendimiento con el tiempo. Si es posible, evite los borrados.
  • Estrategias de actualización: Entender cómo funcionan las actualizaciones en Cassandra. Dado que las actualizaciones son esencialmente operaciones de escritura, pueden dar lugar a la creación de múltiples versiones de una fila que deben resolverse en tiempo de lectura, lo que afecta al rendimiento. Diseñe sus patrones de actualización para minimizar estos impactos. Si es posible, evite las actualizaciones.

Elija bien su nivel de coherencia

La capacidad de Cassandra para configurar los niveles de consistencia para las operaciones de lectura y escritura ofrece una poderosa herramienta para equilibrar entre la precisión de los datos y el rendimiento. Sin embargo, como con cualquier característica poderosa, viene con una advertencia: Responsabilidad. El nivel de consistencia elegido puede tener un impacto significativo en el rendimiento, la disponibilidad y la tolerancia a fallos de su clúster Cassandra, incluyendo las siguientes áreas:

  • Entender los niveles de consistencia: En Cassandra, los niveles de consistencia van desde UNO (donde la operación requiere confirmación de un único nodo) hasta TODOS (donde la operación necesita confirmación de todas las réplicas del cluster). También hay niveles como QUORUM (que requiere la mayoría de los nodos) y LOCAL_QUORUM (una mayoría dentro del centro de datos local). Cada uno de estos niveles tiene sus propias implicaciones sobre el rendimiento y la precisión de los datos. Puede obtener más información sobre estos niveles en las configuraciones aquí
  • Compromiso entre rendimiento y precisión: Los niveles de consistencia más bajos, como ONE, pueden ofrecer un mayor rendimiento porque requieren menos nodos para responder. Sin embargo, también conllevan un mayor riesgo de incoherencia de los datos. Los niveles más altos, como TODOS, garantizan una gran coherencia, pero pueden afectar significativamente al rendimiento y la disponibilidad, especialmente en una configuración con varios centros de datos.
  • Impacto en la disponibilidad y la tolerancia a fallos: Los niveles de consistencia más altos también pueden afectar a la disponibilidad de tu aplicación. Por ejemplo, si utilizas un nivel de consistencia de TODOS, y una sola réplica se cae, la operación fallará. Por lo tanto, es importante equilibrar la necesidad de consistencia con el potencial de fallos de nodo y problemas de red.
  • Ajuste dinámico basado en el caso de uso: Una estrategia consiste en ajustar dinámicamente los niveles de coherencia en función de la criticidad de la operación o del estado actual del clúster. Este enfoque requiere una lógica de aplicación más sofisticada, pero puede optimizar tanto el rendimiento como la precisión de los datos.

Ajuste su estrategia de compactación (y filtro bloom)

La compactación es un proceso de mantenimiento en Cassandra que fusiona múltiples SSTables, o tablas de cadenas ordenadas, en una sola. La compactación se realiza para recuperar espacio, mejorar el rendimiento de lectura, limpiar lápidas y optimizar la E/S de disco.

Los usuarios deben elegir entre tres estrategias principales para activar la compactación en los usuarios de Cassandra en función de sus casos de uso. Cada estrategia está optimizada para cosas diferentes: 

  1. Estrategia de compactación por niveles de tamaño (STCS)
    • Mecanismo de disparo:
      • La estrategia controla el tamaño de las SSTables. Cuando un determinado número alcanza aproximadamente el mismo tamaño, se activa el proceso de compactación para esas SSTables. Por ejemplo, si el sistema tiene un umbral fijado en cuatro, cuando cuatro SSTables alcancen un tamaño similar se fusionarán en una sola durante el proceso de compactación.
    • Cuándo utilizarlo:
      • Cargas de trabajo intensivas en escritura
      • Tamaños coherentes de SSTable
    • Pros:
      • Amplificación de escritura reducida
      • Buena redacción
    • Contras:
      • Posible disminución del rendimiento de lectura debido al aumento de las exploraciones de SSTable.
      • Fusiona datos antiguos y nuevos a lo largo del tiempo
      • Debe dejar un disco de reserva mucho mayor para ejecutar eficazmente esta estrategia de compactación
  2. Estrategia de compactación nivelada, o LCS
    • Mecanismo de disparo:
      • Los datos se organizan en niveles. El nivel 0 (L0) es especial y contiene tablas SST recién descargadas o compactadas. Cuando el número de SSTables en L0 supera un umbral específico (por ejemplo, 10 SSTables), estas SSTables se compactan con las SSTables del Nivel 1 (L1). Cuando L1 supera su límite de tamaño, se compacta con L2, y así sucesivamente.
    • Cuándo utilizarlo:
      • Cargas de trabajo de lectura intensiva
      • Necesidad de un rendimiento de lectura constante
      • La gestión del espacio en disco es vital
    • Pros:
      • Rendimiento de lectura predecible gracias al menor número de SSTables
      • Utilización eficiente del espacio en disco
    • Contras:
      • Mayor amplificación de escritura
  3. Estrategia de compactación TimeWindow, o TWCS
    • Mecanismo de disparo:
      • Las SSTables se agrupan en función de la fecha y hora de los datos, creando distintas ventanas temporales, como la diaria o la horaria. Cuando una ventana temporal expira -lo que significa que hemos pasado a la siguiente ventana- las SSTables dentro de esa ventana expirada se convierten en candidatas para la compactación. Sólo se compactan juntas las SSTables dentro de la misma ventana, garantizando así la localización temporal de los datos.
    • Cuándo utilizarlo:
      • Datos de series temporales o del ciclo de vida previsible
      • Vencimientos basados en TTL
    • Pros:
      • Tratamiento eficaz de series temporales de datos
      • Reducción de la amplificación de las lecturas para las consultas con indicación de tiempo
      • SSTables mayores inmutables
    • Contras:
      • No es adecuado para cargas de trabajo no temporales
      • Posibles problemas de espacio si los datos de una ventana temporal son muy amplios y varían mucho de una ventana a otra.

En nuestra experiencia, a menos que esté almacenando estrictamente datos de series temporales con TTL predefinido, LCS debería ser su elección por defecto. Incluso cuando su aplicación es de escritura intensiva, el espacio extra en disco requerido por SSTables progresivamente grandes bajo STCS hace que esta estrategia no sea atractiva. En los casos de uso intensivo de lectura, LCS es una opción obvia. La figura 2 muestra la reducción del uso de disco tras cambiar la estrategia de compactación y las limpiezas.

Figura 2: Descenso de la utilización del disco tras ajustar la estrategia de compactación

Es fácil olvidar que cada estrategia de compactación debe tener un tamaño de caché de filtro bloom diferente. Cuando cambies entre estrategias de compactación, no olvides ajustar este tamaño de caché en consecuencia. 

  • Configuración por defecto del filtro de floración STCS: La configuración predeterminada de STCS suele buscar un equilibrio entre el uso de memoria y el rendimiento de lectura. Debido a que STCS puede conducir a SSTables más grandes, el filtro bloom podría configurarse como ligeramente más grande de lo que se utilizaría en LCS para reducir la posibilidad de lecturas innecesarias en disco. Sin embargo, el tamaño exacto dependerá de la configuración de Cassandra y de la carga de trabajo específica.
  • Configuración por defecto del filtro bloom LCS: Los filtros bloom de LCS suelen ser más pequeños porque las SSTables se gestionan en niveles y cada nivel contiene datos que no se solapan. Esta organización reduce la necesidad de filtros de floración más grandes, ya que es menos probable que se realicen lecturas de disco innecesarias.
  • Configuración por defecto del filtro bloom TWCS: Utilizado principalmente para datos de series temporales, TWCS suele implicar SSTables de vida más corta debido a la naturaleza de la caducidad de los datos basada en el tiempo. El tamaño predeterminado del filtro de floración para TWCS podría ajustarse para reflejar la naturaleza temporal de los datos; es potencialmente más pequeño debido al envejecimiento predecible de las SSTables.

Como ejemplo concreto, cambiamos uno de nuestros clústeres de Cassandra que se ejecuta en 3.11 de STCS a LCS, como se muestra en la Figura 3 a continuación. Sin embargo, no aumentamos el tamaño de la caché del filtro de floración en consecuencia. Como resultado, los nodos de ese clúster se quedaban constantemente sin memoria, o OOM, debido al aumento de la tasa de falsos positivos en las lecturas. Tras aumentar bloom_filter_fp_chance de 0,01 a 0,1, se ahorra mucha más memoria del sistema operativo, lo que elimina el problema de OOM. 

Figura 3: Ajuste de Bloom_filter_fp_chance para eliminar OOM

¿Lotear o no lotear? Es una pregunta difícil

En las bases de datos relacionales tradicionales, las operaciones por lotes son una técnica común para mejorar el rendimiento, ya que puede reducir los viajes de ida y vuelta de la red y agilizar la gestión de transacciones. Sin embargo, cuando se trabaja con una base de datos distribuida como Cassandra, el enfoque por lotes, ya sea para lecturas o escrituras, requiere una consideración cuidadosa debido a su arquitectura única y métodos de distribución de datos.

Escrituras por lotes: Las compensaciones

Cassandra, optimizado para un alto rendimiento de escritura, gestiona las operaciones de escritura individuales de manera eficiente a través de sus nodos distribuidos. Pero las escrituras por lotes, en lugar de mejorar el rendimiento, pueden introducir varios retos, como:

  • Aumento de la carga en los nodos coordinadores: Los grandes lotes pueden crear cuellos de botella en el nodo coordinador, encargado de gestionar la distribución de estas operaciones de escritura.
  • Amplificación de la escritura: El batching puede provocar que se escriban en disco más datos de los necesarios, sobrecargando el subsistema de E/S.
  • Posibilidad de latencia y fallos: Las grandes operaciones por lotes podrían superar los umbrales de tiempo de espera, lo que provocaría escrituras parciales o la necesidad de reintentos.

Teniendo en cuenta estos factores, a menudo consideramos más eficaces los lotes más pequeños y frecuentes o las escrituras individuales, que garantizan una distribución más equilibrada de la carga y un rendimiento constante.

Lecturas por lotes: Una perspectiva diferente

Las lecturas por lotes en Cassandra, u operaciones multiobtención, implican la obtención de datos de múltiples filas o particiones. Aunque aparentemente eficiente, este enfoque viene con su propio conjunto de complicaciones:

  • Sobrecarga del coordinador y de la red: El nodo coordinador debe realizar consultas en varios nodos, lo que puede aumentar el tiempo de respuesta.
  • Impacto en particiones grandes: Las grandes lecturas por lotes pueden provocar problemas de rendimiento, especialmente en particiones grandes.
  • Localidad y distribución de datos: La distribución por lotes puede alterar la localidad de los datos, un factor clave en el rendimiento de Cassandra, provocando operaciones más lentas.
  • Riesgo de puntos calientes: Las lecturas por lotes distribuidas de forma desigual pueden crear puntos calientes, lo que afecta al equilibrio de carga en todo el clúster.

Para mitigar estos problemas, puede ser más beneficioso trabajar con operaciones de lectura específicas que se alineen con los puntos fuertes de Cassandra en el manejo de datos distribuidos.

En nuestro viaje en DoorDash, hemos aprendido que la dosificación en Cassandra no sigue la sabiduría convencional de los sistemas RDBMS tradicionales. Ya sea para lecturas o escrituras, cada operación por lotes debe ser cuidadosamente evaluada en el contexto de la naturaleza distribuida de Cassandra y las características de manejo de datos. De este modo, hemos conseguido optimizar nuestro uso de Cassandra, logrando un equilibrio entre rendimiento, fiabilidad y eficiencia de recursos.

DataCenter no sirve para aislar consultas

Cassandra utiliza centros de datos, o DCs, para soportar la disponibilidad multi-región, una característica que es crítica para asegurar una alta disponibilidad y recuperación de desastres. Sin embargo, hay un error común en relación con el uso de DCs en Cassandra, especialmente entre aquellos que están en transición desde los sistemas RDBMS tradicionales. Puede parecer intuitivo tratar un DC como una réplica de lectura, de forma similar a como se utilizan las réplicas de lectura en RDBMS para el equilibrio de carga y la descarga de consultas. Pero en Cassandra, este enfoque requiere una cuidadosa consideración.

Cada DC en Cassandra puede participar en la replicación de datos; esta replicación es vital para la resistencia general del sistema. Aunque es posible designar un DC para cargas de trabajo de lectura intensiva, como hemos hecho en DoorDash con nuestro DC de solo lectura, esta decisión no está exenta de contrapartidas.

Un aspecto crítico que hay que entender es el concepto de contrapresión. En nuestra configuración, el CC de sólo lectura sólo se utiliza para operaciones de lectura. Sin embargo, esto no aísla completamente el CC principal de la carga. Cuando el DC de sólo lectura experimenta una carga elevada u otros problemas, puede crear una contrapresión que afecte al DC principal. Esto se debe a que en un cluster Cassandra todos los DCs están interconectados y participan en la salud general del cluster y en el proceso de replicación de datos.

Por ejemplo, si el DC de sólo lectura se ve desbordado por consultas pesadas o incorrectas, puede ralentizarse, lo que provoca un aumento de las latencias. Estos retrasos pueden repercutir en el centro de distribución principal, ya que espera los acuses de recibo o intenta gestionar la coherencia de la replicación en todos los centros de distribución. Estas situaciones pueden provocar una reducción del rendimiento y un aumento de la latencia en todo el clúster, no sólo en el DC de sólo lectura.

En uno de nuestros clústeres de Cassandra, utilizábamos su DC de sólo lectura para alojar costosas consultas analíticas que, de hecho, tomaban una instantánea diaria de las tablas. Como tratábamos el DC de sólo lectura como algo complicado y aislado, a medida que crecía el número de tablas, las consultas eran cada vez más caras. Finalmente, el trabajo de análisis provocó que el DC de la OR se quedara bloqueado al 100% cada noche. Esto también empezó a afectar al DC principal. Trabajando con el equipo de producto, optimizamos drásticamente esos trabajos por lotes y creamos una forma mejor de tomar la instantánea. Sin entrar en demasiados detalles, utilizamos toke range para recorrer aleatoriamente el anillo y distribuir la carga entre los clústeres. La figura 4 muestra la arquitectura aproximada. 

Figura 4: Arquitectura de escaneado diario aleatorio

El resultado final fue asombroso. Se eliminó el pico de la CPU, lo que nos permitió desmantelar por completo el CC de RO. El rendimiento del CC principal también se vio notablemente beneficiado. 

Figura 5: Paseo aleatorio optimizado para RO DC

Puesta a punto GC: A veces merece la pena

Dentro de Cassandra, el ajuste de GC, o ajuste de la recolección de basura, es una tarea desafiante. Requiere un profundo conocimiento de los mecanismos de recolección de basura dentro de la máquina virtual Java, o JVM, así como la forma en que Cassandra interactúa con estos sistemas. A pesar de su complejidad, el ajuste fino del proceso de recolección de basura puede producir mejoras significativas en el rendimiento, especialmente en entornos de alto rendimiento como el nuestro en DoorDash. Estas son algunas consideraciones comunes:

  • Preferir recolecciones de generación joven más frecuentes: En la recolección de basura de JVM, los objetos se asignan primero a la generación joven, que suele ser más pequeña y se recolecta con más frecuencia. Ajustar Cassandra para que favorezca las recolecciones de generación joven más frecuentes puede ayudar a limpiar rápidamente los objetos de corta vida, reduciendo la huella de memoria total. Este enfoque a menudo implica ajustar el tamaño de la generación joven y la frecuencia de las colecciones para lograr un equilibrio entre la recuperación de memoria con prontitud y no abrumar al sistema con demasiadas pausas de GC.
  • Evite las colecciones de antigua generación: Los objetos que sobreviven a varias recopilaciones de la generación joven pasan a la generación antigua, que se recopila con menos frecuencia. Las colecciones de la generación antigua consumen más recursos y pueden provocar tiempos de pausa más largos. En una base de datos como Cassandra, donde el rendimiento consistente es clave, es crucial minimizar las colecciones old gen. Esto puede implicar no sólo ajustar los tamaños de generación joven/vieja, sino también optimizar el uso de la memoria y las estructuras de datos de Cassandra para reducir la cantidad de basura producida.
  • Ajustar el algoritmo del recolector de basura: Los distintos recolectores de basura tienen características diferentes y se adaptan a distintos tipos de cargas de trabajo. Por ejemplo, el recolector de basura G1 es a menudo una buena opción para Cassandra, ya que puede gestionar de manera eficiente grandes pilas con tiempos de pausa mínimos. Sin embargo, la elección y el ajuste del recolector de basura deben basarse en patrones de carga de trabajo específicos y en el comportamiento observado en su entorno.
  • Supervisar y ajustar en función de las métricas: Un ajuste eficaz de la GC requiere una supervisión y unos ajustes continuos. Las métricas clave a monitorizar incluyen los tiempos de pausa, la frecuencia de las recolecciones y la tasa de asignación y promoción de objetos. Herramientas como JMX, herramientas de monitorización de JVM y las propias métricas de Cassandra pueden proporcionar información valiosa sobre el comportamiento de la GC y su impacto en el rendimiento general.
  • Comprender el impacto en el rendimiento y la latencia: Cualquier ajuste de la GC debe tener en cuenta su impacto tanto en el rendimiento como en la latencia. Aunque una GC más agresiva puede reducir el consumo de memoria, también puede introducir pausas más frecuentes que afecten a la latencia. El objetivo es encontrar una configuración que ofrezca un equilibrio óptimo para su carga de trabajo específica.

En nuestra experiencia en DoorDash, hemos descubierto que el ajuste específico de la GC, aunque complejo, puede ser muy beneficioso. Mediante el análisis cuidadoso de nuestras cargas de trabajo y el ajuste iterativo de la configuración de la GC, hemos conseguido reducir los tiempos de pausa y aumentar el rendimiento y la fiabilidad generales del sistema. Sin embargo, hay que tener en cuenta que el ajuste de la GC no es una tarea puntual, sino un proceso continuo de observación, ajuste y optimización. La figura 6 muestra un ejemplo de cómo hemos ajustado nuestra GC para mejorar el rendimiento de P99. 

Figura 6: Mejora de la latencia mediante el ajuste de GC

Trabajos futuros y aplicaciones

Mientras miramos hacia el futuro en DoorDash, nuestro viaje con Apache Cassandra se profundizará y evolucionará. Una de nuestras búsquedas en curso es refinar las optimizaciones de consulta. Estamos profundizando en los matices de los tamaños de lote y evitando los antipatrones que dificultan la eficiencia.

Otro reto pendiente es el rendimiento de la captura de datos de cambios, o CDC. Nuestra configuración actual con Debezium, emparejado con Cassandra 3, adolece de limitaciones en cuanto a latencia, fiabilidad y escalabilidad. Estamos planeando una transición a Cassandra 4 y a clientes sin procesar, que ofrecen mejores capacidades de CDC. Este cambio no es sólo una actualización técnica; es un movimiento estratégico para desbloquear nuevos ámbitos de procesamiento e integración de datos en tiempo real.

La observabilidad en Cassandra es otra frontera que estamos ansiosos por conquistar. El panorama actual hace difícil discernir los entresijos del rendimiento de las consultas. Para sacar a la luz estos aspectos ocultos, nos estamos embarcando en una iniciativa para integrar nuestra propia capa proxy. Esta adición, aunque introduce un salto adicional en nuestro flujo de datos, promete una gran cantidad de información sobre la dinámica de las consultas. Se trata de un compromiso calculado, que creemos que enriquecerá nuestra comprensión y control sobre nuestras operaciones de datos.

Agradecimientos 

Esta iniciativa no sería un éxito sin la ayuda de nuestros socios, los DRI de los distintos clusters que se pusieron a punto, entre ellos:

  • Equipo de anuncios: Chao Chu, Deepak Shivaram, Michael Kniffen, Erik Zhang y Taige Zhang
  • Equipo de pedidos: Cesare Celozzi, Maggie Fang y Abhishek Sharma
  • Equipo del público: Edwin Zhang
  • Equipo de menús y datos: Yibing Shi, Jonathan Brito, Xilu Wang y Santosh Vanga

Gracias también a Levon Stepanian por ayudarnos a rastrear el ahorro de costes en AWS Infra y los honorarios de gestión de Instaclustr. Por último, gracias por el apoyo de todo el equipo de almacenamiento y de nuestros socios de Instaclustr. 

About the Author

  • Semilla Zeng

    Seed is a software engineer on Storage team in Core Infra Organization. His focus on is on databases and large distributed systems. During his spare time, he hosts a podcast interviewing founders & VCs in tech.

Trabajos relacionados

Ubicación
Toronto, ON
Departamento
Ingeniería
Ubicación
New York, NY; San Francisco, CA; Sunnyvale, CA; Los Angeles, CA; Seattle, WA
Departamento
Ingeniería
Ubicación
San Francisco, CA; Sunnyvale, CA
Departamento
Ingeniería
Ubicación
Seattle, WA; San Francisco, CA; Sunnyvale, CA
Departamento
Ingeniería
Ubicación
Seattle, WA; San Francisco, CA; Sunnyvale, CA
Departamento
Ingeniería