How Coralogix cut processing times from 30 seconds to 86 milliseconds with a PostgreSQL to ScyllaDB migration. La velocidad es importante para , una plataforma de observación en la que los equipos de desarrollo confían para detectar incidentes antes de que se escalen en problemas. Coralogix utiliza un canal de análisis de transmisión en tiempo real, proporcionando capacidades de monitoreo, visualización y alerta sin requerir indexación. Coralógico Uno de los diferenciadores clave de Coralogix es un motor de consulta distribuido para consultas rápidas sobre datos mapeados de los archivos de un cliente en almacenamiento remoto. Originalmente fue diseñado como un motor de consulta sin estado en la parte superior del almacenamiento de objeto subyacente, pero la lectura de metadatos de Parquet durante la ejecución de la consulta introdujo un impacto de latencia inaceptable. Parquet La implementación metastórica original, construida sobre PostgreSQL, no fue lo suficientemente rápida como para satisfacer sus necesidades. Por lo tanto, el equipo probó una nueva implementación, esta vez con ScyllaDB en lugar de PostgreSQL. Spoiler: Funcionó. Lograron ganancias de rendimiento impresionantes, reduciendo el tiempo de procesamiento de consultas de 30 segundos a 86 milisegundos. Y sus ingenieros Dan Harris (Ingeniero Principal de Software) y Sebastian Vercruysse (Ingeniero Senior de Software) tomaron el escenario en la Cumbre de ScyllaDB para explicar cómo lo hicieron. Únete a nosotros en ScyllaDB Summit 24 para escuchar más informes de primera mano de cómo los equipos están abordando sus desafíos de base de datos más difíciles. Disney, Discord, Expedia, Supercell, Paramount y más están todos en la agenda. ScyllaDB Summit 2024 ya está en marcha! Update: Metastore Motivación y Requisitos Antes de entrar en los detalles de la implementación de metástrofes, vamos a dar un paso atrás y mirar la razón para construir una metástrofes en primer lugar. “Inicialmente diseñamos esta plataforma como un motor de consulta sin estado en la parte superior del almacenamiento de objetos subyacentes, pero rápidamente nos dimos cuenta de que el costo de leer los metadatos de Parquet durante la ejecución de la consulta es un gran porcentaje del tiempo de la consulta”, explicó Dan Harris. Proponen una solución que: Almacena los metadatos de Parquet en un formato descompuesto para una alta escalabilidad y rendimiento Utilice filtros de bloom para identificar de forma eficiente los archivos para escanear para cada consulta Utilice los registros de comisión transaccional para agregar, actualizar y reemplazar transaccionalmente los datos existentes en el almacenamiento de objetos subyacente Los requisitos clave incluyeron baja latencia, escalabilidad en términos de capacidad de lectura/escritura y escalabilidad del almacenamiento subyacente. genera 2.000 archivos de Parquet por hora (50.000 por día), un total de 15 TB por día, resultando en 20 GB de metadatos de Parquet solo . Un único cliente Por un solo día Un único cliente Por un solo día La implementación inicial de PostgreSQL “Empezamos la implementación inicial en Postgres, entendiendo en ese momento que un motor no distribuido no sería suficiente para el largo plazo”, reconoció Dan. Esa implementación original almacenaba información clave como “blocos”, representando un grupo de filas y un archivo de parquet. Esto incluye metadatos como la URL del archivo, el índice de grupo de filas y detalles mínimos sobre el archivo. Block url: s3://cgx-production-c4c-archive-data/cx/parquet/v1/team_id=555585/… …dt=2022-12-02/hr=10/0246f9e9-f0da-4723-9b64-a12346095d25.parquet Row group: 0, 1, 2 … Min timestamp Max timestamp Number of rows Total size … Para optimizar la lectura, usaron filtros de bloom para el corte eficiente de datos. Dan detalló, “Al final, queremos soportar algo como la búsqueda de texto completo. Básicamente, cuando estamos ingiriendo estos archivos en nuestro sistema, podemos construir un filtro de bloom para todos los tokens distintos que encontramos en el archivo. Luego, basado en una consulta particular, podemos usar esos filtros de bloom para raspar los datos que necesitamos para escanear.” Además, almacenaron metadatos de columna para cada archivo Parquet. Block URL Row Group Column Name Column metadata (blob) Dan explicó: “Los archivos que estamos escribiendo son bastante amplios, a veces hasta 20.000 columnas. Por lo tanto, al leer solo los metadatos que necesitamos, podemos realmente reducir la cantidad de IO necesaria en cualquier consulta dada”. Implementación de ScyllaDB A continuación, echemos un vistazo a la implementación de ScyllaDB como lo describió el compañero de equipo de Dan, Sebastian Vercruysse. Modelo de datos de bloques El modelo de bloque tuvo que ser revisado para la nueva implementación.Aquí está un ejemplo de una URL de bloque: s3://cgx-production-c4c-archive-data/cx/parquet/v1/team_id=555585/… …dt=2022-12-02/hr=10/0246f9e9-f0da-4723-9b64-a12346095d25.parquet La parte audaz es el cubo de nivel superior del cliente; dentro del cubo, los artículos se dividen por hora. Pero algunos clientes tienen muchos más archivos de Parquet que otros clientes, y querían mantener las cosas equilibradas Esto identifica de forma única un bloque dado, pero sería difícil listar todos los bloques para un día dado porque el timestamp no está en la clave ((Table url, hora))? Esto funciona porque si tienes 24 horas para consultar, puedes consultar con bastante facilidad ((Table url, hora), bloque url, grupo de fila)? Eso es lo que seleccionaron. Al agregar el bloque url y grupo de fila como claves de agrupación, pueden recuperar fácilmente un bloque específico dentro de una hora, lo que también simplifica el proceso de actualizar o eliminar bloques y grupos de fila. Bloom Filter Chunking y Modelado de Datos El siguiente desafío: cómo verificar que ciertos bits están configurados, dado que ScyllaDB no ofrece funciones fuera de la caja para eso. El equipo decidió leer los filtros de bloom y procesarlos en la aplicación. Sin embargo, recuerde que están tratando de hasta 50.000 bloques por día por cliente, cada bloque conteniendo 262 KB para la parte del filtro de bloom. Eso es un total de 12 GB – demasiado para sacar de vuelta a la aplicación para una consulta. Pero no necesitaban leer el filtro de bloom entero cada vez; solo necesitaban partes de él, dependiendo de los tokens involucrados durante la ejecución de la consulta. Para el modelo de datos, una de las opciones era utilizar como la clave primaria. Esto generaría 8192 piezas de 32 bytes por filtro de bloom, lo que resultaría en una distribución uniforme con aproximadamente 262 KB por partición. Con cada filtro de bloom en la misma partición, sería fácil insertar y borrar datos con una única consulta de lotes. Pero hay una captura que afecta la eficiencia de lectura: necesitarías conocer el ID del bloque antes de poder leer el filtro de bloom. Además, el enfoque implicaría acceder a un número sustancial de particiones; los bloques 50K significan particiones 50K. Y como señaló Sebastian, “Incluso con algo tan rápido como ScyllaDB, todavía es difícil lograr el proceso de subseconding para particiones 50K”. ((block_url, row_group), índice de pestaña) Otra opción (la que finalmente decidieron): Tenga en cuenta que esta es la misma clave de partición que la de Blocks, con un índice añadido a la clave de partición que representa el nth token requerido por el motor de consulta.Con este enfoque, escanear 5 tokens que abarcan una ventana de 24 horas resulta en 120 particiones - una mejora impresionante en comparación con la opción anterior de modelado de datos. (URL de la tabla, hora, índice de chunk), URL de bloque, grupo de líneas) Además, este enfoque ya no requiere el identificador de bloques antes de leer el filtro de floración – permitiendo lecturas más rápidas. Por supuesto, siempre hay compromisos. Aquí, debido al enfoque de filtro de floración bloqueado, tienen que dividir un único filtro de floración en 8192 particiones únicas. Esto termina afectando la velocidad de ingestión en comparación con el enfoque de partición anterior que permitió ingerir todos los pedazos de filtro de floración a la vez. Sin embargo, la capacidad de leer rápidamente un bloque dado en una hora es más importante para ellos que los escritos rápidos – por lo que decidieron que este compromiso valía la pena. Modelado de datos Woes No es de extrañar que el paso de SQL a NoSQL involucrara una buena cantidad de reformulación de la modelización de datos, incluyendo algunos ensayos y errores. Por ejemplo, Sebastian compartió, “Un día, descubrí que habíamos arruinado los timestamps min y max – y me pregunté cómo iba a arreglarlo. Pensé que quizás podría renombrar las columnas y luego de alguna manera hacer que funcione de nuevo. Pero aquí no se puede renombrar una columna si es parte de una clave de agrupamiento. Pensé que seguramente podría añadir nuevas columnas y ejecutar una consulta UPDATE para actualizar todas las filas. En última instancia, decidieron truncar la mesa y comenzar de nuevo contra escribir el código de migración.Su mejor consejo en este frente es obtenerlo bien la primera vez. 🙂 Ganancias de rendimiento A pesar del trabajo de modelado de datos requerido, la migración se pagó bien. Para la lista de bloques de metástrofes: Cada nodo actualmente maneja 4-5 TB. Actualmente están procesando alrededor de 10K escritos por segundo con la latencia de P99 consistentemente por debajo de un milisegundo. La lista de bloques resulta en alrededor de 2000 archivos de parquet en una hora; con sus filtros de floración, se procesan en menos de 20 milisegundos. Para los archivos de 50K, es menos de 500 milisegundos. Pero, para los archivos de 50K Parquet, 500 milisegundos es bueno para sus necesidades. En el procesamiento de metadatos de columna, el P50 es bastante bueno, pero hay una alta latencia de cola. Sebastian explicó: “El problema es que si tenemos archivos 50K Parquet, nuestros ejecutores están recogiendo todos estos en paralelo. Configuración de ScyllaDB Notablemente, Coralogix se movió desde el primer descubrimiento de ScyllaDB a entrar en producción con terabytes de datos en sólo 2 meses (y esto fue una migración de SQL a NoSQL que requería trabajo de modelado de datos, no una migración mucho más simple de Cassandra o DynamoDB). La implementación fue escrita en Rust en la parte superior de la Y encontraron , de , y Dado que ofrecer a sus propios clientes una alternativa de observación de bajo costo es importante para Coralogix, el equipo de Coralogix se mostró satisfecho por el rendimiento favorable del precio de su infraestructura ScyllaDB: un clúster de 3 nodos con: ScyllaDB Rust conductor Operador ScyllaDB para Kubernetes Monitorización de ScyllaDB Gerente de ScyllaDB 8 VCPU 32 GB de memoria ARM y Gravitón Volúmenes EBS (gp3) con ancho de banda de 500 MBps y 12k IOPS El uso de ARM reduce los costos, y la decisión de usar volúmenes EBS (gp3) finalmente se redujo a la disponibilidad, la flexibilidad y el rendimiento del precio. Ellos admitieron, “Esta es una decisión controvertida – pero estamos tratando de hacer que funcione y veremos cuánto tiempo podemos manejar”. Lecciones aprendidas Sus principales lecciones aprendidas aquí... La mayor diferencia en trabajar con ScyllaDB versus trabajar con Postgres es que tienes que pensar bastante cuidadosamente sobre tus tamaños de partición y partición. Keep an eye on partition sizes: Usted también tiene que pensar cuidadosamente sobre los patrones de lectura/escritura. ¿Su carga de trabajo es difícil de leer? ¿Involucra una buena combinación de lecturas y escrituras? O, ¿es predominantemente difícil de escribir? Las cargas de trabajo de Coralogix son bastante difíciles de escribir porque ingieren datos constantemente, pero necesitan priorizar las lecturas porque la latencia de lectura es la más crítica para su negocio. Think about read/write patterns: El equipo admite que se les advirtió de no usar EBS: “No escuchamos, pero probablemente deberíamos.Si está considerando usar ScyllaDB, probablemente sería una buena idea mirar a las instancias que tienen SSDs locales en lugar de tratar de usar volúmenes de EBS”. Avoid EBS: Planes para el futuro: WebAssembly UDFs con Rust En el futuro, quieren encontrar el punto medio entre escribir pedazos lo suficientemente grandes y leer datos innecesarios.Están dividiendo los pedazos en ~8.000 filas y creen que pueden dividirlos aún más en 1.000 filas, lo que podría acelerar sus inserciones. Su objetivo final es descargar aún más trabajo a ScyllaDB aprovechando Con su código Rust existente, la integración de los UDFs eliminaría la necesidad de enviar datos de vuelta a la aplicación, proporcionando flexibilidad para ajustes y mejoras potenciales. Funciones definidas por el usuario (UDFs) con WebAssembly Sebastian comparte, “Ya tenemos todo escrito en Rust. Sería muy bueno si podamos empezar a usar los UDFs para que no tengamos que enviar nada de vuelta a la aplicación. Ver el discurso técnico completo Puede ver la conversación de tecnología completa y esquiar a través de la cubierta en nuestra biblioteca de conversación de tecnología. Más sobre Cynthia Dunlop Cynthia es directora senior de estrategia de contenido en ScyllaDB. Ha estado escribiendo sobre desarrollo de software e ingeniería de calidad durante más de 20 años.