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

Регулятор управления частотой CPU

Всегда используйте регулятор performance. Регулятор on-demand работает заметно хуже при стабильно высокой нагрузке.
$ echo 'performance' | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

Ограничения CPU

Процессоры могут перегреваться. Используйте dmesg, чтобы проверить, не была ли тактовая частота CPU ограничена из-за перегрева. Ограничение также может устанавливаться извне, на уровне датацентра. Для отслеживания этого под нагрузкой можно использовать turbostat.

Оперативная память

Для небольших объёмов данных (до ~200 ГБ в сжатом виде) лучше использовать объём памяти, сопоставимый с объёмом данных. Для больших объёмов данных и при обработке интерактивных (онлайн) запросов следует использовать достаточный объём оперативной памяти (128 ГБ или больше), чтобы горячий набор данных помещался в кэше страниц. Даже при объёме данных ~50 ТБ на сервер использование 128 ГБ оперативной памяти значительно повышает производительность запросов по сравнению с 64 ГБ. Не отключайте overcommit. Значение cat /proc/sys/vm/overcommit_memory должно быть 0 или 1. Выполните
$ echo 0 | sudo tee /proc/sys/vm/overcommit_memory
Используйте perf top, чтобы отслеживать, сколько времени ядро тратит на управление памятью. Постоянные большие страницы памяти также не нужно выделять.

Использование менее 16 ГБ оперативной памяти

Рекомендуемый объём оперативной памяти — 32 ГБ или больше. Если в вашей системе менее 16 ГБ оперативной памяти, вы можете столкнуться с различными ошибками нехватки памяти, поскольку настройки по умолчанию не рассчитаны на такой объём памяти. ClickHouse можно использовать и в системе с небольшим объёмом оперативной памяти (вплоть до 2 ГБ), но такие конфигурации требуют дополнительной настройки и поддерживают лишь низкую скорость приёма данных. При использовании ClickHouse с объёмом оперативной памяти менее 16 ГБ мы рекомендуем следующее:
  • Уменьшите размер кэша меток в config.xml. Его можно установить вплоть до 500 МБ, но не до нуля.
  • Уменьшите число потоков обработки запросов до 1.
  • Уменьшите max_block_size до 8192. Значения вплоть до 1024 тоже могут быть вполне практичными.
  • Уменьшите max_download_threads до 1.
  • Установите input_format_parallel_parsing и output_format_parallel_formatting в 0.
  • отключите запись в таблицы логов, так как из-за этого фоновая задача слияния продолжает резервировать оперативную память для выполнения слияний таблиц логов. Отключите asynchronous_metric_log, metric_log, text_log, trace_log.
Дополнительные примечания:
  • Чтобы очистить память, кэшированную аллокатором памяти, можно выполнить команду SYSTEM JEMALLOC PURGE.
  • Мы не рекомендуем использовать интеграции S3 или Kafka на машинах с небольшим объёмом оперативной памяти, поскольку для буферов им требуется значительный объём памяти.

Подсистема хранения

Если бюджет позволяет использовать SSD, используйте SSD. Если нет — HDD. Подойдут SATA HDD со скоростью 7200 об/мин. Лучше отдать предпочтение большому числу серверов с локальными жесткими дисками, чем меньшему числу серверов с подключёнными дисковыми полками. Но для хранения архивов, к которым обращаются редко, дисковые полки тоже подойдут.

RAID

При использовании HDD их можно объединить в RAID-10, RAID-5, RAID-6 или RAID-50. В Linux лучше использовать программный RAID (с mdadm). При создании RAID-10 выберите схему far. Если бюджет позволяет, выбирайте RAID-10. Сам по себе LVM (без RAID или mdadm) вполне подходит, но создание RAID с его помощью или его сочетание с mdadm — менее распространённый вариант, и вероятность ошибок выше (неправильный выбор размера фрагмента; смещение фрагментов; неправильный выбор типа RAID; забыли очистить диски). Если вы уверенно работаете с LVM, ничто не мешает использовать его. Если у вас больше 4 дисков, используйте RAID-6 (предпочтительно) или RAID-50 вместо RAID-5. При использовании RAID-5, RAID-6 или RAID-50 всегда увеличивайте stripe_cache_size, поскольку значение по умолчанию обычно не лучший вариант.
$ echo 4096 | sudo tee /sys/block/md2/md/stripe_cache_size
Рассчитайте точное значение исходя из количества устройств и размера блока, используя формулу: 2 * num_devices * chunk_size_in_bytes / 4096. Размер блока 64 КБ достаточен для большинства конфигураций RAID. Средний размер записи clickhouse-server составляет примерно 1 МБ (1024 КБ), поэтому рекомендуемый размер stripe тоже равен 1 МБ. При необходимости размер блока можно оптимизировать, установив его равным 1 МБ, делённому на количество дисков без чётности в массиве RAID, чтобы каждая запись распределялась параллельно по всем доступным дискам без чётности. Никогда не устанавливайте слишком маленький или слишком большой размер блока. На SSD можно использовать RAID-0. Независимо от использования RAID, всегда применяйте репликацию для защиты данных. Включите NCQ с длинной очередью. Для HDD выберите планировщик mq-deadline или CFQ, а для SSD — noop. Не уменьшайте значение параметра ‘readahead’. Для HDD включите кэш записи. Убедитесь, что fstrim включён для дисков NVME и SSD в вашей ОС (обычно это реализуется с помощью задания cron или сервиса systemd).

Файловая система

Ext4 — самый надёжный вариант. Укажите параметр монтирования noatime. XFS тоже хорошо подходит. Большинство других файловых систем также должны работать без проблем. FAT-32 и exFAT не поддерживаются из-за отсутствия жёстких ссылок. Не используйте файловые системы со сжатием, потому что ClickHouse сам выполняет сжатие и делает это лучше. Не рекомендуется использовать зашифрованные файловые системы, так как вместо этого можно использовать встроенное в ClickHouse шифрование, которое работает лучше. Хотя ClickHouse может работать через NFS, это не лучший вариант.

Ядро Linux

Не используйте устаревшее ядро Linux.

Сеть

Если вы используете IPv6, увеличьте размер кэша маршрутов. В ядре Linux до версии 3.2 было множество проблем с реализацией IPv6. По возможности используйте сеть со скоростью не менее 10 Гбит/с. 1 Гбит/с тоже подойдёт, но это будет значительно хуже для синхронизации реплик с десятками терабайт данных или для обработки распределённых запросов с большим объёмом промежуточных данных.

Большие страницы памяти

Всегда устанавливайте transparent huge pages в режим madvise. На старых ядрах (до 5.9) THP в режиме always может вызывать заметное снижение производительности — ядро тратит слишком много времени на дефрагментацию памяти, особенно в системах с 64 GB+ оперативной памяти. В ядре 5.9 появилась проактивная компакция, которая значительно лучше работает с THP, однако ClickHouse по-прежнему выводит предупреждение при запуске, если THP установлен в always, поэтому madvise остаётся рекомендуемым значением независимо от версии ядра.
$ echo 'madvise' | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
Если вы хотите навсегда изменить настройку transparent huge pages, отредактируйте /etc/default/grub, добавив transparent_hugepage=madvise в параметр GRUB_CMDLINE_LINUX_DEFAULT:
$ GRUB_CMDLINE_LINUX_DEFAULT="transparent_hugepage=madvise ..."
После этого выполните команду sudo update-grub, затем перезагрузите систему, чтобы изменения вступили в силу.

Конфигурация гипервизора

Если вы используете OpenStack, задайте
cpu_mode=host-passthrough
в nova.conf. Если вы используете libvirt, укажите
<cpu mode='host-passthrough'/>
в XML-конфигурации. Это необходимо, чтобы ClickHouse мог получать корректные данные через инструкцию cpuid. В противном случае возможны аварийные завершения с ошибкой Illegal instruction, если гипервизор запущен на старых моделях процессоров.

ClickHouse Keeper и ZooKeeper

Для кластеров ClickHouse рекомендуется использовать ClickHouse Keeper вместо ZooKeeper. См. документацию по ClickHouse Keeper Если вы хотите продолжать использовать ZooKeeper, лучше взять свежую версию ZooKeeper — 3.4.9 или новее. Версия в стабильных дистрибутивах Linux может быть устаревшей. Никогда не используйте написанные вручную скрипты для передачи данных между разными кластерами ZooKeeper, потому что для последовательных узлов результат будет некорректным. По той же причине никогда не используйте утилиту “zkcopy”: https://github.com/ksprojects/zkcopy/issues/15 Если вы хотите разделить существующий кластер ZooKeeper на два, правильный способ — увеличить число его реплик, а затем перенастроить его в два независимых кластера. Вы можете запускать ClickHouse Keeper на том же сервере, что и ClickHouse, в тестовых средах или в средах с низкой скоростью ингестии. Для production-сред мы рекомендуем использовать отдельные серверы для ClickHouse и ZooKeeper/Keeper либо размещать файлы ClickHouse и файлы Keeper на разных дисках. Это связано с тем, что ZooKeeper/Keeper очень чувствительны к задержкам диска, а ClickHouse может использовать все доступные системные ресурсы. В ансамбле ZooKeeper могут быть наблюдатели, но серверы ClickHouse не должны с ними взаимодействовать. Не изменяйте настройку minSessionTimeout, большие значения могут повлиять на стабильность перезапуска ClickHouse. При настройках по умолчанию ZooKeeper — это бомба замедленного действия:
Сервер ZooKeeper не будет удалять файлы старых снимков и журналов при использовании конфигурации по умолчанию (см. autopurge), и это является обязанностью оператора.
Эту бомбу необходимо обезвредить. Приведённая ниже конфигурация ZooKeeper (3.5.1) используется в крупной production-среде: zoo.cfg:
# http://hadoop.apache.org/zookeeper/docs/current/zookeeperAdmin.html

# Количество миллисекунд в каждом тике
tickTime=2000
# Количество тиков, которое может занять
# начальная фаза синхронизации.
# Это значение не имеет строгого обоснования
initLimit=300
# Количество тиков, которое может пройти между
# отправкой запроса и получением подтверждения
syncLimit=10

maxClientCnxns=2000

# Это максимальное значение, которое клиент может запросить, а сервер — принять.
# Допустимо устанавливать высокое значение maxSessionTimeout на сервере, чтобы клиенты могли работать
# с большим тайм-аутом сеанса при необходимости.
# По умолчанию запрашивается тайм-аут сеанса 30 секунд (можно изменить через session_timeout_ms в конфигурации ClickHouse).
maxSessionTimeout=60000000
# каталог, в котором хранится снимок.
dataDir=/opt/zookeeper/{{ '{{' }} cluster['name'] {{ '}}' }}/data
# Разместите dataLogDir на отдельном физическом диске для повышения производительности
dataLogDir=/opt/zookeeper/{{ '{{' }} cluster['name'] {{ '}}' }}/logs

autopurge.snapRetainCount=10
autopurge.purgeInterval=1

# Чтобы избежать операций seek, ZooKeeper выделяет пространство в файле журнала транзакций
# блоками по preAllocSize килобайт. Размер блока по умолчанию — 64 МБ. Одна из причин
# изменения размера блоков — уменьшить его, если снимки создаются чаще. (См. также snapCount).
preAllocSize=131072

# Клиенты могут отправлять запросы быстрее, чем ZooKeeper успевает их обрабатывать,
# особенно при большом количестве клиентов. Чтобы предотвратить нехватку памяти
# из-за очереди запросов, ZooKeeper ограничивает клиентов так, чтобы в системе
# было не более globalOutstandingLimit необработанных запросов. Лимит по умолчанию — 1000.
# globalOutstandingLimit=1000

# ZooKeeper записывает транзакции в журнал транзакций. После того как в файл журнала
# записано snapCount транзакций, создаётся снимок и открывается новый файл журнала транзакций.
# Значение snapCount по умолчанию — 100000.
snapCount=3000000

# Если этот параметр задан, запросы будут записываться в файл трассировки с именем
# traceFile.год.месяц.день.
#traceFile=

# Лидер принимает клиентские подключения. Значение по умолчанию — "yes". Машина-лидер
# координирует обновления. Для повышения пропускной способности записи за счёт незначительного
# снижения пропускной способности чтения лидер можно настроить так, чтобы он не принимал
# клиентов и сосредоточился на координации.
leaderServes=yes

standaloneEnabled=false
dynamicConfigFile=/etc/zookeeper-{{ '{{' }} cluster['name'] {{ '}}' }}/conf/zoo.cfg.dynamic
Версия на Java:
openjdk 11.0.5-shenandoah 2019-10-15
OpenJDK Runtime Environment (build 11.0.5-shenandoah+10-adhoc.heretic.src)
OpenJDK 64-Bit Server VM (build 11.0.5-shenandoah+10-adhoc.heretic.src, mixed mode)
Параметры JVM:
NAME=zookeeper-{{ '{{' }} cluster['name'] {{ '}}' }}
ZOOCFGDIR=/etc/$NAME/conf

# TODO это действительно некрасиво
# Как узнать, какие jar-файлы нужны?
# похоже, что log4j требует наличия файла log4j.properties в classpath
CLASSPATH="$ZOOCFGDIR:/usr/build/classes:/usr/build/lib/*.jar:/usr/share/zookeeper-3.6.2/lib/audience-annotations-0.5.0.jar:/usr/share/zookeeper-3.6.2/lib/commons-cli-1.2.jar:/usr/share/zookeeper-3.6.2/lib/commons-lang-2.6.jar:/usr/share/zookeeper-3.6.2/lib/jackson-annotations-2.10.3.jar:/usr/share/zookeeper-3.6.2/lib/jackson-core-2.10.3.jar:/usr/share/zookeeper-3.6.2/lib/jackson-databind-2.10.3.jar:/usr/share/zookeeper-3.6.2/lib/javax.servlet-api-3.1.0.jar:/usr/share/zookeeper-3.6.2/lib/jetty-http-9.4.24.v20191120.jar:/usr/share/zookeeper-3.6.2/lib/jetty-io-9.4.24.v20191120.jar:/usr/share/zookeeper-3.6.2/lib/jetty-security-9.4.24.v20191120.jar:/usr/share/zookeeper-3.6.2/lib/jetty-server-9.4.24.v20191120.jar:/usr/share/zookeeper-3.6.2/lib/jetty-servlet-9.4.24.v20191120.jar:/usr/share/zookeeper-3.6.2/lib/jetty-util-9.4.24.v20191120.jar:/usr/share/zookeeper-3.6.2/lib/jline-2.14.6.jar:/usr/share/zookeeper-3.6.2/lib/json-simple-1.1.1.jar:/usr/share/zookeeper-3.6.2/lib/log4j-1.2.17.jar:/usr/share/zookeeper-3.6.2/lib/metrics-core-3.2.5.jar:/usr/share/zookeeper-3.6.2/lib/netty-buffer-4.1.50.Final.jar:/usr/share/zookeeper-3.6.2/lib/netty-codec-4.1.50.Final.jar:/usr/share/zookeeper-3.6.2/lib/netty-common-4.1.50.Final.jar:/usr/share/zookeeper-3.6.2/lib/netty-handler-4.1.50.Final.jar:/usr/share/zookeeper-3.6.2/lib/netty-resolver-4.1.50.Final.jar:/usr/share/zookeeper-3.6.2/lib/netty-transport-4.1.50.Final.jar:/usr/share/zookeeper-3.6.2/lib/netty-transport-native-epoll-4.1.50.Final.jar:/usr/share/zookeeper-3.6.2/lib/netty-transport-native-unix-common-4.1.50.Final.jar:/usr/share/zookeeper-3.6.2/lib/simpleclient-0.6.0.jar:/usr/share/zookeeper-3.6.2/lib/simpleclient_common-0.6.0.jar:/usr/share/zookeeper-3.6.2/lib/simpleclient_hotspot-0.6.0.jar:/usr/share/zookeeper-3.6.2/lib/simpleclient_servlet-0.6.0.jar:/usr/share/zookeeper-3.6.2/lib/slf4j-api-1.7.25.jar:/usr/share/zookeeper-3.6.2/lib/slf4j-log4j12-1.7.25.jar:/usr/share/zookeeper-3.6.2/lib/snappy-java-1.1.7.jar:/usr/share/zookeeper-3.6.2/lib/zookeeper-3.6.2.jar:/usr/share/zookeeper-3.6.2/lib/zookeeper-jute-3.6.2.jar:/usr/share/zookeeper-3.6.2/lib/zookeeper-prometheus-metrics-3.6.2.jar:/usr/share/zookeeper-3.6.2/etc"

ZOOCFG="$ZOOCFGDIR/zoo.cfg"
ZOO_LOG_DIR=/var/log/$NAME
USER=zookeeper
GROUP=zookeeper
PIDDIR=/var/run/$NAME
PIDFILE=$PIDDIR/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
JAVA=/usr/local/jdk-11/bin/java
ZOOMAIN="org.apache.zookeeper.server.quorum.QuorumPeerMain"
ZOO_LOG4J_PROP="INFO,ROLLINGFILE"
JMXLOCALONLY=false
JAVA_OPTS="-Xms{{ '{{' }} cluster.get('xms','128M') {{ '}}' }} \
    -Xmx{{ '{{' }} cluster.get('xmx','1G') {{ '}}' }} \
    -Xlog:safepoint,gc*=info,age*=debug:file=/var/log/$NAME/zookeeper-gc.log:time,level,tags:filecount=16,filesize=16M
    -verbose:gc \
    -XX:+UseG1GC \
    -Djute.maxbuffer=8388608 \
    -XX:MaxGCPauseMillis=50"
Инициализация Salt:
description "zookeeper-{{ '{{' }} cluster['name'] {{ '}}' }} centralized coordination service"

start on runlevel [2345]
stop on runlevel [!2345]

respawn

limit nofile 8192 8192

pre-start script
    [ -r "/etc/zookeeper-{{ '{{' }} cluster['name'] {{ '}}' }}/conf/environment" ] || exit 0
    . /etc/zookeeper-{{ '{{' }} cluster['name'] {{ '}}' }}/conf/environment
    [ -d $ZOO_LOG_DIR ] || mkdir -p $ZOO_LOG_DIR
    chown $USER:$GROUP $ZOO_LOG_DIR
end script

script
    . /etc/zookeeper-{{ '{{' }} cluster['name'] {{ '}}' }}/conf/environment
    [ -r /etc/default/zookeeper ] && . /etc/default/zookeeper
    if [ -z "$JMXDISABLE" ]; then
        JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=$JMXLOCALONLY"
    fi
    exec start-stop-daemon --start -c $USER --exec $JAVA --name zookeeper-{{ '{{' }} cluster['name'] {{ '}}' }} \
        -- -cp $CLASSPATH $JAVA_OPTS -Dzookeeper.log.dir=${ZOO_LOG_DIR} \
        -Dzookeeper.root.logger=${ZOO_LOG4J_PROP} $ZOOMAIN $ZOOCFG
end script

Антивирусное ПО

Если вы используете антивирусное ПО, настройте его так, чтобы оно исключало из проверки каталоги с файлами данных ClickHouse (/var/lib/clickhouse), иначе производительность может снизиться, и во время ингестии данных и фоновых слияний могут возникать неожиданные ошибки.
Последнее изменение 10 июня 2026 г.