SharedMergeTree vs ReplicatedMergeTree: El Caso de Negocio
Si ejecutas ClickHouse® a escala en tu propio hardware, estás pagando un impuesto que nunca aparece como una línea en la factura. La solución es un motor que se llama SharedMergeTree, y el argumento a su favor empieza por tu factura de almacenamiento.
Empecemos por la primera parte. ReplicatedMergeTree guarda una copia completa de tus datos en cada réplica. Con dos réplicas, lo almacenas todo dos veces. Con tres, tres veces. Una tabla que crece medio terabyte al mes suma en realidad un terabyte al mes con dos réplicas, y esa diferencia se acumula cada mes que conservas los datos.
La mayoría de los equipos con los que hablamos nunca le han puesto nombre a esto. Saben que el clúster es caro, pero no han rastreado el coste hasta el motor. Así que vamos a rastrearlo, porque en realidad son cuatro impuestos apilados uno encima de otro, y luego te enseñamos qué cambia si dejas de pagarlos.
Este es el caso de negocio, y al terminar sabrás si la alternativa, desacoplar cómputo y almacenamiento, te compensa para tu carga de trabajo. Y te quedas con una checklist que puedes guardar.
Qué es SharedMergeTree en realidad
Empieza por la idea de la que cuelga todo lo demás: el almacenamiento y el cómputo se separan.
En un despliegue clásico de ClickHouse, cada nodo es dueño de todo el dataset en disco local. El cómputo y el almacenamiento viven en la misma máquina, así que cuando quieres más de uno, te llevas más del otro lo necesites o no. SharedMergeTree rompe ese vínculo. Los datos viven una sola vez en el almacenamiento de objetos, S3 o equivalente, y los nodos de cómputo que van encima no tienen estado. Hemos escrito sobre las dos mitades: cómo los datos salen del disco local y pasan al almacenamiento de objetos, y cómo el cómputo sin estado sigue siendo rápido leyendo desde ahí.
Lo que tus ingenieros notan primero: una tabla es una tabla. Sin tabla Distributed montada encima de una tabla local con shards. Sin clave de sharding que elegir. Sin ON CLUSTER pegado a cada cambio de esquema y a cada query de lectura. Apuntas a un único endpoint, y se comporta igual haya un nodo detrás o cincuenta.
Para verlo en concreto, aquí tienes la misma tabla lógica en los dos mundos. Autoalojada, son varios objetos que tienen que ir sincronizados:
-- una tabla física por shard, replicada para durabilidad
CREATE TABLE events_local ON CLUSTER main (...)
ENGINE = ReplicatedMergeTree(...)
ORDER BY (...);
-- una tabla Distributed para repartir las queries entre los shards
CREATE TABLE events ON CLUSTER main AS events_local
ENGINE = Distributed(main, default, events_local, rand());
En almacenamiento compartido, es un solo objeto:
CREATE TABLE events (...)
ENGINE = SharedMergeTree
ORDER BY (...);
La primera versión mete la estructura de shards en tu esquema, en tu cliente y en cada migración que ejecutes. La segunda no tiene ninguna estructura de shards que se filtre.
En ObsessionDB corremos nuestra propia versión, alloy, construida contra la misma API de SharedMergeTree, así que la experiencia de desarrollo es idéntica aunque la implementación de debajo sea nuestra. Y nada de esto es raro. Separar el almacenamiento del cómputo es la forma por defecto de los sistemas de datos en la nube hoy en día. No lo inventamos nosotros, ni ClickHouse tampoco. La pregunta interesante es qué le hace a tu factura y a tus guardias.
Por qué ReplicatedMergeTree te rompe la estructura de costes
Cuatro mecanismos, y se acumulan.
El primero es con el que abríamos: pagas por los mismos datos más de una vez. Replicar significa copias, no shards. Cada réplica guarda una copia completa de los datos de los que se encarga, así que la durabilidad te cuesta un múltiplo del tamaño real de tus datos. SharedMergeTree guarda una sola copia en el almacenamiento de objetos. Cuando añades un nodo de cómputo, no estás añadiendo otra copia de los datos, estás añadiendo un lector. El número de réplicas deja de marcar la factura de almacenamiento.
El segundo es más silencioso, y es el que más hardware desperdicia. Cuando el cómputo y el almacenamiento van soldados, no puedes escalarlos por separado. Imagina que tu carga de trabajo necesita más almacenamiento pero el mismo cómputo. En un clúster replicado, añades nodos enteros igualmente, y acabas pagando por cómputo que no vas a tocar solo para guardar bytes. Y al revés también: un pico de carga de queries te obliga a provisionar máquinas cargadas de almacenamiento para lo que en realidad es un problema de cómputo. Lo oímos constantemente de equipos que se están planteando el cambio: el sobredimensionamiento que nunca eligieron. Desacoplar es la solución. El almacenamiento crece añadiendo bytes al almacenamiento de objetos. El cómputo crece añadiendo nodos sin estado. Dos mandos en vez de uno.
El tercer impuesto es operativo, y se subestima porque no se ve hasta que intentas crecer. Añadir capacidad a un clúster con shards no es apretar un botón. No hay reequilibrado automático de shards: los datos que ya están en tus shards viejos no se mueven al nuevo hasta que los mueves tú, a mano. En la práctica eso es copiar tablas grandes entre nodos, un trabajo que se mide en horas y días, hecho con cuidado para no tirar el clúster. Súmale la capa de coordinación que tienes que mantener sana y el conocimiento de los shards que se cuela en tu aplicación, y ves la foto real: un clúster replicado es un diseño genuinamente elegante que aun así necesita a varias personas para mantener vivo hasta uno pequeño. Con SharedMergeTree, añadir un nodo es una operación de metadatos. El nodo se anuncia y empieza a servir. No hay nada que copiar.
El cuarto es cómo se comportan los dos modelos bajo carga, y aquí te enseñamos nuestros propios números. En un montaje replicado clásico, doblar el throughput nos ha costado en torno a 2,3-2,5 veces los recursos, porque el overhead de coordinación y duplicación va incluido. En almacenamiento compartido, vemos más bien 1,2 veces para el mismo doblado. La diferencia es que llegamos ahí sin recopiar el dataset, y en el tiempo que tarda un nodo en arrancar en vez del que tarda un clúster en reequilibrarse.
Escalar a lo ancho no es la única palanca, además. Como el cómputo está separado del almacenamiento, puedes tener más de un pool de cómputo sobre los mismos datos, cada uno dimensionado para su tarea: uno para ingesta, uno para la API, uno para las queries analíticas pesadas. En un clúster replicado, esas cargas comparten los mismos nodos y compiten, así que el proceso batch que satura todos los cores es también el motivo de que tus dashboards se atasquen. Dale su propio pool y la ruta de serving ni se entera. Eso es la separación cómputo-cómputo, y funciona precisamente porque los datos de debajo son compartidos, no copiados.
El otro lado de la balanza
No nos fiamos de una propuesta sin ninguna pega, así que aquí va. SharedMergeTree no es gratis, y el coste cae donde la gente no lo espera.
El almacenamiento de objetos no es lento por falta de capacidad. Es lento por la latencia y por los límites de peticiones. AWS sitúa la latencia de primer byte de S3 en "unos 100-200 milisegundos", frente a los microsegundos de un disco NVMe local. Y hay un techo de cuántas veces puedes pedir: S3 te da, en palabras de AWS, al menos 3.500 peticiones PUT/COPY/POST/DELETE o 5.500 GET/HEAD por segundo por prefijo particionado de Amazon S3. Suena a mucho hasta que recuerdas que un part de ClickHouse es un directorio lleno de ficheros pequeños, y un diseño descuidado puede convertir un solo insert en miles de objetos diminutos, todos peleando por ese mismo presupuesto de peticiones. Este es el problema de ingeniería de verdad que un motor de almacenamiento compartido tiene que resolver, y por eso ninguno puede existir sin una capa de caché seria delante del almacén de objetos.
Y hay una carga de trabajo donde nada de esto compensa. Si tu dataset es pequeño, estático y cabe de sobra en un disco rápido, un solo nodo autoalojado es más rápido. En nuestras propias notas de lanzamiento decimos lo mismo: las cargas pequeñas pueden ir un pelín más lentas con almacenamiento separado que en una sola máquina con disco local. Desacoplar se gana el sueldo a escala.
Cuándo SharedMergeTree es la opción correcta
Esta es la parte que merece la pena guardar. Tira de SharedMergeTree cuando la mayoría de esto va contigo:
- Tu dataset es grande y va creciendo, y la replicación te está multiplicando el almacenamiento sin que lo notes.
- Tienes ingesta en tiempo real, serving y analítica pesada sobre los mismos datos, y se pelean por los mismos nodos.
- Tu carga es irregular o estacional, y quieres añadir cómputo sin tocar el almacenamiento.
- El downtime por resharding y estar de niñera de la capa de coordinación le cuestan horas de verdad a tu equipo.
Quédate en un solo nodo o en ReplicatedMergeTree a secas cuando:
- Tus datos son pequeños y estáticos y caben en un disco local rápido.
- Necesitas evitar por completo el retraso de latencia.
- Prefieres el control total antes que la elasticidad.
Una regla rápida: no necesitas los cuatro. Si aunque sea uno de los de arriba va contigo, estás pagando el impuesto todos los meses, y solo con eso ya merece la pena mirarte ObsessionDB en serio.
Dónde deja esto a ObsessionDB
Probablemente ya intuyes dónde nos situamos. ObsessionDB te da la arquitectura de SharedMergeTree sin el modelo de precios de ClickHouse Cloud ni su lock-in. La misma API, nuestro propio motor debajo, construido por gente que llevó ClickHouse a escala de casi un petabyte en Numia y se cansó de pagar el impuesto de la replicación en almacenamiento y en fines de semana.
No somos los únicos, y no vamos a fingir lo contrario. Nuestro argumento es más concreto: la misma arquitectura, alojada donde tú quieras, con una mejor relación entre rendimiento y lo que pagas. En un benchmark de diez mil millones de filas medimos queries un 35% más rápidas y hasta 9x mejor rendimiento por dólar que ClickHouse Cloud, y esa comparación tiene su propio artículo en vez de repetirse aquí.
Si las cuentas de almacenamiento de este artículo te suenan a tu clúster, esa es la conversación que toca tener. Hacemos evaluaciones de carga: trae tus queries reales y la forma real de tus datos, y te ponemos delante la comparativa sobre hardware.
Seguir Leyendo
Publicado originalmente en obsessionDB. Lee el artículo original aquí.
ClickHouse is a registered trademark of ClickHouse, Inc. https://clickhouse.com