Комментарии 165
Как раз будем мерить производительность хранилищ.
А не подскажете, где можно об этом подробнее почитать?
Список доступных алгоритмов:
$ find /lib/modules/3.2.0-30-generic-pae/ -name «tcp_*»
/lib/modules/3.2.0-30-generic-pae/kernel/net/ipv4/tcp_htcp.ko
/lib/modules/3.2.0-30-generic-pae/kernel/net/ipv4/tcp_scalable.ko
/lib/modules/3.2.0-30-generic-pae/kernel/net/ipv4/tcp_yeah.ko
/lib/modules/3.2.0-30-generic-pae/kernel/net/ipv4/tcp_highspeed.ko
/lib/modules/3.2.0-30-generic-pae/kernel/net/ipv4/tcp_bic.ko
/lib/modules/3.2.0-30-generic-pae/kernel/net/ipv4/tcp_diag.ko
/lib/modules/3.2.0-30-generic-pae/kernel/net/ipv4/tcp_probe.ko
/lib/modules/3.2.0-30-generic-pae/kernel/net/ipv4/tcp_vegas.ko
/lib/modules/3.2.0-30-generic-pae/kernel/net/ipv4/tcp_veno.ko
/lib/modules/3.2.0-30-generic-pae/kernel/net/ipv4/tcp_westwood.ko
/lib/modules/3.2.0-30-generic-pae/kernel/net/ipv4/tcp_hybla.ko
/lib/modules/3.2.0-30-generic-pae/kernel/net/ipv4/tcp_illinois.ko
/lib/modules/3.2.0-30-generic-pae/kernel/net/ipv4/tcp_lp.ko
Рекомендую вот эту книгу: https://intronetworks.cs.luc.edu/
Начиная с 17й главы много полезной информации о том как tcp работает
Спасибо конечно =Ъ, но низкий поклон, шаркая ножкой.
На мой взгляд измерять его производительность вообще бессмысленно, потому что операции к нему как к блочному устройству никогда не завершаются. Убедитесь глядя в blktrace.
Собственно, я его использовал для отладки сетевого стека — IO на него я полагал в пределах производительности СХД равным бесконечности, т.е. весь возникающий оверхед был связан с параметрами tcp, iscsi target'а и initiator'а.
Я всего лишь написал про методологию измерения производительности дисковой подсистемы, не более. Ну как бы если бы в автомобильном топике объясняли, что величина «секунд до сотни» важнее, чем «число лошадей».
Если пересказать кратко, то: создание RAID массива из нескольких дисков приводит к тому, что операция записи становится «дороже», вызывает более чем одну операцию ввода-вывода.
От себя дополню, что обычно сначала считаю теоретическую производительность, затем гоняю тесты. Если теория не сходится с практикой в разы — что-то где-то настроено криво. Если сходится с погрешностью в процентов 5 — всё отлично.
Кроме того, «как померить» — хороший вопрос. Ещё более хороший вопрос: как предсказать %)
Пока что позвольте вам не поверить, что вы с sata'шного диска можете получить 300 IOPS с 10мс latency.
Оно такое нужно?
Это всё равно, как если бы магазин гордился, что обслуживает вместо 40 человек в час 300, но эти триста в очереди по полтора часа стоят.
Насчёт рейда — да, с некоторыми оговорками: время записи на него равно max() от времени записи на диски (т.к. все приличные рейды пишут параллельно). Наличие write-back кеша хоть какого-то размера обычно нивелирует этот аспект. Разумеется, речь про mirror'ы, для 5-6 важнее оверхед по процессору.
Мне чаще приходится обходиться более-менее адекватным предсказанием производительности железки. Тесты производительности мне потом несколько бесполезны: денег на изменение конфигурации всё равно не дадут. Хотя, конечно, по итоговой конфигурации мы проходимся небольшим тестом, чтобы убедиться, что конфигурация всей хранилки верна и производительность соответствует расчётной.
А сколько Очень Умных Интеграторов так же берут с потолка показатели «иопсов на пользователя», но не признаются в этом?
Говорить же про «статистику реальных инсталляций» в условиях публичного облака — нонсенс.
Завтра придёт жадный человек, который себе выставит параметры MOD в 16Мб и будет бесконечно свопиться. А послезавтра придёт человек с кеширующим в память сервером, у которого всего IO — прочитать один раз да логи с dmesg'ом писать.
И нагрузка у них будет несопоставимая — минимум на порядок разница. Сейчас мы можем предоставить на виртуалку порядка 3-8кIOPS, но сколько человек их потребляют?
В условиях облака вся нагрузка воспринимается как белый шум, идущий на storage. И планирование идёт именно из характеристик интегрированной нагрузки. Да даже не планирование, а простой принцип «утилизация к 50% подобралась — надо железо заказывать, чтобы к 70% его ввести в продакт».
Ну вы поняли.
С точки зрения публичного облака, эти виртуалки:
а) появляются и исчезают случайным образом (по воле клиентов)
б) дают такую нагрузку, которую захотелось владельцу ресурса, и с ним нет никакой связи (никаких предварительных согласований типов нагрузки и т.д.)
в) их безумно много. Настолько, что даже самый крупный клиент не заметен на фоне остальной массы.
В этих условиях пытаться предсказывать нагрузку в режиме белого ящика — это страдать фигнёй.
Предсказываем в режиме чёрного ящика (т.е. есть график — по нему и работаем).
Под «белым шумом» я имел в виду, что невозможно как-то разделить «вот это трафик БД, вот это трафик веб-сервера, а вот это трафик стримкастинга». Понятно, что у нас есть вполне чётко ощутимая область горячих и тёплых точек и есть огромная масса лежащих гигабайт, к которым месяцами не обращаются.
Насчёт «чтение доминирует над записью» — нет, т.к. у виртуалок свои кеши, и чаще всего чтение хорошо закешировано со стороны клиента. (есть и обратная сторона — прошедшие операции чтения — т.к. «холодное чтение», то есть нифига не кешируемое и самое проблемное).
Белый шум — я имел в виду, что мы не выделяем конкретных приложений. Идёт «поток», этот поток обслуживается. Все виды анализа — только статистические (и вот тут человек в комментариях подсказал blktrace, будем и его использовать), без попытки вникать в предметную область клиентов.
Увы, это всё фантазии.
В качестве тестов(параллельно с fio) используем еще нагрузку ORION Oralcle, утилита бесплатна и предоставляет различные варианты операций с дисками, ну и предполагает эмуляцию работы БД(Oracle'овой как минимум). Есть ли у вас опыт работы с этим тестом — интересно мнение?
В условиях же случайной и заранее неизвестной нагрузки, лучше работать с тестами worst case.
Плюс я не увидел у него latency в выводе, т.е. смысла в этой утилите никакого.
Что можно сказать про диск, у которого вот такие попугаи:
RTR: 2091.45 KiB/s Transfer time: 00:00:31 IOPS: 522.86
В параллель — да, нету.
Чтение после записи — ну если размер тестируемой области достаточно большой, кеши можно пробить.
Латентность я смотрел отдельно системными утилитами, да, не так удобно, но количественные показатели можно понять.
Без latency ни один тест не интересен. Потому что тот же wd green аж под 90 IOPS выдаёт.… При latency в 500мс.
Сейчас, когда я на эту тему два года потратил, я могу сказать, что fio реализует 90% нужного функционала.
Я бы не отказался от функции «мерять число IOPS'ов при фиксированной latency», то есть автоматический подбор числа iodepth, но даже без этого оно неплохо.
Вторая претензия к fio — немного неровный рандом, который явно задирает производительность к концу теста.
Вот я потому и пишу, что надо график от латентности строить (собственно я это говорил еще два года назад, но у меня не было средств/желания/времени такое соорудить). тогда будет видно, какие iops мы можем получить в хорошей области (до 10, до 20 мс), а какие за пределами.
1920 дисков в 6/60ом рейде с хотспарами будет примерно (утрирую) 1700 дисков полезных. Итого 1728*146=252Тб.
По нашим ценам это будет приносить 4.5р*252=1134р/час. То есть примерно 9.9 миллиона в год. При полной загрузке. Стоимость железки 174 миллиона. Итого — 17 лет окупаемости.
Я, конечно, лукавлю, IOPS'ы вполне приносят деньги. Но даже если мы утроим годовую выручку, всё равно это нерентабельно. (А ещё надо не забывать про клиентов, которые «положили диск и забыли», т.е. IO не генерируют).
Рынок IaaS уже достаточно сформировавшийся, чтобы цены на нём диктовались не себестоимостью.
И указанное решение в эту цену не укладывается.
«1920 дисков 146GB 15K RPM»
и этому противопоставляется
нетапп с
«432 диска 450GB 15K RPM».
Цена для такой демпинговой услуги — очень важна. И если они будут покупать готовые сторы — у них взлетит или единомоментно цена на диск в облаке (причем сразу раз в 10-20), или уменьшится время окупаемости — а это не интересно инвесторам.
Но существует довольно подробное «описание словами», по которому, при T -> бесконечность можно попробовать его реверсинжинирить.
Или, по крайней мере, взять из него полезное относительно workload. Это конечно не будет бенчмарком SPC-1, в смысле полученными результатами нельзя будет меряться с результатами официального SPC-1, но внутри себя — как вариант.
В среднем одна коробочка (4U) показывает примерно 6-10к IOPS.
Я бы не отказался от функции «мерять число IOPS'ов при фиксированной latency», то есть автоматический подбор числа iodepth, но даже без этого оно неплохо.
Сейчас (спустя 2 года) такая возможность есть:
# Test job that demonstrates how to use the latency target
# profiling. Fio will find the queue depth between 1..128
# that fits within the latency constraints of this 4k random
# read workload.
[global]
bs=4k
rw=randread
random_generator=lfsr
direct=1
ioengine=libaio
iodepth=128
# Set max acceptable latency to 500msec
latency_target=500000
# profile over a 5s window
latency_window=5000000
# 99.9% of IOs must be below the target
latency_percentile=99.9
[device]
filename=/dev/sda
Собственно — у нас хранилище выдаёт примерно 50-80Мб/с на виртуалку при 4-8к IOPS (latency <10), рядом у меня лежит WD green, который выдаёт 110Мб/с при 40 IOPS и latency >20. Кто из них быстрее?
PS NL-storage (write once, read rare) отдельный мир. Я с ним в продакте не имел дела, по своей домашней коллекции, о которой я думаю, там ключевым фактором является надёжность, цена, энергопотребление и время первого доступа.
Я говорю: если делать бэкап LUN'а, который сильно занят, то для него процесс чтения (вроде бы линейный) будет мало отличаться от рандомного IO, т.к. в очереди будет дофига других запросов.
Потому и непонятно отчего все еще «копирование BD-рипа в Тоталкоммандере» все еще (часто) используется в качестве измерения параметра диска.
— ничего не сказано про такой параметр как утилизация дисков. В случае если мы говорим об отдельном диске — это легко меряется. Например вот тут, слайды 12-15
www.ruoug.org/events/20091111/perf_IO_presentation.pdf
— про SAN/ NAS ни разу не надо тестить с нескольких серверов. Один сервер запросто генерит такую нагрузку чтобы напрочь убить любую дисковую подсистему. Характер нагрузки при этом легко настраивается увеличением числа параллельных потоков.
Утилизация на сторе росла, общая латенси тоже, но всё в пределах нормы (т.е. latency <10мс). Когда я начал играться с TCP, я добился, что единичный хост стал выжимать до 36к IOPS, но это был потолок (потом я подумал и вернул обратно — 15к на хост выглядит более чем разумно).
Если вы думаете, что единичный сервер может положить любую дисковую подсистему — добро пожаловать к нам в облако. За ваши деньги — неограниченные IOPS'ы. Заметим, без затруднений для клиентов вокруг.
Спасибо, за предложение, но у меня есть собственный опыт на эту тему. Обычный proliant с двумя 4GB карточками запросто генерит 60,000 IOPS, и это далеко не предел, так как мы уперлись на стороне массива.
По поводу вашего теста, надо смотреть детали. Я не уверен какой массив вы тестировали, но видимо какой-то большой.
То есть чтобы давать 36k IOPS при ~120 IOPS/диск вам нужно ~ 300 физических дисков.
а) клиента, который «just for fun» способен выжрать все ресурсы хранилища и нужно будет специально мутить с cgroups, чтобы его в этом порезать (и резать, заметим, ресурсами dom0, за которые клиент не платит).
б) Повышение цены СХД
Зачем?
Я сначала когда наткнулся на проблему «хост не может выжрать весь стор» очень переживал, оптимизировал. А потом осознал простую вещь: мне на халяву (с учётом tcp offload в сетевуху) достался мягкий и добрый шейпер, который гарантирует, что клиент не выжрет все ресурсы стора.
Существующих попугаев на виртуалку (от 3к до 8к IOPS при latency <10) я считаю более чем достаточным для того, чтобы сказать «у нас в облаке офигенная СХД». (И да, если вы меня пнёте по поводу старых аварий, мы учли ошибки, и старые хранилища имели… м… нюансы, я говорю про то, что мы начали деплоить в сентябре, и куда сейчас перенесены все клиенты, кроме одного упирающегося).
Спасибо за статью!
А вот почему я выбираю тот или иной стиль при письме, то это мои уже, как автора, проблемы, правда?
Ровно так же использовал «попугаи» вместо «показателей». Это нарекания не вызвало?
test: (g=0): rw=randread, bs=4K-4K/4K-4K, ioengine=libaio, iodepth=2 fio 1.59 Starting 1 process Jobs: 1 (f=1): [r] [100.0% done] [1248M/0K /s] [312K/0 iops] [eta 00m:00s] test: (groupid=0, jobs=1): err= 0: pid=9600 read : io=31250MB, bw=1254.3MB/s, iops=321091 , runt= 24915msec slat (usec): min=1 , max=110 , avg= 1.96, stdev= 0.27 clat (usec): min=3 , max=396 , avg= 3.46, stdev= 0.57 lat (usec): min=5 , max=398 , avg= 5.55, stdev= 0.62 bw (KB/s) : min=1198448, max=1319824, per=100.05%, avg=1285045.39, stdev=23648.81 cpu : usr=35.92%, sys=63.93%, ctx=43, majf=0, minf=22 IO depths : 1=0.1%, 2=100.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued r/w/d: total=8000000/0/0, short=0/0/0 lat (usec): 4=54.65%, 10=45.34%, 20=0.01%, 50=0.01%, 100=0.01% lat (usec): 250=0.01%, 500=0.01%
«Для HDD нет разницы запись или чтение, важно, что головки гонять по диску.»
— разница всё-таки есть — при чтении сам процесс чтения начинается раньше, когда головка над нужной дорожкой всё еще продолжает дрожать из стороны в сторону после позиционирования. При записи контроллер дожидается устаканивания головки над дорожкой. Плюс мелкая вибрация диска из вне (плохой крепеж, соседний диски, дивидюк) могут сильно снизить общую скорость записи.
youtu.be/tDacjrSCeq4
# eix sys-block/fio |grep Homepage
Homepage: brick.kernel.dk/snaps/
на домашнюю страничку не тянет, зато есть все версии fio, blktrace и других утилиток
yum.aclub.net/pub/linux/centos/6/umask/x86_64/fio-2.0.10-1.el6.x86_64.rpm
clat (usec): min=244, max=140717, avg=39278.48, stdev=7872.94
а на втором — в msec:
clat (msec): min=15, max=534, avg=267.07, stdev=38.65
Конечно можно ручками пересчитать, но хотелось бы видеть разницу наглядно без калькулятора.
А дальше удачи в парсинге вывода. Я недавно занялся вопросом, вот результат:
github.com/amarao/fio_minimal_csv_header
# fio --minimal ./test.ini
readtest;0;0;329940;11259;30006;3;89;5.515827;1.196062;282;221438;11633.393635;33859.575791;6586;14152;102.853479%;11308.740000;2122.336812;0;0;0;0;0;0.000000;0.000000;0;0;0.000000;0.000000;0;0;0.000000%;0.000000;0.000000;0.359940%;2.266289%;82454;0;54;0.1%;0.1%;0.1%;0.1%;0.1%;100.0%;0.0%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.94%;2.62%;2.29%;9.28%;18.62%;54.01%;9.13%;0.04%;0.01%;3.06%;0.00%;0.00%;0.00%;0.00%;0.00%
writetest;0;0;0;0;0;0;0;0.000000;0.000000;0;0;0.000000;0.000000;0;0;0.000000%;0.000000;0.000000;270364;9222;30019;4;79;6.516948;1.286312;310;257231;14203.332204;37032.724029;5929;12208;102.718885%;9250.862745;1745.055266;0.199880%;2.238657%;67554;0;22;0.1%;0.1%;0.1%;0.1%;0.1%;100.0%;0.0%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.00%;0.32%;2.25%;1.84%;7.67%;14.94%;44.06%;24.89%;0.29%;0.01%;3.73%;0.01%;0.00%;0.00%;0.00%;0.00%
Понятно, что это можно распарсить и вывести в более наглядном виде, но в целом пока устраивает текущий вывод. Т.е. в обычном выводе зафиксировать величины для вывода цифр нельзя никак?
И по поводу github.com/amarao/fio_minimal_csv_header — можете поподробнее расписать как им пользоваться? Насколько я понял, ему на вход нужно скормить вывод «fio --minimal», а на выходе он их должен оформить в каком-то более-менее приглядном виде?
It do not do anything useful. It's just repository for CSV header. You should convert fio ouput from 'semicolon' to comma based (|tr ';' ',') and append header to it. After that you can open result in any table editor (Excel, Gnumeric) and see results as a table with header.
Otherwise, one can writes simple program to parse CSV output of fio to extract specific fields. They are listed in github.com/amarao/fio_minimal_csv_header/blob/master/fio_field_names.txt.
Поэтому в дополнение к статье было бы очень здорово увидеть несколько готовых конфигов к fio по разным видам нагрузке для быстрого определения производительности текущей конфигурации и сравнения с альтернативными решениями. Ну и, обязательно, с краткой инструкцией «куда смотреть» чтобы было понятно какие параметры являются ключевыми.
Например, сразу в голову приходят 4 теста:
1. Хостинг сайтов: куча мелких файлов объемом 1-500 кб, 98% конкурирующих запросов на чтение всего файла, 2% запросов на запись всего файла.
2. База данных: несколько больших файлов в несколько гб, 70% конкурирующих запросов на чтение куска файла, 30% запросов на запись куска файла.
3. Файловое хранилище: много файлов разного объема от 1 мб до нескольких гигабайт, 80% на чтение полного файла, 20% на запись полного файла.
4. Хранилище бекапов: много файлов разного объема от 1 мб до нескольких гигабайт, 5% на чтение полного файла, 95% на запись полного файла.
И, может быть, спустя 2 года с момента публикации этой статьи у вас появились какие-то дополнительные методы тестирования производительности дисков, чтобы сделать более свежую статью на эту же тему? ;)
с) Не забывайте обнулять диск перед тестом (т.е. dd if=/dev/zero of=/dev/sdz bs=2M oflag=direct)
с учётом засилия ssd, совет вредный. большинство ssd воспринимают это как trim, помечают у себя сектора как свободные и обращения к NAND при чтении не происходит. думаю, что многие СХД поступают так же (или хотя бы используют сжатие, что уменьшит дисковый обмен в мегабайтах в секунду и помешает нам обнаружить bus saturation).
Как раз наоборот, чем умнее контроллеры, тем важнее при бенчмарке заставить контроллеры не умничать. Вас же интересуют sustained (постоянные?) показатели производительности, а не пиковые. Для этого надо создать условия, близкие к нагрузке на 100500 день работы — т.е. запись не в "новые" блоки, а в уже давно заполненные.
К совету про обнуление я сейчас бы добавил запись рандомом, потому что вендоры не лыком шиты и любят делать трим для нулей сами.
К совету про обнуление я сейчас бы добавил запись рандомом, потому что вендоры не лыком шиты и любят делать трим для нулей сами.
так я про то и говорю, только почему добавить, а не заменить? я просто перед тестом делаю dd if=/dev/urandom of=/dev/xxx
.
если уж нужно обнуление (хотя из магазина ssd обычно чистыми приходят), есть blkdiscard
.
Как правильно мерять производительность диска