13 831
правка
Изменения
Нет описания правки
[[en:Ceph performance]][[File:Ceph-funnel.svg|500px|right]]
Ceph — это SDS (по-русски — программная СХД), которая по некоторым параметрам является уникальной в своём роде, и в целом, умеет очень многое — S3, диски виртуалок, кластерную FS + огромный багаж дополнительных фич.
И всё было бы хорошо — бери, ставь, запускай своё облако и руби бабло — если бы не один маленький нюанс: ПРОИЗВОДИТЕЛЬНОСТЬ. Терять 95 % производительности в Production-е разумным людям обычно жалко. «Облакам» типа AWS, GCP, Яндекса, по-видимому, не жалко — у них тоже собственные крафтовые SDS и они тоже тормозят примерно так же :-) но этот вопрос оставим — кто мы такие, чтобы их судить.
В данной статье описано, каких показателей производительности можно добиться от цефа и как. Если вкратце, то примерным ориентиром служит доклад Nick Fisk «Low-Latency Ceph», в его исполнении Low Latency это 0.7 мс (на запись). Лучший результат с Ceph-ом получить практически невозможно (худший — легко). При этом 0.7 мс — это всего лишь примерно ~1500 iops в 1 поток. На чтение в идеальной ситуации можно получить где-то раза в 2 больше, то есть где-то до 3000 iops в 1 поток.
Для сравнения: любой самый дешёвый серверный SSD-диск раз в 10 быстрее, средний порядок задержки SSD на запись — 0.01-0.04 мс, на чтение — 0.1 мс.
'''UPDATE: Догнать (почти догнать) SDS-кой локальной диск можно, я это сделал в своём собственном проекте — Vitastor: https://vitastor.io :-) это блочная SDS с архитектурой, похожей на Ceph, но при этом БЫСТРАЯ — в тесте на SATA SSD кластере задержка и чтения, и записи составила 0.14 мс. На том же кластере задержка записи у Ceph была 1 мс, а чтения — 0.57 мс. Детали в [https://yourcmc.ru/git/vitalif/vitastor/src/branch/master/README.md README] — смотрите по ссылке.'''
== Бенчмаркинг ==
Задержки обычно важнее простой пиковой производительности случайного чтения/записи, так как далеко не каждое приложение может загрузить диск при большом параллелизме / глубокой очереди (32-128 запросов).
=== Тестирование дисков ===
[https://docs.google.com/spreadsheets/d/1E9-eXjzsKboiCCX-0u0r5fAjjufLKayaut_FOPxYZjc SSD Bench Google Docs]
Сначала прогоните fio на голом диске:
* Задержка случайной записи: {{Cmd|1=fio -ioengine=libaio -sync=1 -direct=1 -invalidate=1 -name=test -bs=4k -iodepth=1 -rw=randwrite -runtime=60 -filename=/dev/sdX}}
«А почему так мало…» — см.нижесагу про конденсаторы.
[[Файл:Warning icon.svg|32px|link=]] Когда разворачиваете Ceph OSD на SSD — очень разумно не отдавать её под Ceph целиком, а оставить небольшой раздел (10-20 гб) пустым для будущего использования под бенчмаркинг. Ибо Ибо SSD имеют свойство со временем (или при забивании данными под 80%) начинать тормозить. Очень удобно иметь возможность гонять fio на пустом никем не используемом разделе. ==== Лирическое отступление ==== Почему нужно тестировать именно так? Ведь в целом производительность диска зависит от многих параметров:* Размер блока* Режим — чтение, запись или смешанный режим чтение+запись в разных пропорциях* Параллелизм — размер очереди и число потоков, то есть, в целом число одновременно запрашиваемых у диска операций* Длительность теста* Исходное состояние — пуст, заполнен линейной записью, заполнен случайной записью, заполнен случайной записью на протяжении какого-то времени и т. п.* Распределение данных — например, 10% горячих данных и 90% холодных — или, например, определённое расположение горячих данных (в начале диска)* Другие смешанные режимы тестов, например, тестирование одновременно с разными размерами блоков Также и результаты можно интерпретировать с разной степенью детализации — вместо простого среднего числа операций или мегабайт в секунду можно также приводить графики, гистограммы, перцентили и так далее — это, естественно, даст больше информации о поведении тестируемого образца. Есть и философская сторона тестов — например, производители серверных SSD иногда заявляют о необходимости подготовки диска к тестам путём 2-х кратной полной случайной перезаписи, чтобы нагрузить слой трансляции адресов диска, а я считаю, что это на самом деле ставит SSD в неправдоподобно плохие по сравнению с реальной нагрузкой условия; есть сторонники рисования графиков формата «задержка в зависимости от числа операций в секунду», что я считаю немного странным, но тоже возможным подходом — в нём, по сути, строится график F1(q) в зависимости от F2(q) и график обычно получается достаточно замысловатый — но для каких-то применений, может быть, и тоже разумный. В общем, бенчмаркингом заниматься можно бесконечно, и уж несколько дней, чтобы предоставить полную информацию, точно уйдёт. Этим обычно и занимаются ресурсы типа 3dnews в своих обзорах SSD. А мы не хотим сидеть несколько дней. Мы хотим обозначить набор тестов, которые можно провести быстро и сразу составить примерное представление о производительности. Посему общая идея — выделить несколько наиболее «крайних» режимов, протестировать диск в них и представить, что остальная часть «амплитудно-скоростной характеристики» диска является некоторой гладкой функцией в пределах изменения параметров между крайними точками. Тем более, что каждому из крайних режимов соответствует и реальное применение в своей категории приложений:# Использующих в основном линейный или крупноблочный доступ. Для таких приложений наиболее важная характеристика — производительность линейного доступа в мегабайтах в секунду. Отсюда режим тестирования линейным доступом 4 МБ блоком со средней очередью — 16-32 операции. Результаты — только в МБ/с.# Использующих случайный доступ мелким блоком и при этом способных к распараллеливанию. Отсюда — режимы тестирования случайным доступом 4 КБ блоком (стандартный блок для большинства ФС и, плюс-минус, СУБД) с большой очередью — 128 операций или, если диск не удаётся нагрузить одним потоком CPU с глубиной очереди 128 — тогда в несколько (2-4-8 или больше) потоков по 128 операций. Результаты — только в iops. Задержку (latency) указывать не нужно, так как в данном тесте её можно произвольно увеличить, просто подняв размер очереди — задержка жёстко связана с iops формулой latency=queue/iops.# Использующих случайный доступ мелким блоком и при этом НЕспособных к распараллеливанию. Таких приложений больше, чем вы могли подумать — например, в части записи сюда относятся все транзакционные СУБД. Отсюда вытекают режимы тестирования случайным доступом 4 КБ блоком с очередью 1 и, для записи, с fsync после каждой операции, чтобы диск/СХД не могли нас обмануть и положить запись во внутренний кэш. Результаты — iops или latency, по желанию — но выберите что-то одно, так как числа, опять же, жёстко связанные.
=== Тестирование кластера Ceph ===
Как тестировать Ceph после сборки:.
== О транзакционности записи ==
[[Файл:Warning icon.svg|32px|link=]] Плохая новость!
Важная особенность Ceph — ''вся запись, даже та, для которой никто этого явно не просит, ведётся транзакционно''. То есть, никакая операция записи не завершается, пока она не записана в журналы всех OSD и не сделан fsync() диска. Так сделано, чтобы предотвращать [[#RAID WRITE HOLE]]-подобные ситуации рассинхронизации данных между репликами при отключении питания, потере сети и т.п…
Это приводит к тому, что типичная настольная SSD под журналом в Ceph выдаёт '''неприлично низкие IOPS-ы''' — обычно от 500 до 2000. И это при том, что при обычном тестировании почти любая SSD выдаёт > 20000 iops. Даже самый паршивый китайский noname выдаёт не менее 10000 iops. NVMe легко выжимает 150000 и больше. Но стоит начать использовать fsync… и та же NVMe выдаёт 600 iops (на 2.5 порядка меньше).
В общем, чтобы понять, сколько у вас теоретически может быть IOPS-ов на запись в Ceph, диски под него нужно тестировать с опциями fio '''sync=1 iodepth=1'''. Это даст «журнальные» иопсы (производительность последовательного коммита операций по одной).
== Конденсаторы ==
Нас спасёт такое чудо инженерной мысли, как '''SSD с конденсаторами''' (точнее, обычно или с суперконденсаторами — ионисторами). Которые на M.2 SSD, кстати, прекрасно видны невооружённым глазом(только тут это не ионисторы :)):
[[File:Micron 5100 sata m2.jpg]]
То есть, под Ceph следует закупать '''только''' SSD с конденсаторами. Даже если рассматривать NVMe — NVMe без конденсаторов хуже, чем SATA с оными.
И ещё один вариант — Intel Optane. Это тоже SSD, но они основаны не на Flash памяти (не NAND и не NOR), а на Phase-Change-Memory «3D XPoint». По спецификации заявляются 550000 iops при полном отсутствии необходимости в стирании блоков, кэше и конденсаторах. Но если даже задержка такого диска и равна 0.01мс005мс (она действительно равна), то задержка Ceph всё равно как минимум в 50 раз больше0.5-1мс, соответственно, с Ceph оптаны использовать чуть менее, чем бессмысленно — за большие деньги (1500$ за 960 гб, 500$ за 240 гб) вы получите не сильно лучший результат.
== Bluestore vs Filestore ==
Блюстор — «новое» хранилище. От «нового» хранилища честно ожидаешь лучшей или хотя бы не худшей производительности в любых во всех сценариях. Однако это, увы, не совсем так.
*: И проблема не только в том, что параметры по умолчанию — deferred_batch_ops и max_deferred_txc — задают частый сброс операций на медленный диск (раз в 64 операции). Проблема ещё в том, что в Bluestore отсутствуют механизмы фоновой очистки «журнала» (очереди отложенной записи). Поэтому, когда очередь забивается, производительность просто падает до HDD-шной до перезапуска OSD. Ну и сама очередь находится в RocksDB, поэтому сильно поднимать её размер, по идее, неполезно.
* В До 1.5-2 раз хуже latency случайной записи на SSD/NVMe (All-Flash кластерах (то есть), ибо накладных расходов на быстрых дисках) каждую операцию записи у Bluestore латентнее больше.* Жор памяти больше. Да, у Filestoreмного занимал pagecache, возможно, на 30-50 %но Bluestore меньше 2 ГБ памяти не жрёт вообще никогда. Однако эти 30Причиной тому — RocksDB (одни только memtable-50 % относятся к latency именно самого блюстора, в абсолютном выражении составляют ~0.ы с дефолтными настройками съедают 1 мс ГБ памяти) и на фоне общей задержки Ceph-а практически собственный кэш метаданных и данных (Bluestore не заметны. Кроме того, latency ничего не говорит о параллельной пиковой пропускной способности, а она по крайней мере не хуже, чем в Filestore (обычно чуть лучше, +5..10 %может использовать pagecache). Жор CPU тоже чуть меньше.* Жор памяти у Bluestore ощутимо больше, потому что RocksDB и потому что кэш у него собственный вместо использования системного page cache-а, как в FilestoreФрагментация приводит к снижению скорости чтения.
Также BlueStore делает огромное количество fsync-ов (что очень смешно — даже больше, чем запросов записи), из-за чего не терпит десктопных SSD под журналом. Но FileStore работает похоже, и кардинальных различий производительности это не вносит. Как полечить медленный коммит высокие задержки на SSD+HDD?
* Либо вместо журнала (или рядом с журналом) сделать на SSD bcache для HDD.
* Либо использовать HDD с SSD Cache, Media Cache или аналогом (перманентным кэшем случайной записи на пластинах). Например, в старых дисках HGST это включается при отключении волатильного кэша командой `hdparm -W 0 /dev/sdXX`. В новых, похоже, включено всё время.
=== Про размер block.db ===
Дефолтные настройки цефа:
* 1 Гб WAL = 4x256 Мб
* max_bytes_for_level_base и max_bytes_for_level_multiplier не изменены, поэтому равны 256 Мб и 10 соответственно
* соответственно , L1 = 256 Мб
* L2 = 2560 Мб
* L3 = 25600 Мби т. д.
…Соответственно!
Rocksdb положит L2 на block.db, только если раздел имеет размер хотя бы 2560+256+1000 Мб (Мб — округлим вверх до '''4 Гб)ГБ'''. А L3 она положит на block.db, только если block.db размером хотя бы 25600+2560+256+1000 МБ = около '''30 ГБ'''. А L4, соответственно, если ещё +256 ГБ, то есть итого '''286 ГБ'''.
== Контроллеры ==
* Разница в IOPS между RAID и HBA/SATA может быть колоссальна. В производительность не самого нового RAID контроллера легко упереться. Плохо даже не то, что на 1 диск вы получите 48000 iops вместо 60000, хуже то, что при подключении 8 дисков вы получите 6000 iops на каждый диск вместо 60000, так как 48000 поделятся на всех. Также в RAID режиме увеличивается задержка в 1 поток.
* Так что свой RAID контроллер либо переключите в режим passthrough (если он умеет), либо перепрошейте, чтобы умел, либо выкиньте в помойку и купите HBA («RAID без RAID-функционала», например, LSI 9300-8i). Это актуально для всех видов программных хранилок — Ceph, ZFS и т. п.
* Если не выкинули RAID — отключайте все кэши контроллера, чтобы уменьшить влияние прослойки и не страдать при разряде батарейки / перемещении диска в другой сервер... и молитесь :). Наверное, в теории можно выжить и с включенным кэшем, но это стрельба себе в ногу.
* Даже если у вас HBA — имейте в виду, что некоторые HBA (в частности, Adaptec) могут всё равно не сбросить кэш корректно и устроить вам Cloudmouse при отключении питания. Но по крайней мере точно известно, что LSI ведут себя нормально.
* Хороший пост про RAID-кэши в списке рассылки: http://lists.ceph.com/pipermail/ceph-users-ceph.com/2019-July/036237.html - если вкратце - человек, админивший 6000 OSD, пишет, что никогда больше не свяжется с RAID0-режимами.
* У HBA тоже есть предел IOPS. К примеру, у LSI 9211-8i это ~280000 iops на весь контроллер.
* При подключении через SATA или HBA контроллер не забывайте для '''серверных''' SATA дисков сделать {{cmd|hdparm -W 0 /dev/sdX}}, для SAS — {{cmd|1=sdparm --set WCE=0 /dev/sdX}}.
* …Но менять их бесполезно, поднять производительность таким образом не получается абсолютно, дефолтные значения (1x5 на HDD и 2x8 на SSD) оптимальны. kv_sync_thread-то всё равно только один.
* Есть одна мера, которая помогает поднять производительность сразу раза в 2-3: отключение экономии энергии процессором:
** <tt>cpupower idle-set -D 10</tt> — отключает C-States (либо опции ядра processor.max_cstate=1 intel_idle.max_cstate=0)** <tt>cpupower frequency-set -g performance</tt> или (старое) <tt>for i in $(seq 0 $((`nproc`-1))); do cpufreq-set -c $i -g performance; done</tt> — отключает снижение частоты через множитель
* После этих двух команд процессор начинает греться как ПЕЧ, но iops-ы увеличиваются сразу раза в 2 (а то и 3)
* Также жор CPU — одна из причин НЕ делать из Ceph «гиперконвергентное облако» (в котором совмещены узлы хранения и запуска виртуальных машин)
* Ещё можно отключить все mitigation-ы аппаратных уязвимостей: noibrs noibpb nopti nospectre_v2 nospectre_v1 l1tf=off nospec_store_bypass_disable no_stf_barrier
== Сеть ==
* Разумеется, 10 Гбит/с или быстрее
* MTU 9000: ip l set enp3s0f0 mtu 9000
* Отключить оффлоады: ethtool -K enp3s0f0 gro off gso off tso off lro off sg off
* Отключить объединение прерываний: ethtool -C enp3s0f0 rx-usecs 0
* Самый дешёвый 10G свитч с Ebay: Quanta LB6M / Brocade TurboIron 24X — но говно старое унылое и жрёт под 200 ватт, и греется и жужжит соответственно
* UPD Самый дешёвый свитч с Aliexpress: [https://aliexpress.ru/item/1005004429524441.html TP-LINK TL-ST5008F]. На чипе [https://www.realtek.com/en/products/communications-network-ics/item/rtl9303-cg Realtek RTL9303-CG]
Если совсем задолбала латенси, как отключить ВСЕ оффлоады?
<pre>
for i in rx tx tso ufo gso gro lro tx nocache copy sg txvlan rxvlan; do
/sbin/ethtool -K eth3 $i off 2>&1 > /dev/null;
done
</pre>
== Настройка виртуалок и ФС ==
С дефолтными опциями qemu подключает RBD, увы, криво.
Криво — это значит, что:
: а) используется медленная эмуляция lsi-контроллера
: б) неправильно настроен кэш
=== Драйвер виртуального диска и ФС ===
В qemu есть следующие способы эмуляции дисков:
* lsi — самый медленный
* virtio — самый быстрый, но до QEMU 4.0 не умел TRIM. Юзать надо его.
* virtio-scsi — достаточно быстрый. На самом деле, умеет multiqueue и поэтому на быстром хранилище (например, при прямом доступе к локальной NVMe) должен быть быстрее virtio — но в случае с Ceph это не так, так как цеф не настолько быстрый, чтобы multiqueue играл роль
* nvme — тоже достаточно быстрый, но немного медленнее virtio. Принцип работы похожий — и там, и там кольцевые буферы. Можно использовать для тех образцов ПО, которые не умеют virtio, потому что не уметь nvme сейчас совершенно точно не может никто. Например, если хочется потестировать VMWare ESXi с вложенной виртуализацией внутри QEMU, то nvme — для вас!
=== cache=writeback ===
Кэш дисков в qemu регулируется опцией, собственно, cache. Бывает <не указано>, writethrough, writeback, none, unsafe, directsync.
С Ceph RBD эта опция регулирует работу rbd cache, то есть кэша на стороне клиентской библиотеки Ceph (librbd). RBD cache маленький (32 МБ) и является аналогом буфера записи на HDD, то есть, предназначен исключительно для группировки операций записи перед, собственно, отправкой их в хранилище.
Режимы writethrough, <не указано> и directsync с RBD, по сути, эквивалентны и означают отсутствие кэширования записи (каждая операция отправляется сразу в Ceph).
Режим writeback означает «честное» (безопасное) кэширование записи. То есть, операции записи без fsync ложатся в кэш и отправляются оттуда либо раз в rbd_cache_max_dirty_age (по умолчанию 1 сек), либо когда ВМ просит fsync.
Режим unsafe означает «нечестное» (чреватое потерей данных) кэширование записи. Операции записи также ложатся в кэш, но fsync от ВМ игнорируются. Транзакционность в виртуалке отсутствует, но и производительность повышается. Использовать этот режим можно только для виртуалок, не содержащих ценные данные (например, для каких-нибудь тестов или CI).
При среднем применении правильный режим — '''cache=writeback'''. Грубо говоря, cache=writeback увеличивает результат следующего теста:
fio -name=test -ioengine=libaio -direct=1 -bs=4k -iodepth=1 -rw=randwrite -filename=/dev/vdb # без -fsync и без -sync
…примерно приводя его к результату того же теста с <tt>iodepth=32</tt>.
{{Note}} ОДНАКО, есть НЮАНСЫ (как всегда с цефом…):
* Если RBD-образ пустой и при этом на нём включён object-map (по умолчанию включён, см. <tt>rbd info <pool>/<image></tt>), то сброс кэша становится однопоточным И ФИГ ВЫ ВИДИТЕ улучшение результата fio.
* Если опция rbd_cache_writethrough_until_flush равна true (так по умолчанию), то до первого fsync кэш не работает. То есть, если вы монтируете к виртуалке диск и сразу тестируете его вышеприведённой командой — вы опять-таки не увидите хороших результатов.
* Из-за той же опции, стоящей в true, cache=unsafe не работает вообще. В Proxmox включен патч, который заставляет qemu ставить эту опцию автоматически. Если у вас не Proxmox — опцию нужно прописать в конфиг глобально: rbd_cache_writethrough_until_flush=false.
* Сам кэш может являться тормозом в SSD-кластерах. Что-то там сделано с блокировками, что-то там однопоточное, всё это оптимизируют, но пока не оптимизировали. Например, 4K randwrite Q128 с rbd_cache=false может достигать 20000 iops, а с rbd_cache=true — только 11000 iops. Для говнософта, который пишет на диск абы как, это торможение оправдано, а для, например, СУБД — нет. Поэтому в случае, если у вас SSD и вам нужны в первую очередь random iops, то правильный режим — '''cache=none'''.
=== ФС ===
А ещё тормозит файловая система! Конкретно, если у вас не включена опция <tt>mount -o lazytime</tt>, то при каждой мелкой записи ФС обновляет mtime, то есть время модификации inode-а. Так как это метаданные, а ФС журналируемые — это изменение журналируется. Из-за этого при тесте <tt>fio -sync=1 -iodepth=1 -direct=1</tt> поверх ФС без lazytime iops-ы уменьшаются в 3-4 раза.
Для lazytime нужны свежие ядра: с ext4 — хотя бы 4.0, с XFS — хотя бы 4.17. Также нужны соответствующие (свежие) util-linux (подсказка: в протухшей 7-й центоси их нет, поставить можно только из исходников).
А если у вас (не дай бог) внутри Oracle, то ему надо обязательно поставить опцию FILESYSTEMIO_OPTIONS=SETALL.
Производительность случайной записи в CephFS почти не отличается от RBD.
Производительность случайной записи в CephFS через mount -t cephfs и через ceph-fuse… при iodepth=1 почти не отличается. А вот при iodepth=128 ядерный клиент ведёт себя нормально, а ceph-fuse выдаёт столько же, сколько при iodepth=1 (то есть на порядок/порядки меньше, чем ядерный клиент).
== Оценка производительности кластера ==
== Картина маслом «Тормозящий кэш» ==
=== O_SYNC vs fsync vs hdparm -W 0 ===
У SATA и SCSI дисков есть два способа сброса кэша: команда FLUSH CACHE и флаг FUA (Force Unit Access) на команде записи. Первый — это явный сброс кэша, второй — это указание записать операцию на диск, минуя кэш. Точнее, у SCSI оно есть, а с SATA ситуация точно не ясна: в спецификации NCQ бит FUA есть, но по факту FUA большинством дисков вроде как не поддерживается и, соответственно, эмулируется ядром/контроллером (если контроллер не кривой).
По всей видимости, fsync() отправляет диску команду FLUSH CACHE, а открытие файла с O_SYNC устанавливает бит FUA на все команды записи.
# Блюстор блокирует запись в журнал записью на HDD. Когда включен спец.кэш, HDD начинает рандомно писать сильно быстрее, и блокировки при сбросе уходят. Действует кэш, естественно, временно — когда он кончится, производительность случайной записи опять упадёт. Однако плюс в том, что в Ceph-е этого, скорее всего, не произойдёт, так как скорость случайной записи ограничивается, собственно, самим Ceph-ом и распределяется по всем дискам кластера :).
# Однако, для обычных дисков без SSD-кэша отключение кэша тоже даёт выигрыш… есть гипотеза, что из-за того же тормоза с bluefs (проверю).
Более свежие тесты бенчилкой ceph-gobench на том же самом стенде. Версия Ceph Mimic 13.2.2, Bluestore, журналы на SSD.
osd.14 | 302 | 229 | 135 | Hitachi Ultrastar A7K2000 | HUA722020ALA330
</tab>
==== Примечания ====
Toshiba MG07ACA14TE тоже замечены в подобном поведении, см. обсуждение в списке рассылки: https://www.spinics.net/lists/ceph-users/msg60753.html
== Почему вообще Bluestore такой медленный? ==
{{Note}} Третья редакция hatespeech’а.
Все мы держим в уме, что 1x 7200rpm HDD может выдать примерно 100—120 iops. Дальше нам говорят — ну, там типа журналирование. Ну ок, как мы рассуждаем — ну, типа, есть журнал, есть диск. Значит типа вроде как синхронно записало в журнал, потом асинхронно постепенно перенесло на диск. Значит, берём 100, умножаем на число дисков в кластере, делим на фактор репликации (3), делим на 1.5-2 (данные+журнал), мы же держим в уме, что наверняка там всё асинхронно и оптимизировано… Получаем, скажем, 100 * 9 дисков / 1.5-2 / 3 = 150—200 iops. Запускаем fio iodepth=128 на собранном кластере — ОЙ, 30 iops. Как так?
Сеть тоже не виновата — её я пробовал бенчить с помощью nbd (network block device). При прямом доступе диск выдаёт 50000 iops, при пробросе диска с одного сервера на другой через nbd — 8000 iops. То есть, добавленная latency сети — примерно 0.1ms. Это не много.
И даже Bluestore не совсем виноват. На NVMe Bluestore с некоторыми тюнами всё-таки осиливает завершить запись примерно за 0.3мс. И в то же время код самого Ceph сжирает ещё 0.4мс. Авторы сейчас пытаются пилить новую реализацию OSD на асинхронном фреймворке Seastar (Crimson OSD). Но проблема в том, что, скорее всего, это им поможет слабо. Проблема не в том, что многопоточный код плохо работает с вводом-выводом — проблема в том, что он сам по себе сильно жрёт CPU. Чтобы всё это работало быстрее, нужно упрощать логику.
По сути, нужно было бы добиться ситуации, в которой Ceph бы отъедал 0.1ms и Bluestore ещё 0.1ms. Сеть съест ещё 0.1ms и тогда на хорошей NVMe получится latency ~ 0.33ms, что в 1 поток соответствует 3000 операциям записи в секунду. До локальной SSD это всё равно не дотянуло бы, но, тем не менее, было бы уже очень-очень неплохо. Тогда, скажем, можно будет бороться за CPU: поставив самолётные CPU по 20000$ каждый, настроив ядро и снизив время Ceph+Bluestore ещё в 2 раза, вы получите уже 0.23ms = ~4350 iops. А допилив поддержку Infiniband, может, получите и все 6000 iops. Пока же код не оптимизирован… всё это — мёртвому припарки.
Авторы сейчас пытаются пилить новую реализацию OSD на асинхронном фреймворке Seastar (Crimson OSD), так что у нас есть теоретические шансы увидеть Ceph, который будет в несколько раз быстрее. Хотя, конечно, там вопрос далеко не только в многопоточности и блокировках — по идее, много съедает именно программная логика. Но так как её они фактически тоже частично переписывают с нуля — она тоже может улучшиться.
== DPDK и SPDK ==
** Code is there, так что, вероятно, всё это можно исправить, если подебажить подольше
** Есть сообщения, что SPDK всё-таки работает из коробки, просто не даёт никакого выигрыша производительности. Но мне пока завести его не удалось
* Однако, похоже, в силу неоптимальной реализации самого сетевого кода Ceph ни от DPDK, ни от RDMA ожидать ускорения не приходится — потому приходится. Задержка Ceph в 10-100 раз выше сетевой задержки, так что один , уменьшая сетевую задержку, добиться практически нечего. Один чувак недавно даже проводил эксперимент — отрезал код AsyncMessenger-а от всего остального цефа и попробовал побенчить пробовал бенчить его отдельно: https://www.spinics.net/lists/ceph-devel/msg43555.html - html — и получил всего лишь ~80000 iops.
* В перспективе SPDK будет на хрен не нужен, так как в ядро приняли штуку под названием io_uring: https://lore.kernel.org/linux-block/20190116175003.17880-1-axboe@kernel.dk/ - с ней обычный код прокачивает через Optane-ы практически столько же iops, сколько и SPDK, при заметно меньшем объёме геморроя на поддержку работы с SPDK/DPDK
== Краткий экскурс в устройство SSD и флеш-памяти ==
Особенность NAND флеш-памяти (NAND/NOR) заключается в том, что пишется она мелкими блоками (обычно 512 байт), а стирается большими . Актуальное соотношение для Micron 3D NAND — страница (2-4 мегабайтаpage) 16 КБ, блок стирания (block) — и при этом 16 или 24 МБ (1024 или 1536 страниц, MLC/TLC соответственно). Случайное чтение страницы быстрое. Запись тоже, но писать можно только в предварительно стёртую область. Чтение блока при этом быстрое, запись тоже быстрая; область — а стирание же медленное, да ещё и число стираний каждого erase unit-а блока ограничено — после нескольких тысяч (типичное значение для MLC) блок физически выходит из строя. В более дешёвых и плотных (MLC, TLC, QLC — 2-4 бита на ячейку) чипах лимит стираний меньше, в более дорогих и менее плотных (SLC, один бит на ячейку) — больше. Соответственно, при «тупом» подходе — если при записи каждого блока его просто стирать и перезаписывать — случайная запись во флеш-память, во-первых, будет очень медленной, а во-вторых, она будет быстро выводить её из строя.
Но почему тогда SSD быстрые? А потому, что внутри SSD на самом деле есть очень мощный и умный контроллер (1-2 гигагерца, типично 4 ядра или больше, примерно как процессоры мобильников), и на нём выполняется нечто, называемое Flash Translation Layer — прошивка, которая переназначает каждый мелкий логический сектор в произвольное место диска. FTL всё время поддерживает некоторое количество свободных стёртых блоков и направляет каждую мелкую случайную запись в новое место диска, в заранее стёртую область. Поэтому запись быстрая. Одновременно FTL делает дефрагментацию свободного места и Wear Leveling (распределение износа), направляя запись и перемещая данные так, чтобы все блоки диска стирались примерно одинаковое количество раз. Кроме того, во всех SSD некоторый % реального места зарезервирован под Wear Leveling и не виден пользователю («overprovision»), а в хороших серверных SSD этот процент весьма большой — например, в Micron 5100 Max это +60 % ёмкости(в Micron 5100 Eco — всего лишь +7.5 %, 1.92 ТБ SSD содержит 10 чипов NAND по 1.5 терабита и 2 по 768 гигабит).
Именно из наличия FTL вытекает и проблема с энергонезависимостью и «power loss protection»-ом. Карты отображения секторов — это метаданные, которые при сбросе кэша тоже нужно сбрасывать в постоянную память, и именно этот сброс и вносит торможение в работу настольных SSD с fsync.
Кстати, из размера страницы 16 КБ следует, что когда вы используете десктопную SSD под мелкую транзакционную перезапись, вы ещё и сильно снижаете срок её жизни, так как при перезаписи по 4 КБ с sync-ами write amplification составляет не менее 16 КБ / 4 КБ = 4. ''Примечание: в современных SSD распространена такая вещь, как SLC Cache — использование части той же самой флеш-памяти в SLC-режиме для первых X гигабайт записи. При SLC-записи размер той же страницы, вероятно, уменьшается в 3 раза, так как вместо 3 бит в каждой ячейке хранится только 1. С другой стороны, это всё равно та же страница, которая номинально вмещает 16 КБ, так что как тут считать WA, не совсем ясно.''
Дополнение: когда я попытался кого-то в списке рассылки полечить на тему, что «все SSD делают fsync», мне в ответ кинули статью: https://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf. В общем, суть статьи в том, что в 2013 году нормой было то, что SSD вообще не сбрасывали метаданные на диск при fsync, и при отключении питания это приводило к разным весёлым вещам вплоть до (!!!) полного отказа SSD.
=== Бонус: USB-флешки ===
А почему тогда USB-флешки такие медленные? Случайная запись на флешку 512-байтными (или 4 Кб) блоками обычно идёт со скоростью 2-3 iops. А флеш-память там ровно примерно та же, что в SSD — ну, может, более дешёвые вариациии мелкие чипы с меньшими размерами страницы и блока (часто 4 КБ страница и 4 МБ блок), но разница принцип тот же и разница в скорости не на порядки. Ответ кроется в том, что на флешках тоже есть FTL (и даже Wear Leveling), но по сравнению с SSD-шным он маленький и тупой. У него слабый процессор и мало памяти. Из-за малого объёма RAM контроллеру флешки, в отличие от контроллера SSD, негде хранить полную таблицу сопоставления виртуальных и реальных секторов — поэтому отображаются не сектора, а крупные блоки где-то по мегабайту или больше, а и при записи есть лимит на количество «открытых» блоков. Как это происходит:
* Допустим, вы пишете в сектор X.
== Пример теста от Micron ==
Пример самолётного сетапа от Micron с процами по полляма (2x Xeon GoldPlatinum 8168), 1002x100-гбит сетью (точнее 2x2x100, так как 2 карты по 2 порта) и 10x топовыми NVMe (с конденсаторами, ага) в каждом узле, 4 узла, репликация 2x: https://www.micron.com/resource-details/30c00464-e089-479c-8469-5ecb02cfe06f
Всего 350000 367011 iops на запись в пике на весь кластер, при 100 % загрузке CPU. Казалось бы, довольно много, но если поделить 350000367000/40 osd — получится 8750 9175 иопс на 1 osd. С учётом репликации на диски нагрузка двойная, выходит, 17500 18350 иопс. Ок, журналы тоже удваивают нагрузку, итого — 35000 36700 iops на запись смог выжать ceph из одной NVMe… которая сама по спеке может 260000 иопс в одиночку. Вот такой вот overhead.
Данных по задержкам в 1 поток нет (а было бы интересно узнать).
== Модели ==
* Micron серий 5100/5200, 9300. Возможно также 5300, 7300
* HGST SN260
* Intel P4500
* Использовать только SSD с конденсаторами. NVMe это тоже касается. Подсказка: 99 % desktop SSD и NVMe конденсаторов не имеют.
* …и надо отключать этим SSD кэш (hdparm -W 0), если они SATA!
* В случае HDD — полезны HDD со встроенным SSD-кэшем. Например, почти все большие Seagate EXOS таковы, хоть на них это часто и не заявлено.* …и им тоже бывает полезно отключить кэш (hdparm -W 0). Только проверьте, что это улучшает iops-ы, а не ухудшает.* SMR HDD не использовать под Ceph никогда.* Отключить powersave: governor cpupower frequency-set -g performance, cpupower idle-set -D 0
* Отключить электронные подписи: <br /><tt>cephx_require_signatures = false<br />cephx_cluster_require_signatures = false<br />cephx_sign_messages = false</tt><br />(и монтировать rbd map / cephfs ядерным драйвером с опциями <tt>-o nocephx_require_signatures,nocephx_sign_messages</tt>)
* Для хороших SSD или NVMe: min_alloc_size=16384 (так и было по умолчанию, в последних версиях поменяли на 4096 и я рекомендовал 4096, prefer_deferred_size_ssd=0 (ДО создания OSDа похоже, что зря)* Актуально для версий до Nautilis Nautilus включительно — <tt>[global] debug objecter = 0/0</tt> (там большой тормоз на клиентской стороне)* В QEMU юзать virtio* Если нужны только random write у вас All-flash кластер и вам критичны либо iops, то в userspace драйвере -ы случайной ''синхронной'' записи (напримерfsync/O_SYNC, QEMUнапример в случае СУБД) — , либо суммарные iops-ы ''параллельной'' случайной записи, то нужно отключить rbd cache(в qemu опция cache=none). Если не критичны или у вас HDD, лучше поставить cache=writeback.* Чтобы мог работать cache=unsafe, поставить <tt>[global] rbd cache writethrough until flush = false</tt>* <s>Для HDD-only или Bad-SSD-Only и версий до Nautilus включительно — снять ручник https://github.com/ceph/ceph/pull/26909</s> - уже влит* Внутри ВМ: <tt>mount -o lazytime</tt>
== Примечание ==
Написанное в статье актуально для версий Ceph, доступных на момент последней правки (см. «История» вверху страницы). Конкретно — для 12 -15 luminous-octopus. Различия между версиями минимальны, 13 mimic, да и 14 nautilus тоже — всё пока что актуально. Если вдруг в будущем что-то пофиксят и всё вдруг станет чудесно быстрым — сам побегу обновляться первым и поправлю статью :).
== См. также ==
* https://www.ixsystems.com/community/resources/list-of-known-smr-drives.141/ - список SMR дисков (вероятно, не полный)
* http://vasilisc.com/bluestore-ceph-2017 - кое-что про bluestore, местами не совсем верно, но тем не менее
* https://amarao-san.livejournal.com/3437997.html - «IOPS не существует» — сказ о latency
*: ''Прим.вред — iops существуют, но с обязательным указанием режима тестирования и параллелизма''
* https://yourcmc.ru/afr-calc/ - мой калькулятор вероятности потери данных в кластере Ceph в зависимости от размера кластера и схемы отказоустойчивости
== Советы лучших собаководов ==
Офлайн балансер:
<pre>ceph osd getmap -o om; osdmaptool om --upmap upmap.sh --upmap-deviation 0; bash upmap.sh; rm -f upmap.sh om</pre>
[[Category:Ceph]]