Производительность Ceph

Материал из YourcmcWiki
Перейти к: навигация, поиск

Бенчмаркинг

Основные направления тестирования:

  • Линейное чтение/запись (большими блоками)
  • Случайное чтение/запись (транзакционное и мелкими блоками)
  • Однопоточная нагрузка
  • Параллельная нагрузка

Сначала прогоните fio на голом диске:

  • Линейное чтение: fio -ioengine=libaio -direct=1 -invalidate=1 -name=test -bs=4M -iodepth=16 -rw=read -runtime=60 -filename=/dev/sdX
  • Линейная запись: fio -ioengine=libaio -fdatasync=1 -direct=1 -invalidate=1 -name=test -bs=4M -iodepth=16 -rw=write -runtime=60 -filename=/dev/sdX
  • IOPS-ы случайной записи: fio -ioengine=libaio -fdatasync=1 -direct=1 -invalidate=1 -name=test -bs=4k -iodepth=16 -rw=randwrite -runtime=60 -filename=/dev/sdX

«А почему так мало…» — см.ниже.

После сборки Ceph можно тестировать так:

  • IOPS на запись через rados bench в режиме, соответствующем RBD (4 Кб блоки в 4 Мб объектах, 128 параллельных запросов) — нетранзакционной нагрузке:
    rados bench -p ваш_пул -t 128 -b 4096 -o $((4096*1024)) 60 write
  • То же самое с транзакционной нагрузкой (например, СУБД): rados bench -p ваш_пул -t 1 -b 4096 -o $((4096*1024)) 60 write
    Примечание: способ признан плохим, так как оказалось, что rados bench в 1 поток создаёт всего лишь несколько объектов для тестирования — запись получается не очень-то «случайной».
  • Тем же самым fio через ioengine=rbd (здесь fdatasync не нужен): fio -ioengine=rbd -direct=1 -invalidate=1 -name=test -bs=4k -iodepth=128 -rw=randwrite -pool=rpool_hdd -runtime=60 -rbdname=testimg
  • Встроенной утилитой rbd bench --io-size 4096 --io-threads 64 --io-total 10G --io-pattern rand --io-type write rpool_hdd/testimg
  • Можно тестировать и fio изнутри виртуалки, rbd драйвер нормально создаёт параллельную нагрузку — проверено.
  • Производительность может отличаться на заполненном и незаполненном RBD-образе. Но отличия небольшие, думать, что там будет разница в несколько раз — не нужно.
  • При тестировании случайной записи в ceph в один поток (fsync/fdatasync/sync/iodepth=1/rados bench -t 1) вы фактически всё время тестируете ОДИН диск. То есть, всё время тестируются разные диски, но в каждый отдельный момент времени запрос идёт только к одной placement group (тройке-четвёрке-пятёрке дисков).
  • Соответственно, вы не увидите 100 % утилизации дисков на хостах при тестировании в один поток, однопоточная нагрузка не может полностью загрузить кластер.

Производительность случайной записи

Warning Warning: Сначала плохая новость!

Важная особенность Ceph — вся запись, даже та, для которой никто этого явно не просит, ведётся транзакционно. То есть, никакая операция записи не завершается, пока она не записана в журналы всех OSD и не сделан fsync() диска. Так сделано, чтобы предотвращать RAID WRITE HOLE-подобные ситуации рассинхронизации данных между репликами при отключении питания, потере сети и т.п…

Сама запись на устройство и репликация с других OSD происходит отложенно и асинхронно, но какая разница — она все равно создаёт дополнительную нагрузку на устройства и притормаживает последующие запросы.

Всё это приводит к тому, что типичная настольная SSD-шка в Ceph выдаёт неприлично низкие IOPS-ы — обычно от 500 до 2000. И это при том, что при обычном тестировании почти любая SSD выдаёт > 20000 iops. Даже самый паршивый китайский noname выдаёт не менее 10000 iops. NVMe легко выжимает 150000 и больше. Но стоит начать использовать fsync… и та же NVMe выдаёт 600 iops (на 2.5 порядка меньше).

Note.svg Старый FileStore на плохих дисках раза в 1.5 быстрее, чем BlueStore, так как он реже делает fsync. Но это не значит, что его надо использовать — по остальным параметрам FileStore устарел. Например, снапшоты там работают со скоростью снапшотов LVM (очень медленно), нет частичной перезаписи объектов в EC-пулах, нет контрольных сумм (вследствие чего вообще нельзя использовать size=2).

В общем, чтобы понять, сколько у вас будет IOPS-ов на запись в Ceph, диски под него нужно тестировать с опцией fio fsync=1. Или fdatasync=1, если тестируете поверх ФС. Или можно sync=1 iodepth=1, эффект обычно почти тот же, что от fsync=1. Разница между опциями (см. man fio):

  • fsync=1 синхронизирует данные и метаданные тестируемого файла после каждой операции записи. Именно так работает BlueStore. Именно поэтому мы будем использовать именно эту опцию.
  • fdatasync=1 синхронизирует только данные (но не метаданные) тестируемого файла после каждой операции записи. Соответственно, от fsync=1 это отличается, только если тестируется файл в ФС, а не блочное устройство.
    Note.svg fdatasync=1 надо использовать, когда на диске уже есть ФС, а прогнать тест хочется. Результаты будут достаточно корректными.
  • sync=1 использует синхронный ввод/вывод, то есть, каждая операция начинается после завершения предыдущей. Но штука в том, что почти все движки fio при этом открывают файл с O_SYNC. А вот O_SYNC уже означает, что каждая операция записи внутри сопровождается аналогом fsync. Но при этом если iodepth > 1, то в очередь диска до синхронизации «пролезает» несколько операций и IOPS-ы растут, тест перестаёт быть эквивалентным записи с fsync=1.

Конденсаторы!

Нас спасёт такое чудо инженерной мысли, как SSD с конденсаторами (точнее, обычно суперконденсаторами — ионисторами). Которые на M.2 SSD, кстати, прекрасно видны невооружённым глазом:

Micron 5100 sata m2.jpg

Конденсаторы работают фактически как встроенный в SSD ИБП и позволяют SSD успеть сбросить кэш во флеш-память при потере питания. Таким образом кэш становится «энергонезависимым» — и таким образом SSD может просто игнорировать запросы fsync, так как точно знает, что данные из кэша в любом случае доедут до постоянной памяти.

При этом IOPS-ы транзакционной записи становятся равны IOPS-ами нетранзакционной.

Конденсаторы в официальных описаниях SSD-шек обычно называются «enhanced/advanced power loss protection». Этой характеристикой обладают, как правило, только «серверные» SSD, да и то не все. Например, в Intel DC S3100 конденсаторов нет, а в Intel DC S4600 есть.

Note.svg Это и является главным отличием серверных SSD от настольных. Обычному пользователю транзакции нужны редко — а вот на серверах живут СУБД, которым транзакции как раз нужны позарез.

То есть, под Ceph следует закупать только SSD с конденсаторами. Даже если рассматривать NVMe — NVMe без конденсаторов хуже, чем SATA с оными.

И ещё один вариант — Intel Optane. Это тоже SSD, но они основаны не на Flash памяти (не NAND и не NOR), а вообще на другой технологии, называющейся 3D XPoint. Хз, как она работает, но заявляются 550000 iops при полном отсутствии необходимости в стирании блоков, кэше и конденсаторах. Но а) в применении к Ceph — нужно проверять — не факт, что Ceph вообще сможет выжать из них их iops-ы б) вариант дорогой, раза в 3 дороже типичной SSD (1500$ за 960 гб, 500$ за 240 гб).

Краткий экскурс в устройство SSD и флеш-памяти

Особенность флеш-памяти (NAND/NOR) заключается в том, что пишется она мелкими блоками (обычно 512 байт), но перед тем, как писать — блок нужно стереть. А вот стирать она умеет только крупные блоки («erase unit»), размером обычно 2-4 мегабайта (и стирание довольно медленное по отношению к записи). Кроме того, каждый erase unit ограничен числом стираний. После нескольких тысяч стираний (типичное значение для MLC) он физически выходит из строя. В более дешёвых чипах и MLC, TLC лимит стираний меньше, в более дорогих и SLC — больше. Таким образом, при «тупом» подходе перезапись флеш-памяти, во-первых, была бы очень медленной, а во-вторых, она бы быстро выходила из строя.

Но почему тогда SSD быстрые? А потому, что внутри SSD на самом деле есть очень мощный и умный контроллер (1-2 гигагерца, примерно как процессоры мобильников), и на нём выполняется нечто, что называется Flash Translation Layer — прошивка, которая переназначает каждый мелкий логический сектор в произвольное место диска. FTL всё время поддерживает некоторое количество свободных стёртых блоков, каждая случайная запись на самом деле идёт в новое место диска — в стёртую область, и поэтому запись быстрая. Одновременно FTL делает дефрагментацию свободного места и Wear Leveling (распределение износа), направляя запись и перемещая данные так, чтобы все блоки диска стирались примерно одинаковое количество раз.

Отсюда же вытекает и проблема с энергонезависимостью и «power loss protection»-ом — карты отображения секторов — это метаданные, которые при сбросе кэша тоже нужно сбрасывать в постоянную память. Именно эти карты и вносят торможение в работу настольных SSD с fsync.

Бонус: USB-флешки

А почему тогда USB-флешки такие медленные? Случайная запись на флешку 512-байтными (или 4 Кб) блоками обычно идёт со скоростью 2-3 iops. А флеш-память там ровно та же, что в SSD — ну, может, более дешёвые вариации, но разница же не на порядки. Ответ кроется в том, что на флешках тоже есть FTL (и даже Wear Leveling), но по сравнению с SSD-шным он маленький и тупой. У него слабый процессор и мало памяти. Из-за малого объёма RAM контроллеру флешки, в отличие от контроллера SSD, негде хранить полную таблицу сопоставления виртуальных и реальных секторов — поэтому отображаются не сектора, а крупные блоки где-то по мегабайту или больше, а при записи есть лимит на количество «открытых» блоков. Как это происходит:

  • Допустим, вы пишете в сектор X.
  • Контроллер отображает блок, которому принадлежит этот сектор, на реальный блок, и «открывает» его — выделяет пустой блок, запоминает, что он «дочерний» для открытого и записывает туда один изменённый вами сектор.
  • Таким макаром можно открыть максимум N разных блоков; число N обычно очень маленькое — от 3 до 6.
  • Дальше если вы пишете следующий сектор из уже открытого блока — он просто записывается в его дочерний блок (что быстро).
  • Если же следующий записываемый сектор принадлежит другому блоку — какой-то из открытых блоков приходится закрывать и «сливать» содержимое дочернего блока с оригинальным.

Для копирования больших файлов на флешку с любой из стандартных файловых систем этого достаточно: один открытый блок — данные, второй — метаданные записываемого файла. Запись последовательная, всё быстро. А вот при случайной записи вы перестаёте попадать в уже «открытые» блоки и каждая операция записи превращается в полное стирание. Тут-то и начинаются тормоза…

Пример теста

3 ноды по 3 SATA 7200rpm HDD, 10 гигабит ethernet. Ceph 13.2.1, bluestore.

rados bench EC-пула в 1/16/64/128 потоков:

  • Журналы на HDD: 40/100/350/450 iops
  • Журналы вынесены на старые серверные SSD (выдающие 22000 iops каждая): 170/620/720/940 iops

Итого при нетранзакционной нагрузке на ВМ стало быстрее в 2.1 раза, при транзакционной в 4.25 раза.

Модели

  • Micron серий 5100/5200
  • HGST SN260