13 636
правок
Изменения
Нет описания правки
[[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 на голом диске:
{{Box|[[Файл:Warning icon.svg|32px|link=]] {{red|ВНИМАНИЕ!}} Для тех, кто в танке — fio-тест записи на диск ДЕСТРУКТИВНЫЙ. Не вздумайте запускать его на дисках/разделах, на которых есть нужные данные… например, журналы OSD (был прецедент).}}
* Перед тестированием отключите попробуйте отключить кэш записи диска: {{Cmd|hdparm -W 0 /dev/sdX}} (SATA-диски через SATA или HBA), {{Cmd|1=sdparm --set WCE=0 /dev/sdX}} (SAS-диски). Не совсем ясно, почему, но эта операция на серверных SSD может увеличить IOPS-ы на 2 порядка(а может НЕ увеличить, поэтому пробуйте оба варианта — и W0, и W1). Также см.ниже [[#Картина маслом «Тормозящий кэш»]].
* Линейное чтение: {{Cmd|1=fio -ioengine=libaio -direct=1 -invalidate=1 -name=test -bs=4M -iodepth=32 -rw=read -runtime=60 -filename=/dev/sdX}}
* Линейная запись: {{Cmd|1=fio -ioengine=libaio -direct=1 -invalidate=1 -name=test -bs=4M -iodepth=32 -rw=write -runtime=60 -filename=/dev/sdX}}
* Задержка случайного чтения: {{Cmd|1=fio -ioengine=libaio -sync=1 -direct=1 -invalidate=1 -name=test -bs=4k -iodepth=1 -rw=randread -runtime=60 -filename=/dev/sdX}}
* Пиковые IOPS случайной записи: {{Cmd|1=fio -ioengine=libaio -direct=1 -invalidate=1 -name=test -bs=4k -iodepth=128 -rw=randwrite -runtime=60 -filename=/dev/sdX}}
* Задержка записи в журнал: {{Cmd|1=fio -ioengine=libaio -sync=1 -direct=1 -invalidate=1 -name=test -bs=4k -iodepth=1 -rw=write -runtime=60 -filename=/dev/sdX}} — также стоит повторить тот же тест с <tt>-fsync=1</tt> вместо <tt>-sync=1</tt> и принять худший результат, так как иногда бывает, что одним из методов sync игнорируется (зависит от контроллера).
* Задержка случайной записи: {{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]]-подобные ситуации рассинхронизации данных между репликами при отключении питания, потере сети и т.п…
Если конкретизировать сильнее, это означает, что Ceph не использует никакие буферы записи дисков (наоборот, он делает всё, чтобы эти буферы всё время очищать). Это не значит, что буферизации записи нет вообще — она есть на уровне клиентов (page cache в linux, кэш RBD устройства на уровне драйвера librbd qemu…). Но именно внутренние дисковые буферы не используются.
Это приводит к тому, что типичная настольная 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), а вообще на другой технологии, называющейся 3D XPointPhase-Change-Memory «3D XPoint». Хз, как она работает, но По спецификации заявляются 550000 iops при полном отсутствии необходимости в стирании блоков, кэше и конденсаторах. Но если даже задержка такого диска и равна 0.01мс005мс (она действительно равна), то задержка Ceph всё равно как минимум в 50 раз больше0.5-1мс, соответственно, с Ceph оптаны использовать чуть менее, чем бессмысленно — за большие деньги (1500$ за 960 гб, 500$ за 240 гб) вы получите не сильно лучший результат.
== BlueStore Bluestore vs FileStore Filestore ==
* BlueStore в 2 раза быстрее FileStore Ликвидирована двойная запись при линейной записи . Линейная запись быстрее в честных 2 раза практически в любых конфигурациях.* Отложенная запись, эффективная для HDD (можно считатьи, что всегдачастично, для очень плохих SSD). iops случайной записи в HDD-only конфигурациях почти в 2 раза больше, так как чем в нём крупные блоки пишутся 1 раз — сразу на устройствоFilestore. Правда, а речь об iops на HDD не 2 (идёт в журнал и потом принципе, поэтому вся разница — 33 или 66 iops на устройство)1 HDD.* BlueStore примерно равен FileStore по производительности случайной записи Возможность использования EC под CephFS и latency RBD благодаря реализованной частичной перезаписи объектов в AllEC-Flash кластерахпулах. Пиковая производительность при этом обычно немного выше* Эффективные снапшоты (благодаря «виртуальным клонам»): после снятия снапшота iops практически не падают, однопоточная — немного нижев отличие от Filestore, в котором они падают до считанных сотен даже на NVMe, так как при перезаписи даже 4 КБ после снятия снапшота в Filestore копируется целый 4 МБ объект. Жор CPU тоже немного меньше*: [[Файл:Warning icon. Всё svg|32px|link=]] Увы, это варьируетсяотносится только к '''rbd snapshot''', но по крайней мере блюстор здесь не хужек '''rbd clone'''. Клоны неэффективны в Bluestore точно так же, как и в Filestore. Запись 4 КБ в клон точно так же выливается в копирование 4 МБ.* Это не так критично, но в Bluestore есть поддержка сжатия и контрольных сумм данных.
* Условно, собрав небольшой кластер Гораздо хуже производительность случайной записи на BlueStoreSSD+HDD, SSD-раздел не работает как буфер для быстрой записи. Bluestore не пишет быстрее, чем может в 1 поток на среднем сам HDD+. То есть, с SSD вы получите ~100 -журналом и Filestore будет 1000—2000 иопс на записьслучайной записи, а в FileStore ~500 с Bluestore (и без SSD вообще будет 30-50 иопсbcache) — 200—300. 1000—2000, конечно, упадёт до 100 или даже ниже, когда у Filestore забьётся журнал и его придётся сбрасывать — но тем не менее, «буфер» для сглаживания пиков Filestore предоставляет. А Bluestore — нет.* Почему? Потому: И проблема не только в том, что BlueStore очень часто делает параметры по умолчанию — deferred_batch_ops и max_deferred_txc — задают частый сброс данных из очереди отложенной записи операций на HDD медленный диск (каждые 32 раз в 64 операции). Проблема ещё в том, deferred_batch_opsчто в Bluestore отсутствуют механизмы фоновой очистки «журнала» (очереди отложенной записи) . Поэтому, когда очередь забивается, производительность просто падает до HDD-шной до перезапуска OSD. Ну и при сбросе тормозит все последующие операциисама очередь находится в RocksDB, поэтому сильно поднимать её размер, по идее, неполезно.* В итоге случайная запись ждёт окончания До 1.5-2 раз хуже latency случайной записи не только на SSD/NVMe (All-Flash), а также и ибо накладных расходов на HDDкаждую операцию записи у Bluestore больше.* Ждёт оно так не каждую операциюЖор памяти больше. Да, поэтому iops-ы лучшеу Filestore много занимал pagecache, чем просто на HDDно Bluestore меньше 2 ГБ памяти не жрёт вообще никогда. Но всё-таки ждёт, поэтому iopsПричиной тому — RocksDB (одни только memtable-ы хуже, чем в FileStoreс дефолтными настройками съедают 1 ГБ памяти) и собственный кэш метаданных и данных (Bluestore не может использовать pagecache).* Фрагментация приводит к снижению скорости чтения.
* Либо вместо журнала (или рядом с журналом) сделать на SSD bcache для HDD.
* Либо использовать HDD с SSD Cache, Media Cache или аналогом (перманентным кэшем случайной записи на пластинах). Например, в старых дисках HGST это включается при отключении волатильного кэша командой `hdparm -W 0 /dev/sdXX`. В новых, похоже, включено всё время.
== Контроллеры ==
* Разница в 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}}.
* Для SAS и NVMe включайте blk-mq (ну или юзайте свежие ядра, в районе 4.18 оно включается по умолчанию). Но для SATA blk-mq обычно бесполезен или почти бесполезен.
* Фактическая глубина очереди, используемая Ceph OSD при случайной записи, редко больше 10 (посмотреть можно при работе утилитой {{cmd|iostat -xmt 1}}).
* …Но менять их бесполезно, поднять производительность таким образом не получается абсолютно, дефолтные значения (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> (вместо 63 подставьте своё число ядер минус 1) — отключает снижение частоты через множитель
* После этих двух команд процессор начинает греться как ПЕЧ, но 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 на все команды записи.
Есть ли разница? Обычно нет. Но на некоторых контроллерах и/или с некоторыми настройками различия по неустановленным причинам встречаются. И тогда fio -sync=1 и fio -fsync=1 начинают давать разные результаты — возможно, даже на порядки разные результаты.
Кроме того, у дисков есть команда отключения кэша. Когда он отключен, запросы сброса (fsync) Linux диску не отправляет. Казалось бы, такой режим тоже должен быть эквивалентен выполнению fsync и/или O_SYNC после каждой команды. Но и это не всегда так! На SSD с конденсаторами (то есть серверных моделях с Advanced Power Loss Protection) при отключении кэша iops-ы случайной записи часто вырастают на порядок (например, с 5000 до 40000). Но не всегда, так как это, опять-таки, зависит от контроллера.
Почему? По-видимому, потому, что команда FLUSH CACHE трактуется диском как «сбрось все кэши» (включая энергонезависимый), а отключение кэша — как «отключи энергозависимый кэш» (а энергонезависимый можешь оставить включенным). Соответственно, запись со сбросом кэша становится медленнее, чем просто отключённый кэш.
А что с NVMe? В NVMe разнообразие чуть меньше — возможность отключить кэш в спецификации не предусмотрена вообще, но точно так же есть команды FLUSH CACHE и бит FUA. При этом по личным наблюдениям FUA часто игнорируется то ли диском, то ли Linux-ом, и <tt>fio -sync=1</tt> выдаёт с NVMe такие же результаты, как и без sync вообще. <tt>-fsync=1</tt> при этом ведёт себя как надо и приземляет производительность туда, где ей самое место (на десктопных NVMe — до тех же 1000—2000 iops).
P.S: Bluestore использует fsync. Filestore использует O_SYNC.
=== Серверные SSD ===
Disabling cache is not a joke!
<tt>fio -ioengine=libaio -name=test -filename=/dev/sdb -(sync|fsync)=1 -direct=1 -bs=(4k|4M) -iodepth=(1|32|128) -rw=(write|randwrite)</tt>
'''Micron 5100 Eco 960GB'''
<div style="float: left">
<div>'''Запись'''</div>
<tab sep="bar" head="top" class="wikitable">
sync или fsync | bs | iodepth | rw | hdparm -W 1 | hdparm -W 0
sync | 4k | 1 | write | 612 iops | 22200 iops
sync | 4k | 1 | randwrite | 612 iops | 22200 iops
sync | 4k | 32 | randwrite | 6430 iops | 59100 iops
sync | 4k | 128 | randwrite | 6503 iops | 59100 iops
sync | 4M | 32 | write | 469 MB/s | 485 MB/s
fsync | 4k | 1 | write | 659 iops | 25100 iops
fsync | 4k | 1 | randwrite | 671 iops | 25100 iops
fsync | 4k | 32 | randwrite | 695 iops | 59100 iops
fsync | 4k | 128 | randwrite | 701 iops | 59100 iops
fsync | 4M | 32 | write | 384 MB/s | 486 MB/s
</tab>
</div>
<div style="float: left; margin-left: 10px">
<div>'''Чтение'''</div>
<tab sep="bar" head="top" class="wikitable">
bs | iodepth | rw | результат
4k | 1 | randread | 6000 iops
4k | 4 | randread | 15900 iops
4k | 8 | randread | 18500 iops
4k | 16 | randread | 24800 iops
4k | 32 | randread | 37400 iops
4M | 1 | read | 460 MB/s
4M | 16 | read | 514 MB/s
</tab>
</div>
<div style="clear:both"></div>
Результаты по чтению не отличаются на hdparm -W 0 и 1.
'''Seagate Nytro 1351 XA3840LE10063'''
Диск заполнен почти полностью, на 90-100 %.
<div style="float: left">
<div>'''Запись'''</div>
<tab sep="bar" head="top" class="wikitable">
sync или fsync | bs | iodepth | rw | hdparm -W 1 | hdparm -W 0
sync | 4k | 1 | randwrite | 18700 iops | 18700 iops
sync | 4k | 4 | randwrite | 49400 iops | 54700 iops
sync | 4k | 32 | randwrite | 51800 iops | 65700 iops
sync | 4M | 32 | write | 516 MB/s | 516 MB/s
fsync=1 | 4k | 1 | randwrite | {{red|288 iops}} | 18100 iops
fsync=1 | 4k | 4 | randwrite | {{red|288 iops}} | 52800 iops
fsync=4 | 4k | 4 | randwrite | 1124 iops | 53500 iops
fsync=1 | 4k | 32 | randwrite | {{red|288 iops}} | 65700 iops
fsync=32 | 4k | 32 | randwrite | 7802 iops | 65700 iops
fsync=1 | 4M | 32 | write | 336 MB/s | 516 MB/s
</tab>
</div>
<div style="float: left; margin-left: 10px">
<div>'''Чтение'''</div>
<tab sep="bar" head="top" class="wikitable">
bs | iodepth | rw | результат
4k | 1 | randread | 8600 iops
4k | 4 | randread | 21900 iops
4k | 8 | randread | 30500 iops
4k | 16 | randread | 39200 iops
4k | 32 | randread | 50000 iops
4M | 1 | read | 508 MB/s
4M | 16 | read | 536 MB/s
</tab>
</div>
<div style="clear:both"></div>
Если не хотите 288 иопс — отключайте кэш.
=== Ceph HDD+SSD ===
Дано: 3 компа с 4x 7200rpm SATA HDD, с 1 SSD (десктопным) под систему и ceph-mon и с 1 SSD (старым, но серверным, 25000 iops) под журналы. Не самая быстрая 10-гигабитная сеть — флуд пингом средний RTT (задержка) 0.098ms. Развёрнут Ceph + OpenNebula с KVM. Диски под Ceph отформатированы в Bluestore утилитой ceph-volume (то есть используется LVM). Диски виртуалок лежат в обычном реплицированном ceph pool с size=3.
# Блюстор блокирует запись в журнал записью на 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. Как так?
== 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
== RAID WRITE HOLE ==
В RAID-е есть один интересный момент: при отказе диска и одновременном отключении питания RAID 5 может кораптить данные.
Суть такая: допустим, есть три диска в рейд5. Есть какая-то пара блоков данных A и B. Соответственно на дисках хранятся: A, B, A xor B.
Теперь представим, что мы пишем в блок B данные B2. Для этого нам надо обновить данные на двух дисках: B -> B2, A+B -> A+B2. Теперь представим, что один из них успел записать, а второй не успел. Тут вырубилось питание и одновременно сдох диск A (или диск сдох от умирания питания, или контроллер повис и ядро в панику упало...). Что мы имеем на дисках?
?, B2, A+B либо ?, B, A+B2.
Теперь при попытке восстановить A мы получим A+B+B2 => опа! Покорраптились данные, которые даже не записывались!
Из-за этого raid всегда делает полный resync после нештатного вырубания питания. И, собственно, такая же потеря данных возможна при отказе диска до завершения resync. mdadm RAID5 в таких ситуациях (когда одновременно потерян диск и массив помечен как грязный) просто отказывается стартовать.
И именно чтоб этого избежать, в цефе сделано полное журналирование всех данных на уровне отдельных дисков (т.е. OSD). Потому что других способов борьбы с этой проблемой НЕТ, а при работе по сети отказы гораздо более вероятны, чем при работе RAID-массива на локальных дисках. Даже write intent bitmap может только сказать вам, потеряли вы какие-то данные или нет, но не может помочь их восстановить, если они потеряны.
Так что Ceph надёжнее RAID-а. :) медленнее (на SSD). Но надёжнее и не требует resync-а.
== Краткий экскурс в устройство 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
https://docs.google.com/spreadsheets/d/1E9-eXjzsKboiCCX-0u0r5fAjjufLKayaut_FOPxYZjc
== Резюме ==
Резюмируя вышесказанное, для random write iops:
* Использовать только SSD с конденсаторами. NVMe это тоже касается. Подсказка: 99 % desktop SSD и NVMe конденсаторов не имеют.
* …и надо отключать этим SSD кэш (hdparm -W 0), если они SATA!
* В случае HDD — полезны HDD со встроенным SSD-кэшем. Например, почти все большие Seagate EXOS таковы, хоть на них это часто и не заявлено.
* …и им тоже бывает полезно отключить кэш (hdparm -W 0). Только проверьте, что это улучшает iops-ы, а не ухудшает.
* SMR HDD не использовать под Ceph никогда.
* Отключить powersave: 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>)
* min_alloc_size=16384 (так и было по умолчанию, в последних версиях поменяли на 4096 и я рекомендовал 4096, а похоже, что зря)
* Актуально для версий до Nautilus включительно — <tt>[global] debug objecter = 0/0</tt> (там большой тормоз на клиентской стороне)
* В QEMU юзать virtio
* Если у вас All-flash кластер и вам критичны либо iops-ы случайной ''синхронной'' записи (fsync/O_SYNC, например в случае СУБД), либо суммарные 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]]