Self‑host ClickHouse: руководство по установке и настройке

Установите ClickHouse на свой сервер через Docker: пошаговое руководство, базовая настройка и оптимизация для аналитики в реальном времени.

Не указано
Алексей Кузнецов
Алексей Кузнецов
Системный администратор16 января 2026 г.

Подготовка окружения и системные настройки

Перед установкой ClickHouse необходимо подготовить систему, настроив ядро Linux для высоконагруженных задач. Основные параметры включают отключение свопа (vm.swappiness), увеличение лимита открытых файлов (fs.file-max) и настройку сетевых буферов (net.core.somaxconn). Для Ubuntu/Debian также установите базовые зависимости.

# Установка системных параметров через sysctl
sudo sysctl -w vm.swappiness=10
sudo sysctl -w fs.file-max=2097152
sudo sysctl -w net.core.somaxconn=65535

# Перманентная запись в конфиг
sudo sh -c 'echo "vm.swappiness=10" >> /etc/sysctl.conf'
sudo sh -c 'echo "fs.file-max=2097152" >> /etc/sysctl.conf'
sudo sh -c 'echo "net.core.somaxconn=65535" >> /etc/sysctl.conf'

# Установка зависимостей для Ubuntu/Debian
sudo apt update
sudo apt install -y curl gnupg ca-certificates lsb-release software-properties-common'

Способ 1: Установка через Docker (рекомендуемый для начала)

Самый простой и гибкий способ развертывания — использование Docker. Этот метод подходит как для тестирования, так и для продакшена при корректной настройке томов volumes. Сначала установите Docker, затем создайте docker-compose.yml файл с конфигурацией ClickHouse.

# Установка Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
newgrp docker

# Создание структуры директорий
mkdir -p {data,config,logs}/clickhouse

# Создание docker-compose.yml
# Содержимое файла см. в следующем шаге

Конфигурация Docker Compose для ClickHouse

Создайте файл docker-compose.yml в директории проекта. Важно пробросить порты (8123 для HTTP, 9000 для TCP) и настроить volumes для сохранения данных и логов. Также установим ограничения ulimits для корректной работы под высокой нагрузкой.

version: '3.8'

services:
  clickhouse:
    image: clickhouse/clickhouse-server:23.8
    container_name: clickhouse-server
    restart: unless-stopped
    ports:
      - "8123:8123"    # HTTP API
      - "9000:9000"    # TCP protocol
      - "9004:9004"    # MySQL protocol (опционально)
    volumes:
      - ./data/clickhouse:/var/lib/clickhouse
      - ./config/clickhouse:/etc/clickhouse-server
      - ./logs/clickhouse:/var/log/clickhouse
    ulimits:
      nofile:
        soft: 262144
        hard: 262144
    environment:
      - CLICKHOUSE_USER=default
      - CLICKHOUSE_PASSWORD=changeme
    networks:
      - clickhouse-net

networks:
  clickhouse-net:
    driver: bridge

Способ 2: Установка из официального пакета (Native)

Для продакшена на выделенном сервере или в кластере рекомендуется нативная установка. Она обеспечивает лучшую производительность и контроль над системными ресурсами. Добавьте официальный репозиторий ClickHouse и установите пакеты.

# Добавление ключа и репозитория (Ubuntu/Debian)
curl -fsSL 'https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key' | sudo gpg --dearmor -o /usr/share/keyrings/clickhouse-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/clickhouse-keyring.gpg] https://packages.clickhouse.com/rpm/lts/ main/" | sudo tee /etc/apt/sources.list.d/clickhouse.list

# Установка пакетов
sudo apt update
sudo apt install -y clickhouse-server clickhouse-client

# Запуск сервиса
sudo systemctl start clickhouse-server
sudo systemctl enable clickhouse-server

Первоначальная настройка и смена пароля

После установки необходимо изменить пароль пользователя по умолчанию и создать отдельного пользователя для аналитики. Это критически важно для безопасности. Команды выполняются через clickhouse-client.

# Подключение к ClickHouse (пароль по умолчанию может быть пустым или 'changeme')
clickhouse-client --password

# В интерфейсе SQL:
-- Смена пароля для пользователя default
ALTER USER default IDENTIFIED BY 'ваш_новый_пароль';

-- Создание пользователя для аналитики
CREATE USER analytics IDENTIFIED BY 'secure_analytics_password';

-- Выход из клиента
EXIT;

# Проверка подключения с новым паролем
clickhouse-client --user=analytics --password='secure_analytics_password' --query='SELECT 1'

Оптимизация конфигурации (config.xml)

Настройте основные параметры сервера в файле config.xml (в Docker это ./config/clickhouse/config.xml). Важно выставить ограничения по памяти, настроить пути хранения и оптимизировать работу с дисками, особенно если используется NVMe.

<yandex>
    <!-- Основные настройки портов -->
    <http_port>8123</http_port>
    <tcp_port>9000</tcp_port>

    <!-- Лимиты памяти (пример для 64ГБ RAM, ставьте ~70% от доступной) -->
    <max_memory_usage>40000000000</max_memory_usage> <!-- 40 GB -->
    <max_bytes_before_external_group_by>20000000000</max_bytes_before_external_group_by>

    <!-- Пути хранения -->
    <path>/var/lib/clickhouse/</path>
    <tmp_path>/var/lib/clickhouse/tmp/</tmp_path>

    <!-- Оптимизация для SSD -->
    <storage_configuration>
        <disks>
            <ssd>
                <path>/mnt/ssd/clickhouse/</path>
            </ssd>
        </disks>
        <policies>
            <ssd_optimized>
                <volumes>
                    <ssd_volume>
                        <disk>ssd</disk>
                    </ssd_volume>
                </volumes>
            </ssd_optimized>
        </policies>
    </storage_configuration>
</yandex>

Настройка безопасности (users.xml)

Конфигурируйте доступ в файле users.xml (в Docker ./config/clickhouse/users.xml). Ограничьте доступ по IP-адресам и настройте профили пользователей. Настоятельно рекомендуется использовать отдельных пользователей вместо default.

<yandex>
    <users>
        <!-- Пользователь для BI-систем (только чтение) -->
        <analytics>
            <password>analytics_password</password>
            <networks>
                <ip>10.0.0.0/8</ip> <!-- Доступ только из внутренней сети -->
            </networks>
            <profile>readonly</profile>
            <quota>readonly</quota>
        </analytics>
    </users>

    <profiles>
        <readonly>
            <readonly>1</readonly>
            <max_memory_usage>10000000000</max_memory_usage>
        </readonly>
    </profiles>
</yandex>

Создание таблицы для аналитики

Создадим таблицу для хранения логов событий. Используем движок MergeTree для высокой производительности, партиционирование по дате и TTL для автоматического удаления старых данных.

CREATE TABLE analytics.system_logs (
    timestamp DateTime DEFAULT now(),
    level Enum8('DEBUG' = 1, 'INFO' = 2, 'WARN' = 3, 'ERROR' = 4),
    service String,
    message String,
    hostname String DEFAULT hostName(),
    event_date Date MATERIALIZED toDate(timestamp)
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, level, service)
TTL event_date + INTERVAL 90 DAY
SETTINGS index_granularity = 8192;

Вставка данных и выполнение запросов

Пример вставки тестовых данных и выполнения аналитического запроса. ClickHouse позволяет выполнять сложные агрегации на лету благодаря столбчатой архитектуре.

-- Вставка данных
INSERT INTO analytics.system_logs (timestamp, level, service, message, application)
VALUES
    (now(), 'INFO', 'api-service', 'Request processed', 'web-api'),
    (now(), 'ERROR', 'db-service', 'Connection timeout', 'database');

-- Аналитический запрос: Ошибки по сервисам за последний час
SELECT
    service,
    count() as error_count,
    uniq(hostname) as affected_hosts
FROM analytics.system_logs
WHERE timestamp >= now() - INTERVAL 1 HOUR
    AND level = 'ERROR'
GROUP BY service
ORDER BY error_count DESC;

Мониторинг и резервное копирование

Настройте регулярные бэкапы с помощью cron и используйте системные таблицы ClickHouse для мониторинга состояния базы данных.

# Просмотр активных процессов и использования памяти (через clickhouse-client)
clickhouse-client --query="SELECT user, elapsed, memory_usage, query FROM system.processes WHERE query_id != '' FORMAT Vertical"

# Пример скрипта резервного копирования (backup.sh)
#!/bin/bash
BACKUP_DIR="/mnt/backup/clickhouse"
DATE=$(date +%Y%m%d_%H%M%S)
# Создание бэкапа всей базы
clickhouse-client --password="ваш_пароль" --query="BACKUP DATABASE analytics TO Disk('backups', 'backup_$DATE')"

# Добавление задачи в cron (ежедневно в 02:00)
# 0 2 * * * /path/to/backup.sh

Интеграция с BI-системами (Grafana/Metabase)

Для визуализации данных подключите ClickHouse к Grafana или Metabase. Используйте HTTP протокол (порт 8123) и создайте read-only пользователя для BI-систем.

-- Создание пользователя для Grafana
CREATE USER grafana IDENTIFIED WITH sha256_hash AS 'хеш_пароля';
GRANT SELECT ON analytics.* TO grafana;

-- Пример запроса для Grafana с переменными времени
SELECT
    toStartOfInterval(timestamp, INTERVAL 5 MINUTE) as time,
    count() as value,
    level as metric
FROM analytics.system_logs
WHERE timestamp >= $__timeFrom() AND timestamp <= $__timeTo()
GROUP BY time, level
ORDER BY time

Как self-host ClickHouse для аналитики в реальном времени

Введение

ClickHouse — это столбчатая СУБД с открытым исходным кодом, созданная Яндексом для аналитики больших объемов данных в реальном времени. В мире self-hostинга (развертывания на собственном инфраструктуре) ClickHouse становится критически важным инструментом для компаний, которые требуют контроля над данными, низких задержек и гибкой настройки под конкретные нагрузки.

Если вам нужно обрабатывать миллионы событий в секунду, выполнять сложные агрегации на лету и при этом сохранять полный контроль над инфраструктурой — ClickHouse станет оптимальным выбором.

ClickHouse vs традиционные БД: Основные отличия и преимущества

Ключевые отличия

ХарактеристикаClickHouseТрадиционные СУБД (PostgreSQL, MySQL)
АрхитектураСтолбчатаяСтрочная
ОптимизацияЗапросы OLAPOLTP + OLAP (компромисс)
ПроизводительностьВысокая на чтении, низкая на записиБалансированная
Сжатие данныхАвтоматическое, высокая степеньОграниченное
ИндексыЧасти данных, полнотекстовыеB-Tree, хэш-индексы
МасштабируемостьГоризонтальная (шардирование)Вертикальная + шардирование

Преимущества ClickHouse для аналитики в реальном времени

  1. Скорость агрегаций — до 1000x быстрее традиционных БД для аналитических запросов
  2. Сжатие данных — коэффициент 3:1 или лучше по сравнению с сырыми данными
  3. Векторизованные вычисления — обработка данных пачками, а не по одному
  4. Поддержка материализованных представлений — предварительные вычисления агрегатов
  5. Нативная поддержка JSON — работа с полуструктурированными данными без нормализации

Архитектура ClickHouse: Понимание работы столбчатой БД

ClickHouse хранит данные в виде столбцов, а не строк. Это ключевая особенность, которая определяет всю архитектуру.

Основные компоненты

  1. Хранилище данных (Data Storage)

    • Данные разбиваются на части (parts)
    • Каждая часть содержит сжатые данные столбцов
    • Формат: MergeTree семейства движков
  2. Процессор запросов (Query Processing)

    • Векторизованная обработка
    • Конвейерная архитектура
    • Распределенные вычисления
  3. Управление памятью (Memory Management)

    • Ограничение для распределенных запросов (max_memory_usage)
    • Буферизация в оперативной памяти
    • Кэширование

Поток данных при запросе

Клиент → ClickHouse Server → Реплика/Шард → Партиции данных → Сжатые столбцы

Подготовка окружения: Минимальные системные требования

Минимальные требования (для тестовой среды)

  • Операционная система: Linux (Ubuntu 20.04+, CentOS 7+, Debian 10+)
  • CPU: 4 ядра (x86-64)
  • RAM: 8 ГБ (рекомендуется 16+ ГБ)
  • Диск: SSD, 50+ ГБ свободного места
  • Сетевая подключение: 1 Gbps+

Рекомендуемые требования (для продакшена)

  • Операционная система: Ubuntu 22.04 LTS / CentOS 9 Stream
  • CPU: 16+ ядер (Intel/AMD, AVX2 поддержка)
  • RAM: 64+ ГБ (20-30% больше, чем размер рабочих данных)
  • Диск: NVMe SSD, 1+ ТБ (RAID 10 или RAID 6)
  • Сетевая подключение: 10 Gbps+
  • Резервное хранилище: Отдельный диск/НВД для бэкапов

Системные настройки (обязательные)

# Установка sysctl для оптимизации
sudo sysctl -w vm.swappiness=10
sudo sysctl -w fs.file-max=2097152
sudo sysctl -w net.core.somaxconn=65535

# Установка перманентно в /etc/sysctl.conf
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf
echo "fs.file-max=2097152" | sudo tee -a /etc/sysctl.conf
echo "net.core.somaxconn=65535" | sudo tee -a /etc/sysctl.conf

Установка зависимостей (для Ubuntu/Debian)

sudo apt update
sudo apt install -y curl gnupg ca-certificates lsb-release software-properties-common

Способ 1: Установка ClickHouse через Docker (самый простой и рекомендуемый)

Docker-установка — самый простой способ для начала работы, тестирования и даже продакшена при правильной настройке.

Шаг 1: Установка Docker

# Установка Docker на Ubuntu/Debian
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Добавление пользователя в docker group (опционально)
sudo usermod -aG docker $USER
newgrp docker

# Проверка
docker --version

Шаг 2: Запуск ClickHouse через Docker Compose

Создайте файл docker-compose.yml:

version: '3.8'

services:
  clickhouse:
    image: clickhouse/clickhouse-server:23.8
    container_name: clickhouse-server
    restart: unless-stopped
    ports:
      - "8123:8123"    # HTTP API
      - "9000:9000"    # TCP protocol
      - "9004:9004"    # MySQL protocol
    volumes:
      - ./data/clickhouse:/var/lib/clickhouse
      - ./config/clickhouse:/etc/clickhouse-server
      - ./logs/clickhouse:/var/log/clickhouse
    ulimits:
      nofile:
        soft: 262144
        hard: 262144
    environment:
      - CLICKHOUSE_USER=default
      - CLICKHOUSE_PASSWORD=changeme
    networks:
      - clickhouse-net

networks:
  clickhouse-net:
    driver: bridge

Шаг 3: Запуск контейнера

# Создание директорий
mkdir -p {data,config,logs}/clickhouse

# Запуск
docker-compose up -d

# Проверка состояния
docker-compose ps

Шаг 4: Первоначальная настройка

# Подключение к контейнеру
docker exec -it clickhouse-server clickhouse-client

# Смена пароля для пользователя default
ALTER USER default IDENTIFIED BY 'новый_пароль';

# Создание нового пользователя
CREATE USER analytics IDENTIFIED BY 'secure_password';

Способ 2: Установка ClickHouse из официального пакета (для продвинутых)

Шаг 1: Добавление репозитория ClickHouse

# Ubuntu/Debian
curl -fsSL 'https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key' | sudo gpg --dearmor -o /usr/share/keyrings/clickhouse-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/clickhouse-keyring.gpg] https://packages.clickhouse.com/rpm/lts/ main/" | sudo tee /etc/apt/sources.list.d/clickhouse.list

# CentOS/RHEL
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://packages.clickhouse.com/rpm/clickhouse.repo

Шаг 2: Установка пакетов

# Ubuntu/Debian
sudo apt update
sudo apt install -y clickhouse-server clickhouse-client

# CentOS/RHEL
sudo yum install -y clickhouse-server clickhouse-client

# Проверка установки
sudo systemctl status clickhouse-server

Шаг 3: Первоначальная настройка

# Запуск сервиса
sudo systemctl start clickhouse-server
sudo systemctl enable clickhouse-server

# Генерация конфигурации по умолчанию
sudo -u clickhouse mkdir -p /etc/clickhouse-server/config.d
sudo -u clickhouse mkdir -p /etc/clickhouse-server/users.d
sudo -u clickhouse mkdir -p /etc/clickhouse-server/conf.d

# Первоначальный вход
sudo clickhouse-client --password

Шаг 4: Смена пароля по умолчанию

-- Подключение к ClickHouse
clickhouse-client --password

-- Смена пароля для пользователя default
ALTER USER default IDENTIFIED BY 'новый_пароль';

Конфигурация и оптимизация: Ключевые параметры для self-host

Основные конфигурационные файлы

  1. config.xml — глобальные настройки сервера
  2. users.xml — настройки пользователей и прав доступа
  3. macros.xml — шаблоны для шардирования и репликации
  4. replicas.xml — настройки репликации

Оптимальные настройки для production

config.xml

<!-- Основные настройки сервера -->
<yandex>
    <!-- Порт для HTTP -->
    <http_port>8123</http_port>
    
    <!-- Порт для Native TCP -->
    <tcp_port>9000</tcp_port>
    
    <!-- Порт для MySQL протокола -->
    <mysql_port>9004</mysql_port>
    
    <!-- Максимальное количество подключений -->
    <max_connections>4096</max_connections>
    
    <!-- Настройки памяти -->
    <max_memory_usage>100000000000</max_memory_usage> <!-- 100 GB -->
    <max_memory_usage_for_user>50000000000</max_memory_usage_for_user> <!-- 50 GB -->
    
    <!-- Настройки для распределенных запросов -->
    <max_bytes_before_external_group_by>50000000000</max_bytes_before_external_group_by>
    <max_bytes_before_external_sort>50000000000</max_bytes_before_external_sort>
    
    <!-- Работа с дисками -->
    <path>/var/lib/clickhouse/</path>
    <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>
    
    <!-- Настройки Zookeeper (для репликации) -->
    <!--
    <zookeeper>
        <node index="1">
            <host>zoo1</host>
            <port>2181</port>
        </node>
    </zookeeper>
    -->
    
    <!-- Настройки шардирования -->
    <!--
    <remote_servers>
        <production_cluster>
            <shard>
                <replica>
                    <host>node1</host>
                    <port>9000</port>
                </replica>
            </shard>
        </production_cluster>
    </remote_servers>
    -->
    
    <!-- Оптимизации для SSD -->
    <storage_configuration>
        <disks>
            <default>
                <path>/var/lib/clickhouse/</path>
            </default>
            <ssd>
                <path>/mnt/ssd/clickhouse/</path>
                <keep_free_space_bytes>100000000000</keep_free_space_bytes>
            </ssd>
        </disks>
        <policies>
            <default>
                <volumes>
                    <main>
                        <disk>default</disk>
                    </main>
                </volumes>
            </default>
            <hot_and_cold>
                <volumes>
                    <hot>
                        <disk>ssd</disk>
                        <max_data_part_size_bytes>1073741824</max_data_part_size_bytes>
                    </hot>
                    <cold>
                        <disk>default</disk>
                    </cold>
                </volumes>
            </hot_and_cold>
        </policies>
    </storage_configuration>
</yandex>

users.xml (настройки безопасности)

<yandex>
    <!-- Настройки пользователей -->
    <users>
        <!-- Пользователь по умолчанию -->
        <default>
            <!-- Пароль (запишите свой!) -->
            <password>secure_password_here</password>
            <networks>
                <ip>127.0.0.1</ip>
                <ip>10.0.0.0/8</ip>
                <ip>192.168.0.0/16</ip>
            </networks>
            <profile>default</profile>
            <quota>default</quota>
        </default>
        
        <!-- Аналитический пользователь -->
        <analytics>
            <password>analytics_password</password>
            <networks>
                <ip>10.0.0.0/8</ip>
            </networks>
            <profile>readonly</profile>
            <quota>readonly</quota>
            <allow_databases>
                <database>analytics</database>
            </allow_databases>
        </analytics>
    </users>
    
    <!-- Профили пользователей -->
    <profiles>
        <default>
            <max_memory_usage>10000000000</max_memory_usage>
            <max_bytes_before_external_group_by>5000000000</max_bytes_before_external_group_by>
            <allow_ddl>1</allow_ddl>
            <allow_experimental_ddl>1</allow_experimental_ddl>
        </default>
        
        <readonly>
            <readonly>1</readonly>
            <max_memory_usage>1000000000</max_memory_usage>
        </readonly>
    </profiles>
    
    <!-- Квоты -->
    <quotas>
        <default>
            <interval>
                <duration>3600</duration>
                <queries>0</queries>
                <errors>0</errors>
                <result_rows>0</result_rows>
                <read_rows>0</read_rows>
                <execution_time>0</execution_time>
            </interval>
        </default>
        
        <readonly>
            <interval>
                <duration>3600</duration>
                <queries>1000</queries>
                <errors>100</errors>
                <result_rows>1000000</result_rows>
                <read_rows>10000000</read_rows>
                <execution_time>60</execution_time>
            </interval>
        </readonly>
    </quotas>
</yandex>

Продвинутые оптимизации

Настройка для SSD/NVMe

<!-- В config.xml -->
<storage_configuration>
    <disks>
        <ssd>
            <path>/mnt/ssd/clickhouse/</path>
            <metadata_path>/var/lib/clickhouse/disks/ssd/</metadata_path>
        </ssd>
    </disks>
    <policies>
        <ssd_optimized>
            <volumes>
                <ssd_volume>
                    <disk>ssd</disk>
                    <max_data_part_size_bytes>1073741824</max_data_part_size_bytes>
                </ssd_volume>
            </volumes>
            <move_factor>0.1</move_factor>
            <prefer_not_to_merge>0</prefer_not_to_merge>
        </ssd_optimized>
    </policies>
</storage_configuration>

Настройка партиционирования

-- Партиционирование по дням для логов
CREATE TABLE logs (
    timestamp DateTime,
    level String,
    message String,
    application String,
    event_date Date MATERIALIZED toDate(timestamp)
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, level)
TTL event_date + INTERVAL 30 DAY
SETTINGS index_granularity = 8192;

Базовые операции: Создание базы, таблиц и выполнение запросов

Создание базы данных

-- Создание базы данных (опционально)
CREATE DATABASE IF NOT EXISTS analytics;
USE analytics;

Создание таблицы для анализа логов

-- Пример таблицы для хранения системных логов
CREATE TABLE system_logs (
    timestamp DateTime DEFAULT now(),
    level Enum8('DEBUG' = 1, 'INFO' = 2, 'WARN' = 3, 'ERROR' = 4),
    service String,
    message String,
    hostname String DEFAULT hostName(),
    application String,
    -- Для агрегации по дате (materialized column)
    event_date Date MATERIALIZED toDate(timestamp),
    event_time DateTime MATERIALIZED toDateTime(timestamp)
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, level, service)
TTL event_date + INTERVAL 90 DAY
SETTINGS index_granularity = 8192;

Создание материализованных представлений (для предварительных вычислений)

-- Предварительный расчет агрегатов по часам
CREATE MATERIALIZED VIEW system_logs_hourly_mv
ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, event_hour, level)
POPULATE AS
SELECT
    toDate(timestamp) as event_date,
    toHour(timestamp) as event_hour,
    level,
    service,
    count() as cnt,
    min(timestamp) as min_time,
    max(timestamp) as max_time
FROM system_logs
GROUP BY event_date, event_hour, level, service;

Примеры запросов

-- Вставка данных
INSERT INTO system_logs (timestamp, level, service, message, application)
VALUES
    (now(), 'INFO', 'api-service', 'Request processed successfully', 'web-api'),
    (now(), 'ERROR', 'db-service', 'Connection timeout', 'database'),
    (now() - INTERVAL 1 HOUR, 'WARN', 'cache-service', 'Cache miss rate high', 'caching');

-- Анализ ошибок за последний день
SELECT
    level,
    service,
    count() as error_count,
    uniq(hostname) as affected_hosts
FROM system_logs
WHERE timestamp >= now() - INTERVAL 24 HOUR
    AND level = 'ERROR'
GROUP BY level, service
ORDER BY error_count DESC;

-- Тренды ошибок по часам
SELECT
    toHour(timestamp) as hour,
    level,
    count() as events
FROM system_logs
WHERE timestamp >= now() - INTERVAL 7 DAY
GROUP BY hour, level
ORDER BY hour, level;

-- Анализ производительности с квантилями
SELECT
    quantile(0.5)(latency) as p50,
    quantile(0.95)(latency) as p95,
    quantile(0.99)(latency) as p99,
    avg(latency) as avg_latency,
    count() as total_requests
FROM request_metrics
WHERE timestamp >= now() - INTERVAL 1 HOUR;

Интеграция и использование: Подключение к BI-системам

Подключение к Metabase

Через ClickHouse HTTP API

-- Создание read-only пользователя для BI
CREATE USER metabase IDENTIFIED WITH sha256_hash
AS 'your_hashed_password'
SETTINGS max_memory_usage = 1000000000;

GRANT SELECT ON analytics.* TO metabase;

Настройка в Metabase

  1. Добавление источника данных:
    • Administration → Databases → Add Database
    • Database type: ClickHouse
    • Host: your-clickhouse-server:8123
    • Database: analytics
    • Username: metabase
    • Password: ваш_пароль
    • Use a secure connection (SSL): выкл (если внутренняя сеть)

Альтернативно: через Native JDBC driver

# Скачивание драйвера
wget https://repo1.maven.org/maven2/ru/yandex/clickhouse/clickhouse-jdbc/0.3.2/clickhouse-jdbc-0.3.2.jar

Подключение к Grafana

Установка плагина ClickHouse

# В контейнере Grafana
docker exec -it grafana bash
grafana-cli plugins install vertamedia-clickhouse-datasource

# Или через конфигурацию
# plugins = vertamedia-clickhouse-datasource

Настройка в Grafana

  1. Configuration → Data Sources → Add Data Source
  2. ClickHouse:
    • URL: http://your-clickhouse:8123
    • Database: analytics
    • User: grafana (создать предварительно)
    • Password: ваш_пароль
    • Content type: JSON (для запросов JSON)

Пример запроса для Grafana

-- Использование временных переменных Grafana
SELECT
    toStartOfInterval(timestamp, INTERVAL 5 MINUTE) as time,
    count() as value,
    level as metric
FROM system_logs
WHERE timestamp >= $__timeFrom() AND timestamp <= $__timeTo()
    AND level IN ('ERROR', 'WARN')
GROUP BY time, level
ORDER BY time

Мониторинг и управление: Встроенные инструменты ClickHouse

Системные таблицы для мониторинга

-- Процессы в ClickHouse
SELECT * FROM system.processes WHERE query_id != '' FORMAT Vertical;

-- Статистика таблиц
SELECT
    database,
    table,
    sum(bytes) as total_bytes,
    sum(rows) as total_rows,
    count() as parts
FROM system.parts
WHERE active = 1
GROUP BY database, table
ORDER BY total_bytes DESC;

-- Использование памяти
SELECT
    formatReadableSize(memory_usage) as memory_usage,
    formatReadableSize(peak_memory_usage) as peak_memory_usage,
    user,
    query
FROM system.processes
WHERE query_id != ''
ORDER BY memory_usage DESC;

-- История запросов
SELECT
    query_start_time,
    query_duration_ms,
    formatReadableSize(peak_memory_usage) as peak_memory,
    query
FROM system.query_log
WHERE query_start_time >= now() - INTERVAL 24 HOUR
    AND event_date = today()
ORDER BY query_duration_ms DESC
LIMIT 10;

Prometheus + Grafana для мониторинга ClickHouse

Экспортер для ClickHouse

# Установка clickhouse-exporter
docker run -d \
  --name clickhouse-exporter \
  -p 9116:9116 \
  -e CLICKHOUSE_HOST=http://clickhouse:8123 \
  -e CLICKHOUSE_USER=exporter \
  -e CLICKHOUSE_PASSWORD=exporter_password \
  vertamedia/clickhouse-exporter:latest

Основные метрики для мониторинга

  • clickhouse_inserted_rows — вставленные строки
  • clickhouse_selected_rows — выбранные строки
  • clickhouse_memory_usage — использование памяти
  • clickhouse_queries_total — общее количество запросов
  • clickhouse_active_connections — активные соединения

Запрос для метрик

-- Сбор метрик в prometheus format
CREATE TABLE IF NOT EXISTS system.metrics
ENGINE = MergeTree()
ORDER BY (metric, value, timestamp) AS
SELECT
    metric,
    value,
    now() as timestamp
FROM system.metrics
WHERE metric IN (
    'Query',
    'InsertQuery',
    'Merge',
    'ActiveParts',
    'ReplicatedParts',
    'ZooKeeperSession',
    'ReplicatedFetch',
    'NetworkReceive',
    'NetworkSend',
    'MemoryResident',
    'MemoryVirtual',
    'MemoryShared',
    'MemoryJS'
);

Управление ClickHouse через CLI

# Подключение к ClickHouse
clickhouse-client --host=localhost --port=9000 --user=default --password

# Запуск запроса из командной строки
echo "SELECT count() FROM system_logs" | clickhouse-client --password

# Выполнение файла с запросами
clickhouse-client --password < queries.sql

# Интерактивный режим
clickhouse-client --multiline --multiline_timeout 10 --password

# Экспорт данных в CSV
clickhouse-client --query="SELECT * FROM system_logs" --format=CSV > logs.csv

# Импорт данных
clickhouse-client --query="INSERT INTO system_logs FORMAT CSV" < logs.csv

Резервное копирование и восстановление данных

Резервное копирование в ClickHouse

Ручное копирование (для небольших баз)

# Создание директории для бэкапов
mkdir -p /mnt/backup/clickhouse

# Бэкап всей базы
clickhouse-client --password --query="BACKUP DATABASE analytics TO Disk('backups', 'analytics_backup_$(date +%Y%m%d_%H%M%S)')"

# Бэкап конкретной таблицы
clickhouse-client --password --query="BACKUP TABLE analytics.system_logs TO Disk('backups', 'system_logs_backup_$(date +%Y%m%d_%H%M%S)')"

# Восстановление
clickhouse-client --password --query="RESTORE DATABASE analytics FROM Disk('backups', 'analytics_backup_20231001_120000')"

Автоматическое резервное копирование с помощью cron

Создайте скрипт /usr/local/bin/backup_clickhouse.sh:

#!/bin/bash
BACKUP_DIR="/mnt/backup/clickhouse"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30

# Создание бэкапа
clickhouse-client --password --query="BACKUP DATABASE analytics TO Disk('backups', 'analytics_backup_$DATE')" >> $BACKUP_DIR/backup.log 2>&1

# Удаление старых бэкапов
find $BACKUP_DIR -name "analytics_backup_*" -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \;

# Логирование
echo "$(date): Бэкап завершен" >> $BACKUP_DIR/backup.log

Добавьте в cron:

# Резервное копирование каждую ночь в 02:00
0 2 * * * /usr/local/bin/backup_clickhouse.sh

Резервное копирование в Docker-окружении

# Бэкап тома данных
docker run --rm -v clickhouse_data:/data -v $(pwd):/backup busybox tar czf /backup/backup_clickhouse_$(date +%Y%m%d).tar.gz /data

# Восстановление
docker run --rm -v clickhouse_data:/data -v $(pwd):/backup busybox sh -c "cd /data && tar xzf /backup/backup_clickhouse_20231001.tar.gz --strip-components=1"

Клиентские бэкапы (external backup)

Репликация для отказоустойчивости

-- Создание реплицируемой таблицы
CREATE TABLE analytics.events_replicated
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/analytics/events_replicated', '{replica}')
PARTITION BY toYYYYMMDD(timestamp)
ORDER BY (timestamp, event_id)
TTL timestamp + INTERVAL 90 DAY
SETTINGS index_granularity = 8192;

Безопасность: Аутентификация, сеть и ограничения доступа

Настройка аутентификации

Создание пользователей с разными правами

-- Администратор
CREATE USER admin IDENTIFIED BY 'super_secure_password_123';
GRANT ALL ON *.* TO admin;

-- Аналитик (только чтение)
CREATE USER analyst IDENTIFIED BY 'readonly_password';
GRANT SELECT ON analytics.* TO analyst;

-- Внешний сервис (ограниченный доступ)
CREATE USER external_service IDENTIFIED WITH sha256_hash
AS 'hashed_password';
GRANT SELECT, INSERT ON analytics.events TO external_service;
GRANT SELECT ON analytics.tables TO external_service;

Настройка сети

Ограничение подключений по IP

<!-- В users.xml -->
<networks>
    <ip>127.0.0.1</ip>
    <ip>10.0.0.0/8</ip>          <!-- Внутренняя сеть -->
    <ip>172.16.0.0/12</ip>       <!-- Docker сеть -->
    <ip>192.168.0.0/16</ip>      <!-- Локальная сеть -->
    <ip>100.64.0.0/10</ip>       <!-- Carrier-grade NAT -->
</networks>

Настройка firewall (iptables)

# Разрешить только внутреннюю сеть
iptables -A INPUT -p tcp --dport 8123 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 9000 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 8123 -j DROP
iptables -A INPUT -p tcp --dport 9000 -j DROP

Ограничения по ресурсам (Quotas)

Ограничение запросов

<!-- В users.xml -->
<quotas>
    <hourly_limit>
        <interval>
            <duration>3600</duration>
            <queries>1000</queries>
            <errors>100</errors>
            <result_rows>10000000</result_rows>
            <read_rows>100000000</read_rows>
            <execution_time>300</execution_time>
        </interval>
    </hourly_limit>
</quotas>

TLS/SSL шифрование

Генерация SSL сертификатов

# Создание самоподписанных сертификатов
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

# Создание конфигурации для ClickHouse
mkdir -p /etc/clickhouse-server/config.d
cat > /etc/clickhouse-server/config.d/ssl.xml <<EOF
<yandex>
    <openSSL>
        <server>
            <certificateFile>/etc/clickhouse-server/certs/cert.pem</certificateFile>
            <privateKeyFile>/etc/clickhouse-server/certs/key.pem</privateKeyFile>
            <dhParamsFile>/etc/clickhouse-server/certs/dhparams.pem</dhParamsFile>
            <verificationMode>none</verificationMode>
            <disableProtocols>sslv2,sslv3</disableProtocols>
            <preferServerCiphers>true</preferServerCiphers>
        </server>
    </openSSL>
</yandex>
EOF

Подключение через SSL

# Клиент SSL
clickhouse-client --secure --host=clickhouse.example.com --port=9440 --user=default --password

Примеры реальных задач: Аналитика логов, мониторинг метрик, отслеживание событий

Сценарий 1: Аналитика системных логов

Структура данных

CREATE TABLE system_logs (
    timestamp DateTime,
    level Enum8('DEBUG' = 1, 'INFO' = 2, 'WARN' = 3, 'ERROR' = 4, 'CRITICAL' = 5),
    service String,
    message String,
    hostname String,
    application String,
    correlation_id UUID DEFAULT generateUUIDv4(),
    event_date Date MATERIALIZED toDate(timestamp),
    event_time DateTime MATERIALIZED toDateTime(timestamp)
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, level, service)
TTL event_date + INTERVAL 90 DAY
SETTINGS index_granularity = 8192;

Запросы для анализа

-- Основная дашборда: Ошибки по сервисам
SELECT
    service,
    count() as error_count,
    countDistinct(hostname) as affected_hosts,
    uniqExact(correlation_id) as unique_incidents
FROM system_logs
WHERE timestamp >= now() - INTERVAL 24 HOUR
    AND level IN ('ERROR', 'CRITICAL')
GROUP BY service
ORDER BY error_count DESC;

-- Тренды ошибок по часам
SELECT
    toHour(timestamp) as hour,
    level,
    count() as events,
    avgIf(latency_ms, latency_ms > 0) as avg_latency
FROM system_logs
WHERE timestamp >= now() - INTERVAL 7 DAY
    AND level IN ('ERROR', 'WARN')
GROUP BY hour, level
ORDER BY hour, level;

-- Распределение ошибок по времени суток
SELECT
    toHour(timestamp) as hour,
    count() as error_count,
    argMax(service, timestamp) as most_frequent_service
FROM system_logs
WHERE timestamp >= now() - INTERVAL 30 DAY
    AND level = 'ERROR'
GROUP BY hour
ORDER BY hour;

Сценарий 2: Мониторинг метрик системы

Таблица метрик

CREATE TABLE metrics (
    timestamp DateTime,
    metric_name String,
    value Float64,
    tags Map(String, String),
    metric_date Date MATERIALIZED toDate(timestamp)
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(metric_date)
ORDER BY (metric_date, metric_name)
TTL metric_date + INTERVAL 365 DAY;

Агрегированные запросы

-- Расчет p95 latency для API
SELECT
    metric_name,
    quantile(0.95)(value) as p95,
    quantile(0.99)(value) as p99,
    avg(value) as avg_value,
    count() as sample_size
FROM metrics
WHERE timestamp >= now() - INTERVAL 1 HOUR
    AND metric_name = 'api_request_latency'
GROUP BY metric_name;

-- Trend analysis с seasonality
SELECT
    toStartOfInterval(timestamp, INTERVAL 5 MINUTE) as time,
    avg(value) as avg_value,
    stddevPop(value) as stddev_value,
    count() as data_points
FROM metrics
WHERE timestamp >= now() - INTERVAL 24 HOUR
    AND metric_name = 'cpu_usage_percent'
GROUP BY time
ORDER BY time;

Сценарий 3: Отслеживание событий пользователей

Структура событий

CREATE TABLE user_events (
    timestamp DateTime,
    user_id UInt64,
    event_type Enum8(
        'login' = 1,
        'logout' = 2,
        'click' = 3,
        'purchase' = 4,
        'signup' = 5
    ),
    properties String, -- JSON с доп. данными
    device_id String,
    session_id UUID,
    event_date Date MATERIALIZED toDate(timestamp)
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, user_id, event_type)
TTL event_date + INTERVAL 365 DAY;

Поведенческая аналитика

-- Воронка конверсии
WITH funnel AS (
    SELECT
        user_id,
        minIf(timestamp, event_type = 'signup') as signup_time,
        minIf(timestamp, event_type = 'purchase') as purchase_time
    FROM user_events
    WHERE timestamp >= now() - INTERVAL 7 DAY
    GROUP BY user_id
)
SELECT
    countDistinct(user_id) as total_users,
    countDistinctIf(user_id, signup_time IS NOT NULL) as signed_up,
    countDistinctIf(user_id, purchase_time IS NOT NULL) as purchased,
    (countDistinctIf(user_id, purchase_time IS NOT NULL) / 
     countDistinctIf(user_id, signup_time IS NOT NULL) * 100) as conversion_rate
FROM funnel;

-- Поведение сессий
SELECT
    session_id,
    min(timestamp) as session_start,
    max(timestamp) as session_end,
    count() as events_count,
    uniqExact(event_type) as event_types_count,
    maxIf(properties, event_type = 'click') as last_click_properties
FROM user_events
WHERE timestamp >= now() - INTERVAL 24 HOUR
GROUP BY session_id
HAVING count() > 5
ORDER BY events_count DESC
LIMIT 100;

Заключение: Лучшие практики и что делать дальше

Лучшие практики для self-host ClickHouse

  1. Мониторинг на первом месте

    • Всегда настраивайте Prometheus + Grafana для метрик ClickHouse
    • Отслеживайте ключевые метрики: active_connections, memory_usage, query_duration
    • Настройте алертинг при превышении порогов
  2. Партиционирование по времени

    • Используйте TTL для автоматического удаления старых данных
    • Правильно выбирайте гранулярность партиций (день/месяц в зависимости от объема)
    • Избегайте слишком мелких партиций (меньше 1 ГБ)
  3. Индексы и сортировка

    • Правильно выбирайте порядок в ORDER BY (от самого селективного к наименее)
    • Используйте INDEX для частых фильтров
    • Регулярно оптимизируйте партиции (OPTIMIZE TABLE)
  4. Управление памятью

    • Настройте max_memory_usage на 70-80% от доступной RAM
    • Используйте max_bytes_before_external_group_by для больших агрегаций
    • Регулярно мониторьте usage по системным таблицам
  5. Резервное копирование

    • Настраивайте регулярные бэкапы (минимум раз в сутки)
    • Тестируйте восстановление данных хотя бы раз в месяц
    • Храните бэкапы на отдельных физических устройствах
  6. Безопасность

    • Никогда не используйте default пользователя в продакшене
    • Настройте сетевые правила (firewall)
    • Используйте SSL для внешних подключений
    • Регулярно меняйте пароли

Что делать дальше

Углубление в тему

  1. Шардирование и репликация — для горизонтального масштабирования
  2. Материализованные представления — для предварительных вычислений
  3. Внешние таблицы — для работы с данными из других СУБД
  4. Кастомные форматы данных — для специфических типов событий

Интеграции

  • Kafka — для потоковой загрузки данных в ClickHouse
  • Kubernetes — для оркестрации ClickHouse в контейнерах
  • OLAP клиенты — Superset, Redash, Metabase для BI

Оптимизация производительности

  • Накопление данных — стратегия градации (hot/cold storage)
  • Materialized View для агрегатов — предварительные вычисления
  • Настройка пулов подключений — уменьшение накладных расходов

Дальнейшие шаги для изучения

  1. Официальная документация — https://clickhouse.com/docs/ru/
  2. GitHub ClickHouse — https://github.com/ClickHouse/ClickHouse
  3. Сообщество — Slack: clickhouse.slack.com, Forum: clickhouse.com
  4. Примеры конфигураций — https://github.com/ClickHouse/ClickHouse/tree/master/programs/server

Полезные команды для отладки

# Проверка конфигурации
sudo clickhouse-client --password --query="SELECT * FROM system.settings WHERE changed = 1"

# Анализ запросов
sudo clickhouse-client --password --query="SELECT query_start_time, query_duration_ms, query FROM system.query_log WHERE event_date = today() ORDER BY query_duration_ms DESC LIMIT 10 FORMAT Vertical"

# Проверка дискового пространства
sudo clickhouse-client --password --query="SELECT name, total_space, free_space FROM system.disks"

Финальный совет

Начните с Docker-версии для быстрого старта и тестирования. Переходите на нативную установку, когда будет понятна нагрузка и требования. Всегда настраивайте мониторинг с первого дня — это сэкономит часы отладки в будущем.

Поделиться:TelegramX / TwitterVK