Volver al inicio

Configuración de ClickHouse: configuración de producción de config.xml y users.xml

Guía práctica para configurar ClickHouse para un entorno de producción. Se cubren las secciones principales de config.xml: logger con rotación basada en tamaño (10 archivos de 1 GB cada uno), rutas de datos y swap, parámetros de MergeTree (min_bytes_for_wide_part, parts_to_throw_insert=300). Se muestra la estructura de users.xml para tres tipos de usuarios: analistas (readonly=1, límites de memoria y tiempo), aplicación (recursos limitados), administrador (acceso local). Configuraciones de perfil: max_memory_usage, max_execution_time, max_rows_to_read. Cuotas sobre el número de consultas y filas leídas. Compresión LZ4 (velocidad) vs ZSTD (ahorro de espacio). TLS/SSL para acceso seguro. Principio de configuración mediante config.d/ para preservar ajustes durante las actualizaciones. Lista de verificación de seguridad mínima: cambiar contraseña predeterminada, cerrar puertos mediante UFW/iptables, restringir redes en users.xml, habilitar query_log.

ClickHouse: cómo configurar la producción y no perder datos
Advertisement 728x90

Configuración de ClickHouse: Cómo configuré producción y no me pegué un tiro en el pie

La historia de un error tipográfico: 300 GB de logs y un servidor caído

Por defecto, ClickHouse escribe logs en /var/log/clickhouse-server/ y nunca los rota. Dos semanas después del lanzamiento, descubrimos que el archivo de log había crecido a 300 GB y llenado toda la partición raíz. El servidor se cayó. Los analistas no podían ejecutar SELECT, la producción se detuvo.

La documentación de ClickHouse es enorme, pero en producción realmente solo necesitas cambiar unos 20 parámetros. A continuación, mi lista de verificación de 5 años operando clústeres desde 1 nodo hasta 12.

1. config.xml: El esqueleto de una configuración de producción

La configuración principal está en /etc/clickhouse-server/config.xml. Estas son las secciones que toco en cada proyecto:

Google AdInline article slot
<clickhouse>
    <!-- Logging: añadir rotación para evitar repetir mi error -->
    <logger>
        <level>information</level>
        <log>/var/log/clickhouse-server/clickhouse-server.log</log>
        <errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
        <size>1000M</size>
        <count>10</count>
        <!-- Esto salva discos. 10 archivos de 1 GB cada uno: rotación por tamaño -->
    </logger>

    <!-- Puertos: estándar, pero los cambio en producción -->
    <tcp_port>9000</tcp_port>           <!-- Cliente nativo -->
    <http_port>8123</http_port>         <!-- API HTTP -->
    <interserver_http_port>9009</interserver_http_port>  <!-- Replicación -->
    
    <!-- Interfaces de escucha: en producción, NO pongas 0.0.0.0 sin firewall -->
    <listen_host>0.0.0.0</listen_host>  <!-- Todas las interfaces: cuidado -->
    <!-- <listen_host>::</listen_host>   IPv6 -->

Por qué recomiendo no usar 0.0.0.0 a ciegas: En producción con IP pública, tu ClickHouse será un objetivo para escaneo de puertos. Mejor usa VPN o firewalls.

2. Rutas de datos: dónde almacena ClickHouse todo

<path>/var/lib/clickhouse/</path>           <!-- Datos principales -->
<tmp_path>/var/lib/clickhouse/tmp/</tmp_path>
<user_files_path>/var/lib/clickhouse/user_files/</user_files_path>
<format_schema_path>/var/lib/clickhouse/format_schemas/</format_schema_path>

Lo que me quemó: El /tmp del sistema estaba montado en memoria (tmpfs) con solo 2 GB. ClickHouse intentaba escribir archivos temporales para consultas grandes con GROUP BY y se caía con un error. Moví tmp_path a un disco de 50 GB:

<tmp_path>/data/clickhouse_tmp/</tmp_path>

3. Configuración de MergeTree: previniendo desastres

Establezco estos parámetros en todos los servidores de producción:

Google AdInline article slot
<merge_tree>
    <!-- Una parte no se fusiona hasta que acumula 10 GB: reduce carga en segundo plano -->
    <min_bytes_for_wide_part>10000000000</min_bytes_for_wide_part>
    
    <!-- Tamaño máximo de parte para fusionar (100 GB) -->
    <max_bytes_to_merge_at_max_space_in_pool>107374182400</max_bytes_to_merge_at_max_space_in_pool>
    
    <!-- Si las partes superan 300, se rechazarán nuevos INSERT -->
    <parts_to_throw_insert>300</parts_to_throw_insert>
    
    <!-- Advertencia en 200 partes -->
    <parts_to_delay_insert>200</parts_to_delay_insert>
    
    <!-- Número máximo de partes en una partición -->
    <max_parts_in_total>10000</max_parts_in_total>
</merge_tree>

Por qué parts_to_throw_insert = 300: Si tienes más de 300 partes, SELECT se ralentiza, y los INSERT solo empeoran las cosas. Mejor rechazar el insert e investigar.

4. users.xml: Usuarios, perfiles, cuotas

El archivo /etc/clickhouse-server/users.xml es el control de acceso. Creo tres usuarios:

<clickhouse>
    <!-- 1. Usuario para analistas (solo lectura) -->
    <analyst>
        <password>analyst_secure_password</password>
        <networks>
            <ip>10.0.0.0/8</ip>   <!-- Solo red interna -->
        </networks>
        <profile>readonly_profile</profile>
        <quota>analyst_quota</quota>
    </analyst>

    <!-- 2. Aplicación (recursos limitados) -->
    <app_user>
        <password>${CLICKHOUSE_APP_PASSWORD}</password>  <!-- Desde variable de entorno -->
        <networks>
            <ip>::/0</ip>  <!-- Cuidado aquí, mejor usar subredes específicas -->
        </networks>
        <profile>app_profile</profile>
    </app_user>

    <!-- 3. Administrador (acceso completo) -->
    <admin>
        <password>admin_strong_password</password>
        <networks>
            <host>localhost</host>
            <host>10.0.0.50</host>  <!-- Solo host bastión -->
        </networks>
        <profile>admin_profile</profile>
    </admin>
</clickhouse>

Matiz importante: La contraseña del usuario por defecto está vacía. Es lo primero que cambio después de la instalación.

Google AdInline article slot

5. Perfiles de configuración: protección contra consultas locas

Los perfiles son conjuntos de restricciones que salvan al clúster de SELECT * FROM huge_table CROSS JOIN.

<profiles>
    <!-- Analistas: pueden ejecutar consultas pesadas pero con límites -->
    <readonly_profile>
        <readonly>1</readonly>   <!-- Solo SELECT -->
        <max_memory_usage>10000000000</max_memory_usage>  <!-- 10 GB -->
        <max_execution_time>300</max_execution_time>      <!-- 5 minutos -->
        <max_rows_to_read>50000000000</max_rows_to_read>  <!-- 50 mil millones de filas -->
        <max_bytes_to_read>107374182400</max_bytes_to_read> <!-- 100 GB -->
        <prefer_global_in_and_join>1</prefer_global_in_and_join>
    </readonly_profile>

    <!-- Aplicación: consultas rápidas, límites pequeños -->
    <app_profile>
        <readonly>0</readonly>
        <max_memory_usage>1000000000</max_memory_usage>   <!-- 1 GB -->
        <max_execution_time>10</max_execution_time>        <!-- 10 segundos -->
        <max_rows_to_read>100000000</max_rows_to_read>     <!-- 100 millones -->
        <timeout_before_checking_execution_speed>0</timeout_before_checking_execution_speed>
    </app_profile>

    <!-- Admin: casi sin límites (pero cuidado) -->
    <admin_profile>
        <readonly>0</readonly>
        <max_memory_usage>0</max_memory_usage>  <!-- sin límite -->
        <max_execution_time>0</max_execution_time>
    </admin_profile>
</profiles>

Cuotas: para que un analista no mate a todos:

<quotas>
    <analyst_quota>
        <interval>
            <duration>3600</duration>      <!-- por hora -->
            <queries>100</queries>         <!-- no más de 100 consultas -->
            <errors>0</errors>             <!-- sin errores -->
            <result_rows>100000000</result_rows>  <!-- 100 millones de filas de resultado -->
            <read_rows>10000000000</read_rows>    <!-- 10 mil millones leídas -->
        </interval>
    </analyst_quota>
</quotas>

6. Configuración de compresión por defecto

ClickHouse comprime datos con LZ4 (rápido) o ZSTD (más fuerte). Elijo según el tipo de datos:

<compression>
    <!-- LZ4 para datos recientes (velocidad) -->
    <case>
        <last_level>1</last_level>  <!-- Nivel de compresión -->
        <method>LZ4</method>
    </case>
    
    <!-- ZSTD para particiones de más de 30 días (ahorro de espacio) -->
    <case>
        <min_part_size>10737418240</min_part_size>  <!-- 10 GB -->
        <method>ZSTD</method>
        <level>3</level>
    </case>
</compression>

Mi elección en producción: LZ4 para todos los datos. ZSTD ahorra 20-30% de espacio pero pierde hasta 10% de velocidad en consultas.

7. TLS/SSL — Si no estás en una red aislada

<https_port>8443</https_port>
<tcp_port_secure>9440</tcp_port_secure>

<openSSL>
    <server>
        <certificateFile>/etc/clickhouse-server/ssl/server.crt</certificateFile>
        <privateKeyFile>/etc/clickhouse-server/ssl/server.key</privateKeyFile>
        <verificationMode>none</verificationMode>
        <caConfig>/etc/clickhouse-server/ssl/CA.pem</caConfig>
        <cacheSessions>true</cacheSessions>
        <disableProtocols>sslv2,sslv3,tlsv1,tlsv1_1</disableProtocols>
        <preferServerCiphers>true</preferServerCiphers>
    </server>
</openSSL>

Lo que me quemó: Un certificado autofirmado sin verificación solo es seguro dentro de una red de confianza. Para acceso externo, usa Let's Encrypt o un certificado de pago.

8. config.d/ — Sobrescrituras sin dolor

Nunca edites config.xml directamente. Pon todos los cambios en /etc/clickhouse-server/config.d/.

Archivo config.d/memory.xml:

<clickhouse>
    <max_server_memory_usage>0.75</max_server_memory_usage>  <!-- 75% de la RAM total -->
    <max_concurrent_queries>100</max_concurrent_queries>
</clickhouse>

Archivo config.d/networks.xml:

<clickhouse>
    <listen_host>0.0.0.0</listen_host>
    <max_connections>4096</max_connections>
</clickhouse>

Ventajas: Al actualizar ClickHouse, tu config.xml no se sobrescribirá y las sobrescrituras permanecen. Aprendí esto a las malas después de perder mi configuración durante una actualización de 22.x a 23.x.

9. Lista de verificación de seguridad para una plataforma de apuestas

Antes de abrir el acceso de ClickHouse al mundo exterior, verifico:

✅ Cambiar la contraseña del usuario por defecto

clickhouse-client --password
ALTER USER default IDENTIFIED BY 'new_strong_password';

✅ Eliminar o restringir el usuario por defecto

<!-- En users.xml, comentar la sección default -->
<!-- <default>
    <password></password>
</default> -->

✅ Cerrar puertos desde acceso externo (UFW)

sudo ufw default deny incoming
sudo ufw allow from 10.0.0.0/8 to any port 9000 proto tcp  # solo red interna
sudo ufw allow from 10.0.0.0/8 to any port 8123 proto tcp
sudo ufw allow ssh

✅ Habilitar firewall a nivel de host

sudo iptables -A INPUT -p tcp --dport 9000 -s 10.0.0.0/8 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 9000 -j DROP

✅ Establecer max_memory_usage para que una consulta no mate el servidor

<max_memory_usage>10000000000</max_memory_usage>  <!-- 10 GB -->

✅ Deshabilitar funciones experimentales (si no son necesarias)

<allow_experimental_geo_types>0</allow_experimental_geo_types>
<allow_experimental_window_functions>1</allow_experimental_window_functions> <!-- 23.8+ -->

✅ Habilitar query_log y slow_log para monitoreo

<query_log>
    <database>system</database>
    <table>query_log</table>
    <partition_by>toYYYYMM(event_date)</partition_by>
    <flush_interval_milliseconds>7500</flush_interval_milliseconds>
</query_log>

<query_thread_log>
    <database>system</database>
    <table>query_thread_log</table>
</query_thread_log>

✅ Restringir acceso por IP (lista blanca)

<analyst>
    <networks>
        <ip>10.0.0.100</ip>   <!-- Solo IP específica del analista -->
        <ip>10.0.0.101</ip>
        <ip>192.168.1.0/24</ip>
    </networks>
</analyst>

Qué sigue

Ahora tu ClickHouse está configurado para la batalla. El próximo artículo trata sobre monitoreo y copias de seguridad en producción.


Anterior: Siguiente: ReplacingMergeTree: Cómo Vencer los Duplicados en ClickHouse Sin Dolor

— Editorial Team

Advertisement 728x90

Leer después