
Кратка история за fio и etcd
Производителността на клъстера в значителна степен зависи от производителността на неговото хранилище. etcd експортира някои метрики в , за да предостави необходимата информация за производителността на хранилището. Например, метриката wal_fsync_duration_seconds. : за да се счита, че хранилището е достатъчно бързо, 99-ят перцентил на тази метрика трябва да бъде под 10 мс. Ако планирате да стартирате клъстер etcd на Linux машини и искате да оцените дали вашето хранилище (например, SSD) е достатъчно бързо, можете да използвате — популярен инструмент за тестване на операции за вход-изход. Изпълнете следната команда, където test-data е директория под точката на свързване на хранилището:
fio --rw=write --ioengine=sync --fdatasync=1 --directory=test-data --size=22m --bs=2300 --name=mytestПросто трябва да прегледате резултатите и да проверите, че 99-ят перцентил на продължителността е под 10 мс. Ако е така, имате достатъчно бързо хранилище. Ето пример за резултати:
sync (usec): min=534, max=15766, avg=1273.08, stdev=1084.70
sync перцентили (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]Бележки
- Настроихме стойностите на параметрите —size и —bs за нашия конкретен сценарий. За да получите полезен резултат от fio, задайте вашите стойности. Откъде да ги вземете? Четете, .
- По време на тестването цялото натоварване за вход-изход идва от fio. В реален сценарий вероятно ще има и други записи в хранилището, освен тези свързани с wal_fsync_duration_seconds. Допълнителното натоварване ще увеличи стойността на wal_fsync_duration_seconds. Така че, ако 99-ят перцентил почти достига 10 мс, вашето хранилище няма да е достатъчно бързо.
- Вземете версия не по-ниска от 3.5 (предишните не показват перцентили на продължителността на fdatasync).
- По-горе е показан само фрагмент от резултатите от fio.
Дълга история за fio и etcd
Какво е WAL в etcd
Обикновено базите данни използват ; etcd също го използва. Тук няма да обсъждаме подробно дневника за предварителни записи (write-ahead log, WAL). Достатъчно е да знаем, че всеки член на кластера etcd го записва в постоянно хранилище. etcd записва всяка операция с двойки ключ-стойност (например, актуализация) в WAL, преди да ги приложи в хранилището. Ако между снимките един от членовете на хранилището аварийно спре и се рестартира, той може локално да възстанови транзакции от последната снимка по съдържанието на WAL.
Когато клиент добавя ключ в хранилището от двойки ключ-стойност или актуализира стойността на съществуващ ключ, etcd прави запис на тази операция в WAL, който представлява обикновен файл в постоянното хранилище. Преди да продължи обработката, etcd ТРЯБВА да е напълно уверен, че записът в WAL действително е станал. В Linux за това не е достатъчен един системен повик. , тъй като всъщност записът в физическото хранилище може да бъде отложен. Например, Linux може за известно време да съхранява записа на WAL в кеша в паметта на ядрото (например в кеша на страниците). И за да се уверим, че данните наистина са записани в постоянното хранилище, е необходим системен повик fdatasync след записа, а etcd точно това използва (както може да се види в резултата от работата , където 8 — това е дескрипторът на файла WAL):
21:23:09.894875 lseek(8, 0, SEEK_CUR) = 12808
21:23:09.894911 write(8, ". 20210220361223255266632$10 20103026"34"rn3fo"..., 2296) = 2296
21:23:09.895041 fdatasync(8) = 0За съжаление, записът в постоянното хранилище не минава веднага. Ако повикването fdatasync работи бавно, производителността на системата etcd спада. , че хранилището се смята за достатъчно бързо, ако в 99-ти процентил на повикванията fdatasync при запис в файла WAL отнемат по-малко от 10 мс. Има и други полезни метрики за хранилището, но в този пост говорим само за тази метрика.
Оценка на хранилището с помощта на fio
Ако трябва да оцените, дали вашето хранилище е подходящо за etcd, използвайте fio — много популярен инструмент за тестване на натоварване на вход-изход. Трябва да имате предвид, че дисковите операции могат да бъдат най-разнообразни: синхронни и асинхронни, множество класове системни повиквания и т.н. В резултат на това — fio е достатъчно сложен за използване. Той има множество параметри и различни комбинации от тях дават напълно различни работни натоварвания на вход-изход. За да получите адекватни цифри за etcd, трябва да се уверите, че тестовото натоварване на запис от fio е максимално близко до реалното натоварване от etcd при запис на файлове WAL.
Следователно, fio трябва, поне, да създава натоварване под формата на поредица последователни операции за запис във файл, всяка запис е системно повикване , следвано от системно повикване fdatasync. За последователни операции за запис fio се нуждае от параметър —rw=write. За да използва fio системно повикване write при запис, а не , трябва да зададете параметър —ioengine=sync. Накрая, за да се извиква fdatasync след всяко записване, трябва да добавите параметър —fdatasync=1. Двата други параметъра в този пример (—size и —bs) зависят от конкретния сценарий. В следващия раздел ще обясним как да ги настроите.
Защо именно fio и как научихме да го настройваме
В този пост описваме реален случай. Имахме клъстер v1.13, който наблюдавахме с Prometheus. etcd v3.2.24 беше разположен на SSD. Метриките за etcd показваха твърде високи закъснения за fdatasync, дори когато клъстерът не правеше нищо. Метриките бяха странни и ние не знаехме точно какво означават. Клъстерът се състоеше от виртуални машини, трябваше да разберем какъв е проблемът: в физическите SSD или в слоя на виртуализацията. Освен това често правехме промени в конфигурацията на хардуера и софтуера и ни трябваше начин да оценим резултатите от тях. Можехме да стартираме etcd при всяка конфигурация и да наблюдаваме метриките в Prometheus, но това беше твърде трудоемко. Търсехме достатъчно прост начин да оценим конкретна конфигурация. Искахме да проверим дали разбираме правилно метриките на Prometheus от etcd.
Но за да направим това, трябваше да решим два проблема. Първо, какъв е входно-изходният товар, който etcd генерира при запис в WAL? Какви системни повиквания се използват? Какъв е размерът на записите? На второ място, ако отговорим на тези въпроси, как можем да възпроизведем подобно натоварване с fio? Не забравяйте, че fio е много гъвкав инструмент с множество параметри. Решихме и двата проблема по един подход — с помощта на команди. и . lsof показва всички файлови дескриптори, използвани от процеса, и свързаните с тях файлове. А с помощта на strace можем да проучим вече стартиран процес или да стартираме процес и да го изучим. strace извежда всички системни повиквания от изследвания процес (и неговите подпроцеси). Последното е много важно, тъй като etcd използва точно такъв подход.
Първо, използвахме strace за изследване на сървъра etcd за Kubernetes, когато клъстерът не беше натоварен. Видяхме, че почти всички записи в WAL бяха с приблизително еднакъв размер: 2200–2400 байта. Затова в командата в началото на публикацията указахме параметър —bs=2300 (bs означава размер в байтове за всеки запис на fio). Обърнете внимание, че размерът на записа в etcd зависи от версията на etcd, доставката, стойностите на параметрите и т.н. и влияе на продължителността на fdatasync. Ако имате подобен сценарий, проучете вашите процеси etcd с помощта на strace, за да получите точните числа.
След това, за да си представим действията във файловата система на etcd, я стартирахме със strace и с параметри -ffttT. Така се опитахме да проучим подпроцесите и да запишем изходните данни от всеки от тях в отделен файл, а също така да получим подробни отчети за началото и продължителността на всяко системно повикване. Използвахме lsof, за да потвърдим нашия анализ на изходните данни от strace и да видим кой файлов дескриптор за какви цели е използван. Така с помощта на strace получихме резултатите, показани по-горе. Статистиката за времето за синхронизация потвърди, че показателят wal_fsync_duration_seconds от etcd съвпада с повикванията на fdatasync с файловите дескриптори на WAL.
Проучихме документацията на fio и избрахме параметри за нашия сценарий, за да генерираме натоварване, подобно на това на etcd. Също така проверихме системните повиквания и тяхната продължителност, стартирайки fio от strace, подобно на etcd.
Внимателно подбрахме стойността на параметъра —size, който представлява цялото входно-изходно натоварване от fio. В нашия случай това е общият брой байтове, записвани в хранилището. Той се оказва право пропорционален на броя системни повиквания write (и fdatasync). За определена стойност bs броят на повикванията fdatasync = size/bs. Тъй като ни интересуваше перцентил, трябваше да имаме достатъчно проби за достоверност и изчислихме, че ще ни е достатъчно 10^4 (т.е. 22 мебибайта). Ако —size е по-малко, могат да възникнат отклонения (например, няколко повиквания fdatasync отнемат повече време от обикновено и влияят на 99-ия перцентил).
Опитайте сами
Показахме как да използвате fio и да проверите дали хранилището разполага с нужната скорост за висока производителност на etcd. Сега можете да опитате това на практика сами, например, използвайки виртуални машини с хранилище SSD в .
Източник: habr.com
