ClickHouse + Graphite: cómo reducir significativamente el consumo de espacio en disco

ClickHouse + Graphite: cómo reducir significativamente el consumo de espacio en disco

Saludos, habr.

Si alguien explota el sistema red de grafito y encontré un problema de rendimiento de almacenamiento susurro (IO, espacio en disco consumido), entonces la posibilidad de que ClickHouse haya sido elegido como reemplazo debería tender a una. Esta declaración implica que ya se utiliza una implementación de terceros como demonio que recibe métricas, por ejemplo escritor de carbono o ir al carbono.

ClickHouse resuelve bien los problemas descritos. Por ejemplo, después de transferir 2 TiB de datos desde Whisper, caben en 300 GiB. No me detendré en la comparación en detalle; hay muchos artículos sobre este tema. Además, hasta hace poco no todo era perfecto con nuestro almacenamiento ClickHouse.

Problemas con el espacio consumido.

A primera vista, todo debería funcionar bien. Siguiente documentación, cree una configuración para el esquema de almacenamiento de métricas (más retention), luego cree una tabla de acuerdo con la recomendación del backend seleccionado para Graphite-web: casa-click-de-carbono+clickhouse de grafito o grafoso, dependiendo de qué pila se utilice. Y... estalla la bomba de tiempo.

Para entender cuál, necesita saber cómo funcionan las inserciones y la vida futura de los datos en las tablas de motores de la familia *.Fusionarárbol ClickHouse (gráficos tomados de presentaciones Alexey Zatelepin):

  • Insertado блок datos. En nuestro caso, fueron las métricas las que llegaron.
    ClickHouse + Graphite: cómo reducir significativamente el consumo de espacio en disco
  • Cada uno de estos bloques se clasifica según la clave antes de escribirse en el disco. ORDER BYespecificado al crear la tabla.
  • Después de clasificar, кусок (part) los datos se escriben en el disco.
    ClickHouse + Graphite: cómo reducir significativamente el consumo de espacio en disco
  • El servidor monitorea en segundo plano para que no haya muchas piezas de este tipo y lanza слияния (merge, en adelante fusionar).
    ClickHouse + Graphite: cómo reducir significativamente el consumo de espacio en disco
    ClickHouse + Graphite: cómo reducir significativamente el consumo de espacio en disco
  • El servidor deja de ejecutar fusiones por sí solo tan pronto como los datos dejan de fluir activamente hacia el партицию (partition), pero puedes iniciar el proceso manualmente con el comando OPTIMIZE.
  • Si solo queda una pieza en la partición, entonces no podrá ejecutar la combinación usando el comando habitual; debe usar OPTIMIZE ... FINAL

Entonces llegan las primeras métricas. Y ocupan algo de espacio. Los eventos posteriores pueden variar un poco dependiendo de muchos factores:

  • La clave de partición puede ser muy pequeña (un día) o muy grande (varios meses).
  • La configuración de retención puede ajustarse a varios umbrales de agregación de datos importantes dentro de la partición activa (donde se registran las métricas), o tal vez no.
  • Si hay muchos datos, entonces los primeros fragmentos, que debido a la fusión en segundo plano pueden ser ya enormes (si elige una clave de partición no óptima), no se fusionarán con fragmentos pequeños nuevos.

Y siempre termina igual. El espacio que ocupan las métricas en ClickHouse solo aumenta si:

  • no apliques OPTIMIZE ... FINAL manualmente o
  • no inserte datos en todas las particiones de forma continua, de modo que tarde o temprano comenzará una fusión en segundo plano

El segundo método parece ser el más fácil de implementar y, por lo tanto, es incorrecto y se probó primero.
Escribí un script en Python bastante simple que enviaba métricas ficticias para todos los días durante los últimos 4 años y ejecutaba cron cada hora.
Dado que todo el funcionamiento de ClickHouse DBMS se basa en el hecho de que este sistema tarde o temprano hará todo el trabajo en segundo plano, pero no se sabe cuándo, no pude esperar el momento en que las viejas y enormes piezas se dignen comenzar a fusionarse. nuevos pequeños. Quedó claro que necesitábamos buscar una forma de automatizar las optimizaciones forzadas.

ClickHouse + Graphite: cómo reducir significativamente el consumo de espacio en disco

Información en tablas del sistema ClickHouse

Echemos un vistazo a la estructura de la tabla. piezas.del.sistema. Esta es información completa sobre cada parte de todas las tablas en el servidor ClickHouse. Contiene, entre otras cosas, las siguientes columnas:

  • nombre de la base de datos (database);
  • nombre de la tabla (table);
  • nombre e ID de la partición (partition & partition_id);
  • cuando se creó la pieza (modification_time);
  • fecha mínima y máxima en una pieza (la partición se realiza por día) (min_date & max_date);

También hay una mesa sistema.grafito_retenciones, con los siguientes campos interesantes:

  • nombre de la base de datos (Tables.database);
  • nombre de la tabla (Tables.table);
  • edad de la métrica en la que se debe aplicar la siguiente agregación (age);

Por lo tanto:

  1. Tenemos una tabla de fragmentos y una tabla de reglas de agregación.
  2. Combinamos su intersección y obtenemos todas las tablas *GraphiteMergeTree.
  3. Buscamos todas las particiones en las que:
    • más de una pieza
    • o ha llegado el momento de aplicar la siguiente regla de agregación, y modification_time más viejo que este momento.

implementación

Esta petición

SELECT
    concat(p.database, '.', p.table) AS table,
    p.partition_id AS partition_id,
    p.partition AS partition,
    -- Самое "старое" правило, которое может быть применено для
    -- партиции, но не в будущем, см (*)
    max(g.age) AS age,
    -- Количество кусков в партиции
    countDistinct(p.name) AS parts,
    -- За самую старшую метрику в партиции принимается 00:00:00 следующего дня
    toDateTime(max(p.max_date + 1)) AS max_time,
    -- Когда партиция должна быть оптимизированна
    max_time + age AS rollup_time,
    -- Когда самый старый кусок в партиции был обновлён
    min(p.modification_time) AS modified_at
FROM system.parts AS p
INNER JOIN
(
    -- Все правила для всех таблиц *GraphiteMergeTree
    SELECT
        Tables.database AS database,
        Tables.table AS table,
        age
    FROM system.graphite_retentions
    ARRAY JOIN Tables
    GROUP BY
        database,
        table,
        age
) AS g ON
    (p.table = g.table)
    AND (p.database = g.database)
WHERE
    -- Только активные куски
    p.active
    -- (*) И только строки, где правила аггрегации уже должны быть применены
    AND ((toDateTime(p.max_date + 1) + g.age) < now())
GROUP BY
    table,
    partition
HAVING
    -- Только партиции, которые младше момента оптимизации
    (modified_at < rollup_time)
    -- Или с несколькими кусками
    OR (parts > 1)
ORDER BY
    table ASC,
    partition ASC,
    age ASC

devuelve cada una de las particiones de la tabla *GraphiteMergeTree cuya fusión debería liberar espacio en disco. Lo único que queda por hacer es revisarlos todos con una solicitud. OPTIMIZE ... FINAL. La implementación final también tiene en cuenta el hecho de que no es necesario tocar particiones con grabación activa.

Esto es exactamente lo que hace el proyecto. optimizador de canales de grafito. Antiguos colegas de Yandex.Market lo probaron en producción, el resultado del trabajo se puede ver a continuación.

ClickHouse + Graphite: cómo reducir significativamente el consumo de espacio en disco

Si ejecuta el programa en un servidor con ClickHouse, simplemente comenzará a funcionar en modo demonio. Cada hora se ejecutará una solicitud, comprobando si han aparecido nuevas particiones con más de tres días de antigüedad que se puedan optimizar.

Nuestros planes inmediatos son proporcionar al menos paquetes deb y, si es posible, también rpm.

En lugar de una conclusión

Durante los últimos 9+ meses he estado dentro de mi empresa. InnoGames Pasé mucho tiempo jugueteando en la intersección de ClickHouse y Graphite-Web. Fue una buena experiencia, que resultó en una rápida transición de Whisper a ClickHouse como almacenamiento de métricas. Espero que este artículo sea el comienzo de una serie sobre las mejoras que hemos realizado en varias partes de esta pila y lo que se hará en el futuro.

Se dedicaron varios litros de cerveza y días administrativos a desarrollar la solicitud, junto con v0diablo, por lo que quiero expresarle mi agradecimiento. Y también por revisar este artículo.

Página del proyecto en github

Fuente: habr.com

Añadir un comentario