Ceph на SSD: тюнинг производительности для продакшена
Ceph умеет в SSD, но не умеет в SSD по умолчанию. Стандартная конфигурация оптимизирована под HDD с их характерными паттернами латентности. Запустить Ceph на NVMe и получить разочаровывающие цифры IOPS — классическая ошибка. Разберём как это исправить.
Почему дефолтная конфигурация плохо работает на SSD
HDD латентность — 5–10 мс на случайное чтение. NVMe — 50–100 мкс. Разница в 100 раз. Многие параметры Ceph по умолчанию рассчитаны на то, что операция займёт миллисекунды. На NVMe это создаёт узкие места совсем в других местах: CPU, сеть, размер allocation unit.
Второй момент — BlueStore. Начиная с Ceph Luminous это единственный поддерживаемый бэкенд, и у него свои специфические параметры для SSD.
BlueStore: ключевые параметры
bluestore_min_alloc_size — минимальный размер выделяемого блока в BlueStore. По умолчанию 64 КБ для HDD и 16 КБ для SSD (определяется автоматически). Для NVMe с преобладающей мелкой записью (4K–16K) уменьшение до 4096 снижает write amplification:
[osd]
bluestore_min_alloc_size = 4096
Внимание: этот параметр применяется только при создании OSD. Существующие OSD нужно пересоздавать.
osd_memory_target — сколько RAM разрешено использовать OSD для кэширования. По умолчанию 4 ГБ. На современных серверах с большим количеством RAM имеет смысл увеличить:
[osd]
osd_memory_target = 8589934592 # 8 GiB
BlueStore автоматически управляет внутренним кэшем в рамках этого лимита.
bluestore_cache_autotune — включено по умолчанию в новых версиях, позволяет BlueStore динамически распределять память между кэшем данных и метаданных. Оставьте включённым.
Отдельный NVMe для WAL и DB
BlueStore разделяет данные на три компонента:
- данные — основной объём
- WAL (Write-Ahead Log) — небольшой, высокоинтенсивная запись
- RocksDB metadata (DB) — метаданные, случайное чтение/запись
Классическая оптимизация: вынести WAL и DB на отдельный, более быстрый NVMe, оставив основные данные на более медленных SSD или даже HDD:
# При создании OSD с отдельными устройствами для WAL и DB
ceph-volume lvm create
--data /dev/sdb
--block.wal /dev/nvme0n1p1
--block.db /dev/nvme0n1p2
Размеры разделов: WAL — 512 МБ на OSD достаточно, DB — 4% от размера данных (минимум 2 ГБ). При размещении на одном быстром NVMe нескольких WAL/DB используйте LVM для разбивки.
CRUSH rules для SSD тира
Для разделения HDD и SSD пулов нужны отдельные CRUSH rules:
# Создаём bucket для SSD OSD
ceph osd crush add-bucket ssd-rack rack
ceph osd crush move ssd-rack root=default
# Помечаем SSD OSD
ceph osd crush set-device-class ssd osd.6 osd.7 osd.8
# Создаём rule для SSD пула
ceph osd crush rule create-replicated ssd-rule default host ssd
# Создаём пул с SSD rule
ceph osd pool create fast-pool 64 64 replicated ssd-rule
Erasure Coding vs Replication для SSD пулов
Replication 3x — стандарт. Простота, низкая латентность чтения (читаете с ближайшей реплики), но 3x overhead по ёмкости.
Erasure Coding — например, 4+2 profile даёт 1.5x overhead вместо 3x. Экономия значительная, особенно на дорогих NVMe. Но есть нюансы:
- запись всегда идёт через partial writes с penalty по IOPS
- чтение с деградировавшего пула требует реконструкции (slow)
- latency выше чем у replication
Для SSD пулов с read-heavy нагрузкой EC оправдан. Для write-intensive рабочих нагрузок — остайтесь на replication.
# Создание EC профиля 4+2
ceph osd erasure-code-profile set fast-ec-profile
k=4 m=2 crush-failure-domain=host
ceph osd pool create ec-fast-pool 64 64 erasure fast-ec-profile
Benchmarks: rados bench и fio
# Тест записи через rados bench
rados bench -p fast-pool 60 write --no-cleanup
# Тест случайного чтения
rados bench -p fast-pool 60 rand
# fio через librbd (для RBD пулов)
fio --name=test --ioengine=rbd
--pool=fast-pool --rbdname=test-image
--rw=randwrite --bs=4k --iodepth=32
--numjobs=4 --runtime=60
Типичные результаты на 3-нодовом кластере с NVMe (3x replication):
Random write 4K: ~80 000 IOPS
Random read 4K: ~180 000 IOPS
Sequential write: ~2 GB/s
Sequential read: ~4 GB/s
Network tuning: Jumbo frames и RDMA
Сеть — неожиданное узкое место на быстрых SSD кластерах.
Jumbo frames (MTU 9000) — обязательно для cluster network. Снижает CPU overhead на обработку пакетов при передаче больших объёмов:
# Проверьте что свитч поддерживает jumbo frames
ip link set ens5f0 mtu 9000
# Зафиксируйте в /etc/netplan/ или /etc/network/interfaces
RDMA (RoCE/InfiniBand) — для экстремальных требований к латентности. Ceph поддерживает Async RDMA messenger. Требует совместимого сетевого оборудования и настройки:
[global]
ms_type = async+rdma
ms_async_rdma_device_name = mlx5_0
Jumbo frames дают ощутимый прирост при небольших вложениях. RDMA — для специализированных задач с бюджетом на Mellanox.
Мониторинг: ceph-mgr dashboard и PG autoscaler
# Включение dashboard
ceph mgr module enable dashboard
ceph dashboard create-self-signed-cert
ceph dashboard set-login-credentials admin admin
# PG autoscaler — включить для всех пулов
ceph mgr module enable pg_autoscaler
ceph config set global osd_pool_default_pg_autoscale_mode on
Ключевые метрики для мониторинга SSD кластера:
ceph osd perf— латентность apply и commit по каждому OSD- slow ops (> 30 сек) — признак проблем с диском или сетью
ceph osd pool stats— throughput по пулам в реальном времени
Prometheus + ceph-mgr prometheus module + Grafana дашборд — стандартный стек для production мониторинга Ceph.
Итог
Тюнинг Ceph под SSD — это прежде всего правильный bluestore_min_alloc_size, вынос WAL/DB на отдельный быстрый NVMe, jumbo frames на cluster сети и правильный выбор между replication и EC под конкретную нагрузку. Без этих шагов вы получите 20–30% от потенциальной производительности железа. С ними — кластер который оправдывает вложения в NVMe.
По erasure coding на SSD — у нас на продакшене 6+3 профиль для холодных данных и 3x replication для горячих. Граница определяется по дате последнего обращения через lifecycle policy. Экономия на ёмкости вышла около 35% при приемлемой разнице в производительности.