Продуктивність Ceph на Proxmox повільна: 10 перевірок, які справді знаходять вузьке місце

Було корисно?

Ceph на Proxmox має особливий талант: він працює нормально, поки не прийде день, коли ви мігруєте кілька ВМ, запускаєте резервне копіювання — і раптом усе здається записом на USB-флешку 2009 року. З’являються піки затримки. Зростає iowait. Ваш «гіперконвергентний» стек перетворюється на «гіпер-переживання».

Виправлення рідко містичні. Зазвичай це одна з десяти нудних, але вимірюваних вузьких місць — мережа, трафік відновлення, змішані класи дисків, неправильно розмірені метадані BlueStore, недостатня потужність CPU або правило CRUSH, яке тихо вас ненавидить. Поймаємо проблему в процесі.

Швидкий план діагностики

Вам потрібні швидкі відповіді, а не вихідні з Grafana і жалями. Ось порядок, який я використовую, коли хтось каже «Ceph повільний» і за ними вже формується черга у виробництві.

Перше: кластер нездоровий чи просто повільний?

  • Перевірте health, recovery і «завислі» операції. Якщо йде відновлення/backfill, ви діагностуєте не продуктивність, а відновлення.
  • Підтвердіть, що OSD запущені/in і ніхто не «флапає».

Друге: чи проблема в мережі?

  • Більшість скарг «Ceph повільний» насправді означає «мережа кластера перевантажена».
  • Шукайте викиди пакунків, повторні передачі, дивні апаратні оффлоади NIC, невідповідність MTU та переспродані комутатори.

Третє: чи це диски/OSD?

  • Перевірте затримки комітів/аплаїв OSD, повільні операції BlueStore і чи не знаходяться DB/WAL на невідповідному носії.
  • Переконайтеся, що ви не помістили HDD-OSD у той же CRUSH-правило, що й SSD-OSD, а потім не дивувалися.

Четверте: чи це шлях клієнта (Proxmox вузли/ВМ)?

  • Вузли Proxmox можуть стати вузьким місцем по CPU, стеку мережі ядра або через забагато клієнтів RBD.
  • Неправильно налаштований кеш, невірний планувальник вводу-виводу та задачі резервного копіювання можуть перетворити «нормально» на «мертвий стан».

Якщо запам’ятаєте одне: завжди доведіть, чи вузьке місце в мережі, носіях OSD чи відновленні, перш ніж тикати регулювання. Налаштовувати неправильний шар — це як перетворити аварію на «навчальний досвід».

Кілька фактів (та історія), що пояснюють сьогоднішній біль

Діагностика продуктивності стає простішою, якщо пам’ятати, чому Ceph поводиться саме так.

  1. Мета дизайну Ceph — надійність у масштабі — не «максимальна IOPS на трьох вузлах». Ceph виник у дослідженнях UC Santa Cruz і виріс у систему з планетарним охопленням.
  2. CRUSH (Controlled Replication Under Scalable Hashing) дозволяє Ceph розміщувати дані без центрального мета-сервера, що вирішує кожне місце. Це добре для масштабу, але означає, що топологія та класи пристроїв дуже важливі.
  3. RBD — це copy-on-write на блоці і любить стабільну затримку. Він неодмінно відобразить мікросплески й джиттер мережі у затримку «диска» ВМ.
  4. BlueStore замінив FileStore, щоб прибрати файлову накладну та підвищити продуктивність, але ввів історію з DB/WAL — зроблено правильно — швидко, зроблено неправильно — повільно у дуже специфічний спосіб.
  5. За замовчуванням «replicated size 3» — це культурна звичка операторів, які люблять спати спокійно. За цю безпеку ви платите ампліфікацією записів і мережним трафіком.
  6. Placement groups (PG) — це важіль масштабу, а не чаклунство налаштувань. Забагато PG їсть пам’ять і CPU; замало концентрує навантаження і гальмує відновлення.
  7. Recovery і backfill — це навмисні обмежувачі. Ceph намагається продовжувати обслуговувати IO під час відновлення, але диски й мережа все одно спільні.
  8. 10GbE зробив Ceph популярним у «доступних» кластерах. На жаль, це також зробило поширеним oversubscription — і воно породжує загадкові затримки.
  9. Proxmox зробив Ceph доступним через дружній UI — і також спростив розгортання Ceph без нудної роботи з мережею та дисками.

Є одна переказана ідея, яку варто пам’ятати, приписувана Вернеру Фогельсу (погляд на надійність/операції): все рано чи пізно виходить з ладу, тож проєктуйте й експлуатуйте так, ніби відмова — нормальний стан. Діагностика продуктивності — та ж ментальність: припускайте, що суперечність нормальна, і доведіть, звідки вона походить.

10 перевірок (з командами, виводами та рішеннями)

Це не «поради». Це перевірки з чітким результатом: ви запускаєте команду, читаєте вивід, потім обираєте конкретну дію. Саме так припиняють гадати.

Перевірка 1: Health кластера, відновлення і повільні операції (перевірка «ми відновлюємося?»)

Якщо кластер відновлюється, ваше «проблемне» поводження може бути очікуваним. Вирішіть чекати, обмежити відновлення або зупинити роботу, що спричиняє зміну стану.

cr0x@server:~$ ceph -s
  cluster:
    id:     9f1b2d9a-1b2c-4b9b-8d2d-2f7e5f0f2c1a
    health: HEALTH_WARN
            12 slow ops, oldest one blocked for 34 sec, daemons [osd.3,osd.7] have slow ops
  services:
    mon: 3 daemons, quorum mon1,mon2,mon3 (age 2h)
    mgr: mgr1(active, since 2h)
    osd: 12 osds: 12 up (since 2h), 12 in (since 2h)
  data:
    pools:   4 pools, 256 pgs
    objects: 1.2M objects, 4.6 TiB
    usage:   13 TiB used, 21 TiB / 34 TiB avail
    pgs:     220 active+clean
             36  active+clean+scrubbing
  io:
    client:   220 MiB/s rd, 55 MiB/s wr, 2.1k op/s rd, 900 op/s wr

Що це означає: «slow ops» зазвичай вказує, що OSD не встигають (диски) або заблоковані (мережа чи внутрішні черги). Scrub теж з’являється; він не злий, але він не безкоштовний.

Рішення: Якщо повільні операції корелюють з вікнами scrub/recovery, заплануйте scrub у непіковий час і налаштуйте QoS відновлення (див. пізніші перевірки). Якщо slow ops з’являються випадково під нормальною навантаженістю — продовжуйте діагностику: це реальне вузьке місце.

cr0x@server:~$ ceph health detail
HEALTH_WARN 12 slow ops, oldest one blocked for 34 sec, daemons [osd.3,osd.7] have slow ops
[WRN] SLOW_OPS: 12 slow ops, oldest one blocked for 34 sec, daemons [osd.3,osd.7] have slow ops
    slow op 1, oldest at osd.3, committed, currently waiting for subops from [osd.7, osd.9]
    slow op 2, oldest at osd.7, waiting for BlueStore kv commit

Що це означає: «waiting for subops» пахне реплікацією/мережею; «waiting for BlueStore kv commit» вказує на BlueStore DB/WAL або затримку пристрою.

Рішення: Розділіть гіпотезу: шлях мережі vs носії OSD/метадані BlueStore.

Перевірка 2: Доведіть, що проблема у Ceph, а не у ВМ чи файловій системі хоста

Оператори люблять звинувачувати Ceph. Іноді це справедливо. Іноді ВМ робить 4k sync-записи у файлову систему з бар’єрами, і ви просто спостерігаєте фізику.

cr0x@server:~$ pvesm status
Name             Type     Status           Total            Used       Available        %
local             dir     active        98.00 GiB        22.16 GiB        70.80 GiB   22.61%
local-lvm     lvmthin     active       870.00 GiB       412.00 GiB       458.00 GiB   47.36%
ceph-rbd         rbd     active        21.00 TiB        13.10 TiB         7.90 TiB   62.38%

Що це означає: Підтверджує, які ВМ насправді на RBD. Бували випадки, коли в тікеті «Ceph повільний» ВМ стояла на local-lvm. Це не серйозна інцидент-розслідування — це пошук скарбів.

Рішення: Якщо лише деякі навантаження на Ceph, порівняйте поведінку між сховищами перед тим, як лазити в налаштування Ceph.

cr0x@server:~$ rbd -p ceph-vm ls | head
vm-100-disk-0
vm-101-disk-0
vm-104-disk-0
vm-105-disk-0

Що це означає: Підтверджує, що RBD-образи існують і доступні. Якщо ця команда повільна, це може вказувати на повільність MON/MGR або проблеми мережі.

Рішення: Повільні метадані штовхають вас у бік мережі, дисків MON або загального навантаження кластера.

Перевірка 3: Основи мережі — затримка, викиди, невідповідність MTU (тихий вбивця)

Ceph — розподілена система зберігання. Отже мережа — це шина зберігання. Ставтеся до неї відповідно.

cr0x@server:~$ ip -s link show dev eno2
2: eno2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether 3c:ec:ef:12:34:56 brd ff:ff:ff:ff:ff:ff
    RX:  bytes packets errors dropped  missed   mcast
    9876543210 7123456      0   18422       0  112233
    TX:  bytes packets errors dropped carrier collsns
    8765432109 6234567      0       9       0       0

Що це означає: RX-викиди в десятках тисяч — не «норма». На навантажених Ceph-лінках викиди часто перетворюються на повторні передачі, що дають хвостову затримку і злих власників ВМ.

Рішення: Якщо викиди ростуть під час інцидентів, спочатку лагодьте мережу. Перевірте буфери комутаторів, oversubscription, flow control та проблеми драйверів NIC.

cr0x@server:~$ ping -c 5 -M do -s 8972 10.10.10.12
PING 10.10.10.12 (10.10.10.12) 8972(9000) bytes of data.
8980 bytes from 10.10.10.12: icmp_seq=1 ttl=64 time=0.321 ms
8980 bytes from 10.10.10.12: icmp_seq=2 ttl=64 time=0.309 ms
8980 bytes from 10.10.10.12: icmp_seq=3 ttl=64 time=0.315 ms
8980 bytes from 10.10.10.12: icmp_seq=4 ttl=64 time=0.311 ms
8980 bytes from 10.10.10.12: icmp_seq=5 ttl=64 time=0.318 ms

--- 10.10.10.12 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4006ms
rtt min/avg/max/mdev = 0.309/0.315/0.321/0.004 ms

Що це означає: Jumbo-кадри або працюють послідовно end-to-end, або це пастка. Це перевірка MTU шляху з опцією «не фрагментувати».

Рішення: Якщо бачите «Frag needed» або втрати пакетів — зупиніться. Виправте MTU на всіх NIC, бондах, бриджах і комутаторах. Змішаний MTU створює виснажливий вид затримки: ніби працює, але повільно.

cr0x@server:~$ ss -ti dst 10.10.10.12 | head -n 12
ESTAB 0 0 10.10.10.11:6801 10.10.10.12:0
	 cubic wscale:7,7 rto:204 rtt:0.31/0.02 ato:40 mss:8960 pmtu:9000 rcvmss:8960 advmss:8960
	 bytes_sent:123456789 bytes_acked:123450000 bytes_received:9876543 segs_out:123456 segs_in:122999
	 retrans:12/3456 lost:0 sacked:123 fackets:12 reordering:0

Що це означає: Повторні передачі під час інциденту затримки — сигарний ознака. Не завжди корінна причина, але завжди релевантно.

Рішення: Якщо retransmits зростають під навантаженням — зменшіть oversubscription, розділіть трафік Ceph, перевірте кількість буферів NIC та налаштування переривань. Не «тюньте BlueStore» щоб виправити втрату пакетів.

Жарт №1: Jumbo-кадри як дієти: або всі їм слідують, або отримуєте дивні результати й багато заперечень.

Перевірка 4: Чи розділені public і cluster мережі (або хоча б не конфліктують)?

Proxmox спрощує запуск Ceph, коли public-трафік і реплікація/backfill йдуть по одному інтерфейсу «поки що». «Поки що» — як правило, залишається назавжди.

cr0x@server:~$ ceph config get mon public_network
10.10.10.0/24
cr0x@server:~$ ceph config get mon cluster_network
10.20.20.0/24

Що це означає: Якщо cluster_network порожній, реплікація та відновлення ділять ту ж мережу, що й клієнти. Це може бути прийнятно для крихітних кластерів — поки не стане неприйнятно.

Рішення: Якщо у вас є окремі NIC/VLAN — налаштуйте cluster_network. Якщо ні — подумайте про додавання перед тим, як ганятися за мікрооптимізаціями.

Перевірка 5: Перевантаження від реплікації/EC — чи не платите ви двічі за надійність?

Скарги на продуктивність часто виникають через невідповідність очікувань. Хтось хотів «швидкі диски ВМ», хтось інший — «три копії по вузлах», і ніхто не поцінив рахунок за IO.

cr0x@server:~$ ceph osd pool ls detail
pool 1 'ceph-vm' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 128 pgp_num 128 autoscale_mode on
pool 2 'ceph-ct' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 64 pgp_num 64 autoscale_mode on
pool 3 'cephfs_data' erasure size 4+2 crush_rule 3 object_hash rjenkins pg_num 64 pgp_num 64 autoscale_mode on
pool 4 'cephfs_metadata' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on

Що це означає: Реплікований пул з size 3 перетворює кожен запис на три записи по мережі й дисках. EC-пули знижують витрати по ємності, але дають навантаження на CPU і можуть підвищити затримку дрібних записів.

Рішення: Для ВМ з великою кількістю дрібних випадкових записів репліковані пули зазвичай розумний базис. Якщо ви використовуєте EC для ВМ — робіть це після вимірів і прийняття компромісів.

cr0x@server:~$ ceph tell osd.* perf dump | head -n 20
{
  "osd": {
    "op_wip": 12,
    "op_latency": 0.018,
    "op_process_latency": 0.012,
    "op_r_latency": 0.006,
    "op_w_latency": 0.021,
    "subop_latency": 0.019
  }
}

Що це означає: Зростаючий subop_latency відносно op_latency може вказувати, що підоперації реплікації повільні — часто мережа, іноді повільні пірінги (змішані класи дисків, зайняті OSD).

Рішення: Якщо підмножина OSD має значно гіршу затримку — ізолюйте їх: можливо, вони на гірших дисках, з неправильною прошивкою або на перевантажених хостах.

Перевірка 6: Класи дисків і CRUSH-правила — припиніть змішувати SSD і HDD в одному шляху продуктивності

Це одна з найпоширеніших «він працював в лабораторії» невдач. Декілька HDD-OSD пробираються в правило SSD-пулу, і тепер кожен запис інколи потрапляє до повільного учасника групи проекту.

cr0x@server:~$ ceph osd tree
ID  CLASS  WEIGHT   TYPE NAME         STATUS REWEIGHT PRI-AFF
-1         34.00000 root default
-3         11.33333     host pve1
 0   ssd    1.80000         osd.0         up  1.00000 1.00000
 1   ssd    1.80000         osd.1         up  1.00000 1.00000
 2   hdd    3.06667         osd.2         up  1.00000 1.00000
-5         11.33333     host pve2
 3   ssd    1.80000         osd.3         up  1.00000 1.00000
 4   ssd    1.80000         osd.4         up  1.00000 1.00000
 5   ssd    1.80000         osd.5         up  1.00000 1.00000

Що це означає: У вас є HDD-OSD в тій самій корені, що й SSD. Це не обов’язково неправильно, але ризиковано, якщо правило пулу не обмежує за класом.

Рішення: Переконайтеся, що CRUSH-правило пулу вибирає лише SSD (або лише HDD) залежно від призначення. Якщо хочете змішаний рівень, робіть це явно з окремими пулами та політиками, а не випадково.

cr0x@server:~$ ceph osd crush rule dump replicated_rule
{
  "rule_id": 0,
  "rule_name": "replicated_rule",
  "type": 1,
  "steps": [
    { "op": "take", "item": -1, "item_name": "default" },
    { "op": "chooseleaf_firstn", "num": 0, "type": "host" },
    { "op": "emit" }
  ]
}

Що це означає: Це правило не фільтрує клас пристрою. Тому HDD можуть обиратися як репліки навіть для пулів, орієнтованих на SSD.

Рішення: Створіть правило за класом і перемістіть чутливі до продуктивності пули туди. Так, це робота. Але менше роботи, ніж пояснювати команді бази даних випадкові 200ms fsync-и.

Перевірка 7: Розміщення та розмір BlueStore DB/WAL — ваші «SSD OSD» можуть бути все ще голодними за метаданими

BlueStore використовує RocksDB для метаданих (DB) і WAL. На швидких носіях правильне розміщення DB/WAL може зробити або зламати затримку при дрібних записах.

cr0x@server:~$ ceph-bluestore-tool show-label --dev /dev/sdb | head -n 30
{
  "osd_uuid": "f3b6b7b3-2a3a-4b7c-9b4c-1f2e3d4c5b6a",
  "size": 1920383410176,
  "btime": "2025-10-01T11:12:13.000000+0000",
  "description": "main",
  "whoami": "3"
}
cr0x@server:~$ ceph-volume lvm list | sed -n '1,80p'
====== osd.3 =======
  [block]       /dev/ceph-2c1a3b4d-.../osd-block-9a8b7c6d-...
      devices              /dev/sdb
  [db]          /dev/ceph-2c1a3b4d-.../osd-db-1a2b3c4d-...
      devices              /dev/nvme0n1
  [wal]         /dev/ceph-2c1a3b4d-.../osd-wal-5e6f7a8b-...
      devices              /dev/nvme0n1

Що це означає: Цей OSD має блок на /dev/sdb (ймовірно SSD/SATA) з DB/WAL на NVMe — загалом добре для затримки. Якщо DB/WAL на тих же повільних пристроях для HDD-OSD — ви відчуєте це.

Рішення: Якщо у вас HDD-OSD — рішуче розгляньте розміщення DB/WAL на SSD/NVMe. Якщо у вас SSD-OSD, але все ще висока затримка комітів — підтвердіть, що DB не замалий або не контендиться (кілька OSD ділять маленький NVMe розділ).

cr0x@server:~$ ceph daemon osd.3 bluestore perf dump | head -n 40
{
  "kv_commits": 124567,
  "kv_commit_latency_ms": {
    "avgcount": 1024,
    "sum": 8345.21,
    "avg": 8.15
  },
  "deferred_write_ops": 0,
  "stall": 0
}

Що це означає: Середня затримка KV commit ~8ms може бути прийнятною для HDD, підозрілою для «всі NVMe» і катастрофічною, якщо стрибає до десятків/сотень мс. Це також корелює з slow ops «waiting for BlueStore kv commit».

Рішення: Якщо KV commit latency висока — перевірте насичення пристрою DB, налаштування кешу запису та чи не занадто багато OSD використовують один DB-пристрій. Розгляньте перейнсталяцію з правильним розміром DB і ізоляцією.

Перевірка 8: CPU, пам’ять і планувальник OSD — коли сховище швидке, хост стає вузьким місцем

Ceph — це не лише диски. OSD роблять контрольні суми, компресію (якщо увімкнено), мережу й облік. На маленьких кластерах трохи голодний CPU дає багато хвостової затримки.

cr0x@server:~$ ceph tell osd.* dump_historic_ops | head -n 25
{
  "ops": [
    {
      "description": "osd_op(client.1234:5678 1.2e3f4b5c ::ffff:10.10.10.50:0/12345 1) [write 0~4096]",
      "duration": 1.238,
      "initiated_at": "2025-12-28T10:11:12.123456+0000",
      "age": 1.238
    }
  ]
}

Що це означає: Операції з тривалістю >1с — ненормально для здорових SSD-кластерів при помірному навантаженні. Опис показує 4k-записи; дрібні синхронні записи відразу виявляють затримку.

Рішення: Корелюйте з CPU steal, середнім завантаженням і контенцією потоків OSD на тому ж вузлі.

cr0x@server:~$ top -b -n 1 | head -n 15
top - 10:22:01 up 12 days,  3:10,  1 user,  load average: 18.22, 16.90, 12.40
Tasks: 512 total,   2 running, 510 sleeping,   0 stopped,   0 zombie
%Cpu(s): 28.1 us,  6.4 sy,  0.0 ni, 48.2 id, 15.9 wa,  0.0 hi,  1.4 si,  0.0 st
MiB Mem : 128000.0 total,   2200.0 free,  41200.0 used,  84600.0 buff/cache
MiB Swap:   2048.0 total,   2048.0 free,      0.0 used.  82200.0 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 8123 ceph      20   0 8421376 4.1g  120m S  220.0   3.3  92:12.34 ceph-osd

Що це означає: 15.9% iowait вказує на затримки зберігання, але середнє навантаження та гарячий процес OSD вказують, що вузол завантажений. Якщо це гіперконвергентний вузол з багатьма ВМ — контенція CPU і IO реальна.

Рішення: Якщо OSD і ВМ борються за CPU — прив’яжіть ресурси, зменшіть щільність ВМ або розділіть ролі. «Просто додати тюнінг» — не план ємності.

cr0x@server:~$ cat /sys/block/sdb/queue/scheduler
mq-deadline none

Що це означає: Для SSD mq-deadline часто розумний вибір; для HDD планувальник має більше значення. Для NVMe планувальник часто менш критичний, але «none» теж підходить.

Рішення: Якщо бачите патологічну затримку на HDD-OSD — перевірте, що не використовується планувальник, який посилює пошукові штормы. Не чекайте дива: Ceph на HDD — це все ще Ceph на HDD.

Перевірка 9: Тиск відновлення/backfill/scrub — ваш кластер їсть овочі під час обіднього напливу

Фонові роботи Ceph — корисні. Вони запобігають втраті даних. Але вони теж змагаються за ті ж диски і мережу, що й клієнти.

cr0x@server:~$ ceph status | sed -n '1,30p'
  cluster:
    id:     9f1b2d9a-1b2c-4b9b-8d2d-2f7e5f0f2c1a
    health: HEALTH_OK
  services:
    mon: 3 daemons, quorum mon1,mon2,mon3 (age 2h)
    mgr: mgr1(active, since 2h)
    osd: 12 osds: 12 up (since 2h), 12 in (since 2h)
  data:
    pools:   4 pools, 256 pgs
    pgs:     256 active+clean
  progress:
    Recovery event (35s)
      [============================..] (remaining: 9s)

Що це означає: Навіть з HEALTH_OK, відновлення може бути активним. На малих кластерах подія відновлення може домінувати над продуктивністю хвилинами або годинами.

Рішення: Якщо клієнтський IO важливіший за швидке відновлення у бізнес-години — обмежте відновлення під час піків і плануйте обслуговування для важкого ребалансингу.

cr0x@server:~$ ceph config get osd osd_recovery_max_active
3
cr0x@server:~$ ceph config get osd osd_max_backfills
2

Що це означає: Ці значення визначають, наскільки агресивно працює recovery/backfill. Вищі — швидше відновлення й гірша видимість для клієнта (зазвичай). Нижчі — лагідніше для клієнтів і повільніше відновлення.

Рішення: Якщо ваш кластер маленький і клієнтський IO важливий — тримайте ці значення консервативними. Якщо ви у сценарії відмови і потребуєте швидкого відновлення — тимчасово підніміть їх, а потім поверніть назад.

cr0x@server:~$ ceph config set osd osd_recovery_sleep 0.1

Що це означає: Додавання невеликої паузи під час відновлення може згладити клієнтську затримку, даючи дискам трохи віддиху.

Рішення: Використовуйте це, коли бачите піки затримки, спричинені відновленням, і можете терпіти повільніше відновлення. Тестуйте уважно; не «встановлюйте і забувайте» без розуміння часу відновлення.

Перевірка 10: Бенчмаркуйте правильне — RADOS vs RBD, читання vs запис, sync vs async

Бенчмарки корисні, коли відповідають на конкретне питання. «Наскільки швидкий Ceph?» — не питання. «Чи прийнятна сирова затримка запису OSD?» — це питання.

cr0x@server:~$ rados bench -p ceph-vm 30 write --no-cleanup
hints = 1
Maintaining 16 concurrent writes of 4194304 bytes for at least 30 seconds.
Total time run:         30.422
Total writes made:      259
Write size:             4194304
Object size:            4194304
Bandwidth (MB/sec):     34.06
Stddev Bandwidth:       6.12
Max bandwidth (MB/sec): 45.01
Min bandwidth (MB/sec): 18.77
Average IOPS:           8
Stddev IOPS:            1
Average Latency(s):     1.932
Max latency(s):         5.221
Min latency(s):         0.412

Що це означає: 4MB записи з середньою затримкою ~2с — тривожний сигнал, якщо тільки кластер не сильно відновлюється або це не HDD з екстремальною контенцією. Це не «налаштування»; це «щось не так».

Рішення: Якщо RADOS bench поганий — проблема на боці кластера (мережа/OSD/відновлення). Якщо RADOS bench хороший, а диски ВМ повільні — проблема на боці клієнта (налаштування RBD, шаблон IO, контенція хоста).

cr0x@server:~$ rbd perf image iostat --pool ceph-vm --image vm-100-disk-0 --interval 2 --count 5
rbd/image                         read_ops  read_bytes  write_ops  write_bytes  read_latency  write_latency
ceph-vm/vm-100-disk-0                  120     1.2MiB        340      24.0MiB        7.2ms        41.8ms
ceph-vm/vm-100-disk-0                  110     1.1MiB        360      25.5MiB        8.1ms        55.3ms
ceph-vm/vm-100-disk-0                   95   980.0KiB        390      28.3MiB        6.9ms        72.1ms
ceph-vm/vm-100-disk-0                  130     1.3MiB        310      22.1MiB        7.5ms        38.9ms
ceph-vm/vm-100-disk-0                  125     1.2MiB        320      23.0MiB        7.0ms        44.0ms

Що це означає: Затримка записів зростає, тоді як читання залишається стабільним. Це часто вказує на тиск реплікації/комітів, контенцію DB/WAL або втручання відновлення.

Рішення: Якщо це один образ/ВМ — перевірте навантаження (fsync-важка БД, журналювання). Якщо багато образів — перевірте затримку комітів OSD і повторні передачі в мережі.

Жарт №2: Бенчмаркувати без питання — як навантажувати кавоварку: ви дізнаєтеся щось, але не те, що потрібно.

Три корпоративні короткі історії з полігонів продуктивності

Коротка історія 1: Інцидент через хибне припущення («10GbE — цього достатньо»)

У них був акуратний Proxmox-кластер, три вузли, Ceph replicated size 3 та стік комутаторів 10GbE, який виглядав гідно в закупівельних таблицях. Припущення було просте: «10GbE нам вистачить». Часто вистачає — поки не перестає.

Першим симптомом не був алерт Ceph. Це був хелпдеск: «ВМ зависають на секунду під час бекапу». Потім — «бази даних підгальмовують». Графіки затримок виглядали як силует міста. Дашборд Ceph був майже спокійний, бо health не був проблемою. Проблема була в продуктивності.

Ми подивилися лічильники інтерфейсів і знайшли, що RX-викиди зростали лише під час двох подій: нічних бекапів і щотижневого scrub-вікна. Бекап-трафік навіть не був на Ceph — принаймні не навмисно. Він ділив ті самі bonded uplinks і ті самі буфери комутатора. Реплікаційний трафік Ceph і «бекап на NAS» билися в вузькому коридорі.

Хибне припущення було в тому, що тільки пропускної здатності достатньо. Справжній лиходій — контенція й мікросплески. Реплікаційний трафік Ceph спіктоподібний; бекап — тривалий; разом вони дають хвостову затримку, що робить клієнтів RBD сумними.

Виправлення було нудним: правильно розділити мережі (VLAN плюс QoS на комутаторі, зрештою виділити NIC), не виконувати scrub під час бекапів і встановити політику, що кластерний трафік ніколи не ділиться з масовими передачами на одному вузькому місці. Інцидент зник. Ніхто не виявив захоплення — знак того, що виправлення правильне.

Коротка історія 2: Оптимізація, що відкотилася («Давайте піджешемо recovery, щоб швидше закінчилося»)

Інша компанія, інший настрій: їм не подобалося бачити «backfill» у статусі Ceph. Після перезавантаження вузла через відключення електрики кластер ребалансувався. Хтось вирішив «прискорити» шляхом підвищення паралельності recovery і backfill.

Кілька хвилин було чудово. Прогрес-бар відновлення рухався швидше. Slack оптимістично ожив. Потім затримка ВМ піднялася у стратосферу. Додатки почали таймаути. Кластер не був нездоровим; він просто занадто активно робив правильну роботу.

Що сталося: вони перетворили відновлення на пріоритетне навантаження. Backfill розбивав ті самі диски, що обслуговували клієнтський IO. Мережа голосніла. Черги OSD заповнилися. Клієнтські запити не падали — вони просто чекали. І чекання — те, що бази даних сприймають як «можливо, диск помирає».

Ми відкотили налаштування, додали невелику паузу recovery і обрали тонку стратегію: агресивне відновлення тільки у визначені вікна інциденту, консервативне — у бізнес-години. Вони досі відновлювали резервність швидко — просто не ціною перетворення продакшну на слайд-шоу.

Урок не «ніколи не тюнити recovery». Урок — «відновлення — це навантаження продуктивності». Якщо ви його не плануєте, воно запланує вас.

Коротка історія 3: Нудна, але правильна практика, що врятувала ситуацію («Класові CRUSH-правила і дисципліна ємності»)

Одна команда зробила непопулярне: вони тримали дизайн сховища простим. Окремі SSD і HDD пули. Окремі CRUSH-правила за класом пристрою. Ніяких мікс-медіа трюків. Вони також тримали запас: 70% використання вважали «початком заповнення», а не «достатньо місця».

Коли партія SSD почала показувати підвищену затримку (не падали, просто поводилися дивно), кластер не зруйнувався. Чому? Бо CRUSH-правила не дозволяли HDD-OSD випадково стати репліками для SSD-пулів ВМ. Робочі навантаження, чутливі до продуктивності, залишалися на SSD. Повільні пристрої не тягнули за собою хвостову затримку всього пулу.

Їм все одно довелося робити: позначити підозрілі OSD, замінити диски, дати пройти відновленню. Але інцидент залишився локалізованим. Ніяких каскадних тікетів від сторонніх сервісів. Ніякого екстреного «перенести все з Ceph» плану.

Що їх врятувало — не магічний sysctl, а гігієна дизайну. Така, що виглядає як overkill, поки одного дня тихо не перетворює кризу на рутину обслуговування.

Типові помилки: симптом → корінна причина → виправлення

Тут ви впізнаєте свій кластер і відчуєте легке осудження. Добре. Продакшн-системи добре реагують на легке осудження.

1) Симптом: «Випадкові» піки затримки записів по багатьох ВМ

  • Корінь: Викиди/повторні передачі мережі, невідповідність MTU або oversubscription комутатора, що дає хвостову затримку.
  • Виправлення: Перевірте ip -s link, ss -ti, MTU end-to-end. Розділіть cluster/public трафік. Зменшіть oversubscription. Не змішуйте бекапи з тим же каналом.

2) Симптом: Читання в порядку, записи жахливі

  • Корінь: Вузьке місце на шляху реплікації/коміту: повільні OSD-пірінги, KV commit BlueStore, замалий DB/WAL або втручання відновлення.
  • Виправлення: Перевірте slow ops detail, BlueStore perf та налаштування відновлення. Перемістіть DB/WAL на швидкі пристрої; обмежте recovery у піки; забезпечте, щоб пул не включав повільні диски.

3) Симптом: «Ceph повільний» лише під час scrub/backfill

  • Корінь: Фонова робота змагається за ті ж IO та мережу.
  • Виправлення: Плануйте scrub у вікна з низьким навантаженням. Налаштуйте concurrency recovery/backfill і додайте osd_recovery_sleep за потреби. Погодьте довший час відновлення як бізнес-вибір.

4) Симптом: Одна ВМ жахлива; інші в порядку

  • Корінь: Невідповідність шаблону навантаження (fsync-важка БД, дрібні випадкові записи, fsync-шторм) або образ на зайнятому PG/наборі OSD.
  • Виправлення: Використайте rbd perf image iostat. Перевірте всередині ВМ налаштування файлової системи й аплікації. Розгляньте перенесення цього навантаження в пул з іншими налаштуваннями або на швидший носій.

5) Симптом: Продуктивність погіршилася після «додавання ємності»

  • Корінь: Ви додали повільні диски в той самий CRUSH-правило/пул або спричинили сильний ребаланс під час піку.
  • Виправлення: Використовуйте CRUSH-правила за класом. Додавайте ємність у контрольованому вікні. Розгляньте поетапні reweight, щоб зменшити blast radius ребалансування.

6) Симптом: Затримка погіршується при заповненні ≈70–80%

  • Корінь: Фрагментація, зменшення вільного простору для BlueStore/алгоритмів розміщення та дорожча поведінка placement/recovery при заповненні кластера.
  • Виправлення: Тримайте запас вільного місця. Плануйте ємність заздалегідь. Не працюйте з Ceph близько до повного, якщо не любите аварійні міграції.

7) Симптом: Команди Ceph повільні (status, ls тощо)

  • Корінь: Затримка диску MON, перевантажені монітори, проблеми мережі або загальне перевантаження кластера.
  • Виправлення: Перевірте IO і мережу хостів MON. Забезпечте MON на надійному медіа й щоб їх не «душили» ВМ на тих же вузлах.

Контрольні списки / покроковий план

Покроковий план триажу (робіть у цьому порядку)

  1. Захопіть момент: запустіть ceph -s і ceph health detail. Збережіть вивід з часовою міткою.
  2. Підтвердіть масштаб: які ВМ, які сховища, які вузли. Використайте pvesm status і перевірте розміщення дисків.
  3. Перевірте відновлення/scrub: якщо активне, вирішіть обмежити чи чекати.
  4. Лічильники мережі: ip -s link на всіх Ceph-NIC, перевірте викиди й помилки.
  5. MTU-саніті: тест path MTU з ping -M do між усіма вузлами Ceph-мереж.
  6. Повторні передачі: ss -ti між вузлами; шукайте зростання retrans під навантаженням.
  7. OSD-аутлаєри: знайдіть OSD з гіршою затримкою через slow ops і perf dumps.
  8. Клас дисків і CRUSH: перевірте, що пули використовують коректні правила і класи; виправте випадкове змішування.
  9. BlueStore DB/WAL: підтвердіть розміщення і перевірте KV commit latency.
  10. Бенчмаркуйте відповідально: RADOS bench для перевірки кластера, потім RBD iostat для перевірки шляху клієнта.

Операційний чекліст для підтримки швидкості (негламурна рутина)

  • Тримайте використання кластера комфортно нижче «повного». Плануйте ємність як дорослий.
  • Розділяйте Ceph public і cluster мережі коли можливо, або принаймні ізолюйте їх від масових передач.
  • Застосовуйте класи пристроїв та CRUSH-правила; розглядайте змішування медіа в одному пулі як питання дизайну.
  • Плануйте scrub і важкі роботи на технічне обслуговування подалі від бекапів і пакетних задач.
  • Документуйте налаштування recovery/backfill і повертайте їх після інцидентів.
  • Відстежуйте розподіли затримок (p95/p99), а не лише середні значення. Середні — як спосіб здивуватися.

Часті питання

1) Чому Ceph на Proxmox повільніший за локальний NVMe?

Бо це інше. Локальний NVMe — це один пристрій з доступом на мікросекунди. Записи Ceph розподілені, реплікуються і підтверджуються через мережу й кілька OSD. Ви обмінюєте затримку за доступність і оперативну гнучкість.

2) Чи дійсно потрібна окрема cluster-мережа?

Не завжди, але якщо у вас непередбачувана затримка і будь-яке змішання клієнтського IO та відновлення/бекапів на тих самих лініях — розділення дає найвищий ROI. Якщо не можна додати NIC — VLAN + QoS на комутаторі краще, ніж «усе разом».

3) Чи обов’язковий replication size 3?

Ні. Це дефолт, що відповідає поширеному рівню ризику. Size 2 знижує ампліфікацію записів, але підвищує ризик і зменшує толерантність до відмов. Правильний вибір залежить від бізнес-вимог, кількості вузлів і того, наскільки ви боїтеся простою.

4) Чи варто використовувати erasure coding для дисків ВМ?

Зазвичай ні для дрібних записів і чутливих до затримки ВМ. EC добре економить ємність і підходить для великих об’єктів, але додає навантаження на CPU і може карати дрібні випадкові записи. Якщо ви хочете EC для ВМ — вимірюйте на реальному навантаженні і приймайте складність.

5) Що насправді означає «slow ops»?

Це означає, що клієнтська IO-операція триває довше, ніж очікують у OSD-пайплайні — чекає підоперацій, комітів, диска або застрягла в чергах. Детальний вивід часто підказує, чи це мережа/підоперації, чи commit BlueStore.

6) Чи можуть кілька повільних дисків нашкодити всьому пулу?

Так. Реплікація означає, що затримка запису часто обмежується найповільнішою реплікою, задіяною в операції. Якщо CRUSH-правило дозволяє HDD брати участь у пулі, призначеному для SSD — ви створили генератор випадковості для p99 затримки.

7) Чому продуктивність тане під час відновлення, хоча кластер «HEALTH_OK»?

Бо HEALTH_OK стосується цілісності даних і властивостей кластера, а не SLO затримки вашого додатка. Відновлення — це інтенсивний IO і мережний трафік; Ceph може залишатися коректним, але повільним.

8) Скільки OSD на вузлі — «занадто багато»?

Залежить від CPU, RAM, медіа й мережі. Якщо процеси OSD голодують по CPU або якщо DB-пристрої діляться занадто агресивно — побачите затримки комітів і slow ops. Правильну відповідь дають виміри затримок по OSD і контенції хоста, а не магічне число.

9) Чи варто «просто додати більше PG», щоб вирішити гарячі точки?

Ні, не за замовчуванням. Кількість PG впливає на пам’ять, накладні витрати на peering і поведінку recovery. Використовуйте autoscaling там, де потрібно, і вручну регулюйте лише коли розумієте розподіл навантаження.

10) Який найшвидший індикатор «мережа проти диска»?

Подивіться на retransmits/викиди для мережі та на BlueStore KV commit latency плюс затримки apply/commit OSD для дисків/метаданих. Якщо обидва погані — вітаю: у вас справжня розподілена проблема.

Висновок: наступні кроки, що дають результат

Якщо Ceph-on-Proxmox повільний — не починайте з зміни тюнінгів. Почніть з доведення, куди витрачається час. Запустіть швидкий план діагностики, а потім дисциплініруйтеся з десятьма перевірками: лічильники мережі, MTU, повторні передачі, тиск відновлення, класи дисків/CRUSH-правила, розміщення BlueStore DB/WAL і нарешті прицільні бенчмарки.

Ваші практичні наступні кроки:

  • Протягом години: захопіть ceph -s, ceph health detail, лічильники NIC, MTU-тести і retransmits під час періоду сповільнення.
  • Протягом дня: перевірте, що правила пулів не змішують класи дисків; підтвердьте розділення cluster/public мереж; проведіть аудит розкладу scrub/recovery.
  • Протягом тижня: виправте структурні проблеми — DB/WAL на правильних пристроях, видаліть повільні аутлайр-диски і вирішіть oversubscription. Налаштовуйте тільки після того, як архітектура перестане сама собі заважати.

Ceph може бути швидким. Він також може бути надійним. Але не буде ні тим, ні іншим, якщо мережу тримати як думку на потім, а макет дисків — як рекомендацію.

← Попередня
Оновлення MySQL та MariaDB: як оновити без руйнування продакшену
Наступна →
Core Web Vitals у WordPress: реальні виправлення для LCP, INP і CLS

Залишити коментар