Изменения

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

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

6571 байт добавлено, 12:22, 8 августа 2020
Нет описания правки
=== Про размер block.db ===
В общемКто задолбался со спилловерами? Все задолбались со спилловерами! :) Спилловер — это когда вы собрали Bluestore на SSD+HDD, выделив SSD под базу (block.db), но при этом эта самая база постоянно частично утекает на HDD. При этом она, вроде бы, даже влезает в SSD с запасом — но всё равно утекает. Начиная, кажется, с Ceph 14 Nautilus, о спилловерах предупреждает <tt>ceph -s</tt>, а с Ceph 15 Octopus авторы попытались победить spillover-ы через дополнительные «allocation hint»-ы RocksDB, но, в целом, легче от всего этого не стало. Когда случается спилловер в SSD+HDD конфигурациях, работа кластера замедляется — в большей или меньшей степени, в зависимости от размеров RocksDB и паттерна нагрузки, так как всегдакогда метаданных не очень много, «есть небольшой нюанс»они влезают в кэш OSD — либо onode cache, либо rocksdb cache, либо, если включено bluefs buffered io — то ещё и в системный page cache. Нюанс Если кэш-промахов достаточно много, могут даже появляться slow ops-ы. Так в чём же дело и как это победить? А дело в том, что с выбором раздела для очередного файла БД (RocksDB организована в виде набора файлов) «есть небольшой нюанс», точнее, даже два. Нюанс № 1: RocksDB кладёт файл на быстрый диск только когда считает, что на быстром диске хватит места под все файлы этого же уровня(для тех, кто ещё не в курсе — RocksDB это [https://github.com/facebook/rocksdb/wiki/Leveled-Compaction LSM база]).
Дефолтные настройки цефа:
* 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 ГБ'''. Иными словами, имеют смысл только размеры раздела block.db 4 ГБ, 30 ГБ, 286 ГБ. Все промежуточные значения бессмысленны — место сверх предыдущего граничного значения использоваться не будет. Например, если БД занимает 10 ГБ, а раздел SSD — 20 ГБ, то фактически на SSD ляжет только WAL (1 ГБ), L1 и L2 (256 МБ + 2.56 ГБ). L3, составляющий бОльшую часть базы, уедет на HDD и будет тормозить работу. При этом 4 ГБ — слишком мало, 286 ГБ — слишком много. Так что, по сути, правильно делать block.db размером хотя бы 30 ГБ для всех OSD. Нюанс № 2: В момент compaction-а RocksDB часто требуется целиком переписать уровень целиком. Если при этом на SSD нет запаса места в размере этого уровня, то он, опять-таки, утечёт на HDD и так там и останется, ибо перемещать после compaction-а его обратно она не умеет. При этом одновременно могут компактиться как минимум первый и последний уровни.
А L3 она положит Из этого следует, что, по идее, на blockразделе БД нужен ещё и запас в размере первого + последнего уровня БД.db, только если block.db размером хотя бы 25600+2560+256+1000 Мб = около То есть примерно 30 ГбГБ превращаются в примерно 60.
А L4, соответственноНо что делать, если ещё +256сами базы у вас размером, скажем, 30 ГБ? Выделять на SSD раздел 550 ГБ как-то уж очень жирно, но и спилловеров иметь не хочется. В этом случае можно поменять базовый размер уровня RocksDB (max_bytes_for_level_base). multiplier менять не будем, оставим по умолчанию 10 - его значение влияет на итоговое количество уровней RocksDB, а это уже более тонкая материя. Теоретически, меньшее число уровней снижает read и space amplification, но замедляет compaction и из-за этого может сильно повысить итоговый write amplification. Также есть итого 286 Гбтема с уменьшением размера отдельных memtable и кратным увеличением общего их числа, т.е., например, установки 32*32 МБ вместо дефолтных 4*256 МБ и min_write_buffer_to_merge=8, но эффект от этого тоже не совсем понятен (возможно, немного экономится CPU при compaction-е), так что это тоже пока лучше не трогать.
Иными словамиИтак, имеют смысл только размеры помня про необходимость запаса под первый и последний уровни выводим, что общий размер раздела block.db 4 ГбБД должен быть равен k*X, 30 Гбгде X - размер первого уровня, 286 Гба k - коэффициенты из ряда: 2 (1 уровень), 22 (2 уровня), 212 (под 3 уровня), 2112 (под 4 уровня) и т. Все промежуточные значения бессмысленны — место сверх предыдущего граничного значения использоваться не будетп.
При этом 4 Гб — слишком малоСоответственно, 286 Гб — слишком многоберём целевой максимальный размер нашей БД: 30 ГБ. Так чтоЭто будет размер последнего уровня. Делим его на 10 до тех пор, пока значение не приблизится где-то к гигабайту и принимаем это за размер первого уровня. Компактится база по сути256 МБ за раз, правильно делать blockтак что меньше 256 МБ размер первого уровня ставить точно смысла нет.db размером 30 гб После этого число делений+1 принимаем за число уровней, домножаем размер первого уровня на соответствующий коэффициент, накидываем +1 ГБ для всех WAL, округляем чуть вверх и получаем необходимый размер раздела SSD. В случае с 30 ГБ - размер первого уровня будет 300 МБ, число уровней 3 и требуемый размер SSD раздела - около 65 ГБ. Прописываем это в конфигурацию (bluestore_rocksdb_options = ...,max_bytes_for_level_base=300MB), деплоим OSDи радуемся жизни. Ну, почти радуемся, так как 50% этого раздела у нас используется только в момент компакшена, а остальное время простаивает...
== Снапшоты ==

Навигация