Як з fio перевірити диски на достатню продуктивність для etcd

Прим. перев.: ця стаття - результати міні-дослідження, проведеного інженерами IBM Cloud у пошуках вирішення реальної проблеми, пов'язаної з експлуатацією бази даних etcd. Для нас було актуальне схоже завдання, проте перебіг роздумів і дій авторів може бути цікавим і в більш широкому контексті.

Як з fio перевірити диски на достатню продуктивність для etcd

Коротке резюме всієї статті: fio та etcd

Продуктивність кластера etcd залежить від швидкості сховища, що лежить в його основі. Для контролю над продуктивністю etcd експортує різні метрики Prometheus. Однією з них є wal_fsync_duration_seconds. У документації до etcd йдетьсящо сховище можна вважати досить швидким, якщо 99-й процентиль цієї метрики не перевищує 10 мс.

Якщо ви обмірковуєте можливість організації кластера etcd на машинах під керуванням Linux і хочете перевірити, чи достатньо швидкі накопичувачі (наприклад, SSD), рекомендуємо скористатися популярним I/O тестером під назвою нитка. Достатньо запустити наступну команду (директорія test-data повинна бути розташована в примонтованому розділі накопичувача, що тестується):

fio --rw=write --ioengine=sync --fdatasync=1 --directory=test-data --size=22m --bs=2300 --name=mytest

Залишилося лише подивитися на висновок і перевірити, чи вкладається 99-й процентиль fdatasync о 10 мс. Якщо це так, то ваш накопичувач працює досить швидко. Ось приклад висновку:

fsync/fdatasync/sync_file_range:
  sync (usec): min=534, max=15766, avg=1273.08, stdev=1084.70
  sync percentiles (usec):
   | 1.00th=[ 553], 5.00th=[ 578], 10.00th=[ 594], 20.00th=[ 627],
   | 30.00th=[ 709], 40.00th=[ 750], 50.00th=[ 783], 60.00th=[ 1549],
   | 70.00th=[ 1729], 80.00th=[ 1991], 90.00th=[ 2180], 95.00th=[ 2278],
   | 99.00th=[ 2376], 99.50th=[ 9634], 99.90th=[15795], 99.95th=[15795],
   | 99.99th=[15795]

Кілька зауважень:

  1. У наведеному вище прикладі ми підлаштували параметри --size и --bs під конкретний випадок. Щоб отримати змістовний результат від fio, вказуйте значення, які підходять для вашого сценарію використання. Про те, як їх обрати, буде розказано нижче.
  2. Під час тестування лише fio навантажує дискову підсистему. У реальному житті цілком ймовірно, що на диск писатимуть й інші процеси (крім тих, що пов'язані з wal_fsync_duration_seconds). Подібне додаткове навантаження може призвести до збільшення wal_fsync_duration_seconds. Іншими словами, якщо 99-й процентиль, отриманий за підсумками тестування з fio, лише трохи менше 10 мс, велика ймовірність, що продуктивність сховища недостатня.
  3. Для тесту вам знадобиться версія fio не нижче 3.5, оскільки старіші версії не агрегують результати fdatasync як процентилей.
  4. Наведений вище висновок є лише невеликий уривок від загального висновку fio.

Детально про fio та etcd

Декілька слів про WAL'ах etcd

Як правило, бази даних використовують попереджувальну журналізацію (Write-ahead logging, WAL). etcd це теж стосується. Обговорення WAL виходить за рамки цієї статті, проте для наших цілей потрібно знати наступне: кожен член кластера etcd зберігає WAL у постійному сховищі. etcd записує деякі операції з key-value-сховищем (наприклад, оновлення) у WAL, перш ніж виконати їх. Якщо вузол впаде і перезапуститься в проміжку між snapshot'ами, etcd зможе відновити транзакції, проведені з попереднього snapshot'а, орієнтуючись на вміст WAL.

Таким чином, кожного разу, коли клієнт додає ключ у KV-сховище або оновлює значення існуючого ключа, etcd додає опис операції WAL, що являє собою звичайний файл у постійному сховищі. Перш ніж продовжити роботу, etcd ПОВИННА бути на 100% впевнена, що запис WAL дійсно збережена. Щоб досягти цього в Linux, недостатньо використовувати системний виклик writeоскільки сама операція запису на фізичний носій може бути відкладена. Наприклад, Linux протягом певного часу може протримати WAL-запис у кеші ядра в пам'яті (наприклад, у сторінковому кеші). Щоб гарантувати, що дані записані на носій, після запису необхідно задіяти системний виклик fdatasync - саме так робить etcd (як видно на прикладі наступного висновку strace; тут 8 - Дескриптор файлу WAL):

21:23:09.894875 lseek(8, 0, SEEK_CUR)   = 12808 <0.000012>
21:23:09.894911 write(8, ".20210220361223255266632$1020103026"34"rn3fo"..., 2296) = 2296 <0.000130>
21:23:09.895041 fdatasync(8)            = 0 <0.008314>

На жаль, запис у постійне сховище займає деякий час. Здійснення виклику fdatasync, що тривало, може позначитися на продуктивності etcd. У документації до сховища вказується, Що для достатньої продуктивності необхідно, щоб 99-й процентиль тривалості всіх викликів fdatasync при записі файл WAL була менше 10 мс. Є й інші метрики, пов'язані зі сховищем, але в цій статті йтиметься саме про цю.

Оцінюємо сховище за допомогою fio

Оцінити, чи підходить якесь сховище для використання з etcd, можна за допомогою утиліти нитка - Популярного тестера I/O. Враховуйте, що дискове введення-виведення може відбуватися по-різному: sync/async, безліч різних класів системних викликів і т.п. Зворотний бік медалі полягає в тому, що fio надзвичайно складна у використанні. В утиліти безліч параметрів, і різні комбінації їх значень призводять до різних результатів. Щоб отримати осудну оцінку у випадку etcd, ви повинні переконатися, що навантаження на запис, що генерується fio, максимально схоже на навантаження etcd при записі WAL-файли:

  • Це означає, що генерується fio навантаження, принаймні, має являти собою серію послідовних записів у файл, де кожна операція запису складається із системного виклику write, за яким слідує fdatasync.
  • Щоб увімкнути послідовний запис, необхідно вказати прапор --rw=write.
  • Щоб fio писала з використанням викликів write (а не інших системних викликів - наприклад, pwrite), використовуйте прапор --ioengine=sync.
  • Нарешті прапор --fdatasync=1 гарантує, що за кожним write випливає fdatasync.
  • Два інших параметри в нашому прикладі: --size и --bs — можуть змінюватись залежно від конкретного сценарію використання. У наступному розділі буде описано їхнє налаштування.

Чому ми вибрали fio і звідки дізналися, як його налаштовувати

Ця замітка з'явилася з реальної нагоди, з якою ми зіткнулися. Ми мали кластер на Kubernetes v1.13 з моніторингом на Prometheus. Як сховища для etcd v3.2.24 виступали твердотільні накопичувачі. Метрики etcd показували надто високі затримки fdatasyncнавіть коли кластер простоював. Нам ці метрики здавалися дуже сумнівними, і ми не були впевнені, що саме вони представляють. Крім того, кластер складався з віртуальних машин, тому не виходило сказати, затримка була пов'язана з віртуалізацією або у всьому винні SSD.

Крім того, ми розглядали різні зміни в конфігурації апаратного та програмного забезпечення, тому був потрібний спосіб їхньої оцінки. Звичайно, можна було б запустити etcd у кожній конфігурації та подивитися на відповідні метрики Prometheus, але це потребувало б значних зусиль. Нам був потрібен простий метод, що дозволяє оцінити конкретну конфігурацію. Ми хотіли перевірити своє розуміння метриків Prometheus, що надходять від etcd.

Для цього потрібно вирішити дві проблеми:

  • По-перше, як виглядає I/O-навантаження, що генерується etcd під час запису у файли WAL? Які дзвінки використовуються? Яким є розмір блоків запису?
  • По-друге, припустимо, відповіді на перелічені вище запитання у нас є. Як відтворити відповідне навантаження з fio? адже fio - надзвичайно гнучка утиліта з безліччю параметрів (У цьому легко переконатися, наприклад, тут - прим. перев.).

Ми вирішили обидві проблеми за допомогою того самого підходу, що спирається на команди lsof и strace:

  • За допомогою lsof можна переглянути всі файлові дескриптори, які використовуються процесом, а також файли, до яких вони належать.
  • За допомогою strace можна аналізувати вже запущений процес або запустити процес і спостерігати його. Команда виводить усі системні виклики, здійснені цим процесом і, за потреби, його нащадками. Останнє є важливим для процесів, що форкається, і etcd — один з таких процесів.

Перше, що ми зробили, – використали strace для вивчення сервера etcd у кластері Kubernetes, поки той простоював.

Так було виявлено, що блоки запису WAL дуже щільно згруповані, розмір більшості лежав в діапазоні 2200-2400 байт. Саме тому у команді на початку цієї статті використовується прапор --bs=2300 (bs - Розмір в байтах кожного блоку запису в fio).

Зверніть увагу, що розмір блоків запису etcd може змінюватись в залежності від версії, deployment'а, значень параметрів і т.д. - Це впливає на тривалість fdatasync. Якщо у вас схожий сценарій використання, проаналізуйте за допомогою strace свої процеси etcd отримати актуальні значення.

Потім, щоб отримати чітке та всеосяжне уявлення про роботу etcd з файловою системою, ми запустили її з-під strace з прапорами -ffttT. Це дозволило охопити процеси-нащадки і записати виведення кожного окремий файл. Крім того, були отримані докладні відомості про момент старту та тривалість кожного системного виклику.

Ми також скористалися командою lsofщоб підтвердити своє розуміння висновку strace у плані того, який файловий дескриптор для якої мети використовувався. Вийшов висновок strace, схожий на те, що наведено вище. Статистичні маніпуляції з часом синхронізації підтвердили, що метрика wal_fsync_duration_seconds від etcd відповідає викликам fdatasync із дескрипторами файлів WAL.

Щоб згенерувати за допомогою fio робоче навантаження, аналогічне навантаженню від etcd, було вивчено документацію утиліти та підібрано параметри, що підходять нашому завданню. Ми переконалися, що задіяні потрібні системні виклики, і підтвердили їх тривалість, запустивши fio з strace (Як це було зроблено у випадку etcd).

Особливу увагу було приділено визначенню значення параметра --size. Він являє собою загальне навантаження I/O, що генерується утилітою fio. У нашому випадку це повна кількість байтів, записана на носій. Воно прямо пропорційне числу викликів writefdatasync). Для певного bs кількість викликів fdatasync одно size / bs.

Оскільки нас цікавив процентиль, ми прагнули до того, щоб кількість проб була досить великою для статистичної значущості. І вирішили, що 10^4 (що відповідає розміру 22 Мб) буде достатньо. Найменші значення параметра --size давали більш виражений шум (наприклад, виклики fdatasync, які займають набагато більше часу, ніж зазвичай, і впливають на 99%).

Справа за вами

У статті показано, як за допомогою fio можна оцінити, чи досить швидким носій, призначений для використання з etcd. Тепер справа за вами! Дослідити віртуальні машини зі сховищем на базі SSD можна у сервісі IBM Cloud.

PS від перекладача

З готовими прикладами використання fio для вирішення інших завдань можна ознайомитись у документації або безпосередньо в репозиторії проекту (Там їх представлено набагато більше, ніж згадується у документації).

PPS від перекладача

Читайте також у нашому блозі:

Джерело: habr.com

Додати коментар або відгук