Files

10 KiB
Raw Permalink Blame History

Учебный кластер ClickHouse на Docker Compose

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

🎯 Зачем это нужно

  • Быстрый старт: поднять кластер ClickHouse на ноутбуке за 5 минут
  • Практическое изучение: пощупать репликацию, шардинг, балансировку и отказоустойчивость
  • Безопасность: всё в Docker Compose, сломалось — пересобрали без риска для продакшена
  • Наглядность: прозрачная структура конфигураций для понимания принципов работы

🏗️ Архитектура стенда

Состав инфраструктуры

  • 4× ClickHouse Server (версия 25.1) — основные узлы кластера
  • 1× ZooKeeper (3.9.3) — координатор для репликации
  • 1× HAProxy (3.1.7) — балансировщик нагрузки
  • 3 типа кластерных конфигураций: 1×4, 2×2, 4×1 (шарды×реплики)

Схема кластера

🚀 Быстрый старт

Предварительные требования

  • Docker и Docker Compose
  • Минимум 4GB RAM
  • Свободные порты: 8124, 9001, 8002-8005, 9123-9126, 2182

Запуск

# Клонируем репозиторий
git clone https://github.com/dementev-dev/clickhouse-learning-cluster
cd clickhouse-learning-cluster

# Запускаем кластер
docker compose up

# Проверяем статус
docker compose ps

Проверка работоспособности

# Через HAProxy (рекомендуемый способ)
curl "http://default:123456@localhost:8124" -d "SELECT version()"

# Или через прямое подключение к узлу
curl "http://default:123456@localhost:9123" -d "SELECT version()"

🔧 Конфигурация кластера

Доступные кластерные топологии

Кластер Шарды Реплики Назначение
c1sh4rep 1 4 Максимальная отказоустойчивость
c2sh2rep 2 2 Сбалансированное решение
c4sh1rep 4 1 Максимальная производительность

Порты и доступ

Сервис HTTP Native Назначение
HAProxy 8124 9001 Балансировка (основной доступ)
click1 9123 8002 Прямой доступ для отладки
click2 9124 8003 Прямой доступ для отладки
click3 9125 8004 Прямой доступ для отладки
click4 9126 8005 Прямой доступ для отладки
ZooKeeper - 2182 Координация кластера

Аутентификация

  • Пользователь: default
  • Пароль: 123456

📊 Примеры работы с кластером

Проверка кластерной конфигурации

-- Список доступных кластеров
SHOW CLUSTERS;

-- Детальная информация о узлах
SELECT cluster, groupArray(concat(host_name,':',toString(port))) AS hosts
FROM system.clusters 
GROUP BY cluster 
ORDER BY cluster;

Создание реплицируемых таблиц

-- Создаем локальную реплицируемую таблицу на всех узлах
CREATE TABLE user_scores_local ON CLUSTER c2sh2rep (
    user_id    UInt32,
    avg_score  Float32,
    created_at DateTime
)
ENGINE = ReplicatedMergeTree(
    '/clickhouse/shard_{shard_c2sh2rep}/{database}/{table}',
    '{replica_c2sh2rep}'
)
ORDER BY (user_id);

-- Создаем Distributed таблицу для прозрачного доступа
CREATE TABLE user_scores ON CLUSTER c2sh2rep
AS user_scores_local
ENGINE = Distributed(c2sh2rep, default, user_scores_local, user_id);

Тестирование с данными

-- Генерируем тестовые данные
INSERT INTO user_scores
SELECT
    number % 10000000 + 1                                AS user_id,
    toFloat32(rand() % 50 + rand() % 50) / 10          AS avg_score,
    now() - (number * 86400 / 1000)                    AS created_at
FROM numbers(10000000);

-- Проверяем распределение данных по шардам
SELECT 
    shardNum() AS shard_id,
    count() AS rows_per_shard
FROM user_scores
GROUP BY shard_id
ORDER BY shard_id;

Мониторинг репликации

-- Состояние репликационных очередей
SELECT
  hostName() AS host,
  database,
  table,
  replica_name,
  total_replicas,
  active_replicas,
  is_leader,
  is_readonly
FROM clusterAllReplicas('c2sh2rep', 'system', 'replicas')
ORDER BY host, table;

-- Лог репликации
SELECT
  hostName() AS host,
  event_time,
  table,
  event_type,              -- NewPart / MergeParts / DownloadPart и т.д.
  part_name                -- имя парты (универсальное поле)
FROM clusterAllReplicas('c2sh2rep', 'system', 'part_log')
ORDER BY event_time DESC
LIMIT 100;

🛠️ Структура проекта

clickhouse-learning-cluster/
├── docker-compose.yml          # Основная конфигурация сервисов
├── configs/
│   ├── default_user.xml        # Настройки пользователя default
│   ├── z_config.xml           # Конфигурация кластеров и ZooKeeper
│   ├── macros_ch1.xml         # Макросы для узла click1
│   ├── macros_ch2.xml         # Макросы для узла click2
│   ├── macros_ch3.xml         # Макросы для узла click3
│   ├── macros_ch4.xml         # Макросы для узла click4
│   └── haproxy/
│       └── haproxy.cfg        # Конфигурация балансировщика
├── sql/
│   └── sample_queries.sql     # Примеры запросов для тестирования
└── data/                      # Директория для пользовательских файлов

🔍 Отладка и мониторинг

Логи сервисов

# Логи всех сервисов
docker compose logs -f

# Логи конкретного узла
docker compose logs -f click1

# Логи балансировщика
docker compose logs -f haproxy

Проверка состояния

# Статус контейнеров
docker compose ps

# Использование ресурсов
docker stats

Подключение к узлам напрямую

# ClickHouse client к первому узлу
docker exec -it clickhouse-learning-cluster-click1-1 clickhouse-client --user default --password 123456

# Или через внешний клиент
clickhouse-client --host localhost --port 8002 --user default --password 123456

⚠️ Важные особенности

Уникальность путей в ZooKeeper

Каждая реплицируемая таблица должна иметь уникальный путь в ZooKeeper. Используйте макросы:

  • {shard_c2sh2rep} — имя шарда
  • {replica_c2sh2rep} — имя реплики
  • {database}, {table} — имя базы и таблицы

Лимиты ресурсов

Настроены оптимальные ulimits для ClickHouse:

  • nofile: 262144 — файловые дескрипторы
  • nproc: 65535 — процессы/потоки

Сети

Все сервисы изолированы в сети ch_learning_net для безопасности.

🧪 Сценарии для экспериментов

Тестирование отказоустойчивости

Подразумевается, что создана Distributed таблица user_scores из примеров.

# Остановим одну реплику шарда 2
docker compose stop click3

# Прроверим чтение распределенной таблицы
curl "http://default:123456@localhost:8124" -d "SELECT count() FROM user_scores"

# Остановим вторую реплику шарда 2
docker compose stop click4

# Снова проверим чтение распределенной таблицы
curl "http://default:123456@localhost:8124" -d "SELECT count() FROM user_scores"

# Восстановим узлы узлы
docker compose start click3
docker compose start click4

Проверка балансировки

for i in {1..8}; do
  echo "Запрос $i:"
  curl -s "http://default:123456@localhost:8124" -d "SELECT hostName() AS current_node, now() AS request_time"
  echo ""
done

📚 Полезные ссылки

📝 Лицензия

MIT License — используйте свободно в учебных и коммерческих целях.

🤝 Вклад в проект

Приветствуются pull requests с улучшениями:

  • Дополнительные примеры запросов
  • Новые конфигурации кластеров
  • Улучшения документации
  • Скрипты автоматизации

📞 Поддержка

При возникновении вопросов создавайте issue в репозитории или обращайтесь к официальной документации ClickHouse.