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

Версия от 18:59, 6 ноября 2018; VitaliyFilippov (обсуждение | вклад)

Do you want to try some new features? By joining the beta, you will get access to experimental features, at the risk of encountering bugs and issues.

Ок Нет, спасибо

Бенчмаркинг

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

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

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

  • Перед тестированием отключите кэш записи диска: hdparm -W 0 /dev/sdX (прямое подключение SATA или SATA через HBA), . Не совсем ясно, почему, но эта операция на серверных SSD может увеличить IOPS-ы на 2 порядка.
  • Линейное чтение: 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 через RBD: 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 на плохих дисках быстрее BlueStore где-то в 1.5 раза; на хороших он менее латентный. Но это не значит, что его надо использовать — по остальным параметрам FileStore устарел. Например, снапшоты там работают со скоростью снапшотов LVM (очень медленно), нет частичной перезаписи объектов в EC-пулах, нет контрольных сумм (вследствие чего вообще нельзя использовать size=2). Также CPU filestore жрёт сильнее и пиковые параллельные IOPS-ы у него хуже bluestore.

В общем, чтобы понять, сколько у вас будет 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 гб).

Контроллеры

  • SATA — это нормально, SAS не обязателен от слова «совсем». SATA за счёт того, что «не умничает», достаточно быстрая и точно лучше, чем старые RAID контроллеры.
  • Разница в IOPS между RAID и HBA/SATA может быть колоссальна. В производительность не самого нового RAID контроллера легко упереться. Плохо даже не то, что на 1 диск вы получите 48000 iops вместо 60000, хуже то, что при подключении 8 дисков вы получите 6000 iops на каждый диск вместо 60000, так как 48000 поделятся на всех.
  • Так что свой RAID контроллер либо переключите в режим passthrough (если он умеет), либо перепрошейте, чтобы умел, либо выкиньте в помойку и купите HBA («RAID без RAID-функционала», например, LSI 9300-8i). Это актуально для всех видов программных хранилок — Ceph, ZFS и т. п.
  • У HBA тоже есть предел IOPS. К примеру, у LSI 9211-8i это ~280000 iops на весь контроллер.
  • Для SAS и NVMe можно попробовать включить blk-mq. Для SATA обычно бесполезно или почти бесполезно.
  • Фактическая глубина очереди, используемая Ceph OSD при случайной записи, редко больше 10 (посмотреть можно при работе утилитой iostat -xmt 1).

Оценка производительности кластера

Конечно, оценка производительности кластера просто по спецификациям входящих в него SSD не совсем верна, причём в обе стороны:

  • Bluestore, видимо, за счёт параллелизма, выдаёт чуть больше iops-ов даже на SSD без конденсаторов, чем просто те же ssd могут выдать с fsync — я лично смог добиться от тестового пула на 3-х Intel SSDSC2KW256G8 8000 iops, хотя сами ssd с fsync выдают типа 5500
  • И обратно, даже если SSD мегабыстрая, цеф — это огромный оверхед, он жрёт проц и никаких 220000 iops из одной SSD не выжмет. См. ниже #Пример теста от Micron — там в суперкрутом сетапе у них вышло всего 8750 iops в пересчёте на 1 NVMe (но это у них без SPDK/DPDK).
  • Правильное применение для всяких оптанов и супербыстрых NVMe это, видимо, журналы, но какое на практике увеличение iops-ов при добавлении условно оптана к тем же обычным серверным ssd — опять же, сходу не ясно.
  • Увеличение IOPS-ов Ceph обычно сопровождается увеличением жора CPU. CPU нужны хорошие. :)
  • Однопоточные IOPS-ы целиком и полностью зависят от задержек. Bluestore латентнее, чем filestore. С другой стороны, разница — условных 280 или 350 iops на дисках, которые сами по себе могут на порядок-два больше.
  • Лайфхак для ускорения однопоточной нагрузки: mdadm RAID 0 из RBD-образов внутри самой виртуалки.
  • Лайфхак для очень быстрых дисков: несколько OSD на одном диске.
  • Гипотетический монстр производительности в вакууме: мощные процы, Intel NVMe, Infiniband или Intel 25-40GbE, SPDK/DPDK.

Краткий экскурс в устройство 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 (распределение износа), направляя запись и перемещая данные так, чтобы все блоки диска стирались примерно одинаковое количество раз. Кроме того, во всех SSD некоторый % реального места зарезервирован под Wear Leveling («overprovision»), а в хороших серверных SSD этот процент весьма большой — например, в Micron 5100 Max это +60 % ёмкости.

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

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

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

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

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

Пример теста от Micron

Пример самолётного сетапа от Micron с процами по полляма, 100-гбит сетью и 10x NVMe (с конденсаторами, ага) в каждом узле, 4 узла, репликация 2x: https://www.micron.com/resource-details/30c00464-e089-479c-8469-5ecb02cfe06f

Всего 350000 iops на запись в пике на весь кластер, при 100 % загрузке CPU. Казалось бы, довольно много, но если поделить 350000/40 osd — получится 8750 иопс на 1 osd. С учётом репликации на диски нагрузка двойная, выходит, 17500 иопс. Ок, журналы тоже удваивают нагрузку, итого — 35000 iops на запись смог выжать ceph из одной NVMe… которая сама по спеке может 260000 иопс в одиночку. Вот такой вот overhead.

Пример теста 9x HDD

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