Experiencias prácticas con ClickHouse en entornos de BI en tiempo real

ClickHouse se ha implementado como backend para sistemas de BI en tiempo real, demostrando excelente rendimiento en generación de reportes y consultas ad-hoc cuando los datos están correctamente almacenados. A continuación comparto aprendizajes clave tras su implementación con Flink y Kafka.

Integración con MySQL

ClickHouse permite acceder directamente a tablas MySQL mediante motores especializados, evitando duplicación de datos:

-- Crear base de datos enlazada
CREATE DATABASE mysql_db 
ENGINE = MySQL('servidor:3306', 'basedatos', 'usuario', 'contraseña');

Ejemplo de consulta cruzada:

SELECT ck.*, mysql.tabla.campo 
FROM tabla_clickhouse ck
JOIN mysql_db.tabla_mysql mysql ON ck.id = mysql.id_ref;

Tablas distribuidas con réplica

Implementación correcta requiere dos pasos:

  1. Tabla local replicada:
CREATE TABLE bd.tabla_nodo ON CLUSTER cluster_default
(
    id UInt32,
    fecha_evento DateTime,
    datos String
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/tabla', '{replica}')
PARTITION BY toYYYYMM(fecha_evento)
ORDER BY id;

  1. Tabla distribuida:
CREATE TABLE bd.tabla_distribuida ON CLUSTER cluster_default
AS bd.tabla_nodo
ENGINE = Distributed(cluster_default, bd, tabla_nodo, rand());

Operaciones DDL requieren sintaxis especial:

-- Actualización
ALTER TABLE bd.tabla_nodo ON CLUSTER cluster_default 
UPDATE campo = valor WHERE condición;

-- Eliminación  
ALTER TABLE bd.tabla_nodo ON CLUSTER cluster_default
DELETE WHERE condición;

Optimización de escritura

Para máximo rendimiento:

  • Buffer de 5-10 segundos
  • Lotes de 10,000+ registros
  • Evitar acutalizaciones frecuentes

Ejemplo en Flink:

dataStream
  .window(TumblingProcessingTimeWindows.of(Time.seconds(5)))  
  .process(new BatchClickHouseInserter());

Gestión de índices

Los índices secundarios requieren materialización explícita:

-- Añadir índice
ALTER TABLE bd.tabla_nodo ADD INDEX idx_campo(campo) TYPE bloom_filter GRANULARITY 3;

-- Aplicar a datos existentes
ALTER TABLE bd.tabla_nodo MATERIALIZE INDEX idx_campo;

Tipos avanzados

Manejo de estructuras JSON/Map:

CREATE TABLE bd.eventos (
    id UUID,
    atributos Map(String, String),
    metadata_json String
) ENGINE = MergeTree()
ORDER BY id;

-- Consulta de mapas
SELECT atributos['clave'] FROM eventos WHERE id = '...';

-- Extracción JSON
SELECT JSONExtractString(metadata_json, 'ruta') FROM eventos;

Mantenimiento

Optimización manual de tablas ReplacingMergeTree:

OPTIMIZE TABLE bd.tabla_nodo FINAL;

Consulta con desduplicación:

SELECT * FROM bd.tabla_distribuida
FINAL WHERE id = 12345;

Etiquetas: ClickHouse OLAP Flink Kafka MySQL

Publicado el 8-23 03:45