Обычно не пишу о том, что и так известно почти всем или если это хорошо освещено. Но недавно в одном популярном русскоязычном telegram-чате посвященном Ceph обсуждалась проблема scrubbing’а и я понял, что все таки знаю кое что, что еще не известно всем) Решил написать заметку посвященную данной теме.
Scrub — служебный механизм призванный проверять целостность копий данных в кластере RADOS. Процесс scrubbing’а идет фоном и циклически перебирает все данные сравнивая одну копию данных на одной OSD с другой копией на другой(или других) OSD.
Проверок бывает два типа: простая(scrubbing) и глубокая(scrubbing+deep)
В рамках простой проверки сверяются только атрибуты фалов и их размер, этот тип проверки безобиден и практически ни оказывает никакого влияния на работу кластера и по этому проводится с частотой в сутки.
При глубокой проверке(scrubbing+deep) проверяемые данные считываются с дисков, считается их контрольная сума и сверяется. Собственно чтение данных и есть проблема. Такие проверки идут с интервалом в неделю.
Естественно проверки не запускаются разом на все данные. В таком случае все вставало бы колом) Разные PG проверяются в разное время. Этот процесс идет не прерывно, сейчас одни проверяются, затем другие а через время опять первые и так без конца.
Так вот когда в кластере появляется нормальное количество данных и они активно используются то вы заметите влияние scrubbing’а даже без мониторинга)
Под нормальным объемом данных я подразумеваю не какой то общий объем данных в кластере а заполненность используемых дисков. Например если у вас диски размером в 2Tb и они заполнены на 50-60 или более процентов то у вас много данных в Ceph, даже если дисков всего шесть). Это моя субъективная метрика но по моему 3-х летнему опыту работы с Ceph в проде — это самый важный критерий.
Собственно когда наши диски достигли такой утилизации мы стали замечать просадки производительности и повышенные задержки во время идущего scrubbing’а. Возможно если бы у нас были SSD мы жили бы счастливо но у нас обычные SATA диски с журналами на SSD.
Так вот, scrubbing. Когда во время идущего скраббинга приходит пользовательская нагрузка на те же OSD что в процессе скраббирга, не заметить это сложно, особенно если у вас есть внешний мониторинг.
Изменение расписания scrubbing’а
Первое что можно сделать это задать расписание для scrubbing’а, отведя для него время где нибудь ночью, например с 00.00-08.00.
Задать в ceph.conf:
[osd]_x000D_ osd scrub begin hour = 0_x000D_ osd scrub end hour = 8_x000D_ ...
Задать в рантайме(без рестарта OSD):
ceph tell osd.* injectargs '--osd_scrub_begin_hour 0'_x000D_ ceph tell osd.* injectargs '--osd_scrub_end_hour 8'
Это сразу изменит ситуацию к лучшему но не надолго. Опять же если у вас много данных то они просто не будут успевать проходить scarbbing в отведенное время. Если какие то PG не успеют пройти scrubbing за 7 дней то он будет запущен принудительно в любое время. Так мы увидели идущий скраббинг в дневное время). Увеличивать установленное время без скраббинга нельзя т.к. он очень важен для сохранности данных. Так мы кстати еще раз получили подтверждение, что у нас много данных.
Раз скраббинг все же идет в итоге в дневное время и мешает нормальной работе сервиса то ничего не остается как искать пусти его ограничения.
Снижение приоритета с помощью CFQ
Самая популярная рекомендация, она же является официальной: https://ceph.com/geen-categorie/ceph-reduce-osd-scrub-priority/
Необходимо сменить планировщик у всех OSD-дисков на CFQ:
cat /sys/block/sda/queue/scheduler_x000D_ noop [deadline] cfq_x000D_ _x000D_ echo cfq > /sys/block/sda/queue/scheduler
и установить следующие параметры для всех OSD:
Задать в ceph.conf:
[osd]_x000D_ osd disk thread ioprio class = idle_x000D_ osd disk thread ioprio priority = 7_x000D_ ...
Задать в рантайме(без рестарта OSD):
ceph tell osd.* injectargs '--osd-disk-thread-ioprio-class idle'_x000D_ ceph tell osd.* injectargs '--osd-disk-thread-ioprio-priority 7'
Этот подход используют очень многие и кому то он помогает. Нам он не помог практически ни как. Мы довольно долго его тестировали но периодические просадки производительности и взлет летенси никуда не делись.
Уменьшение порции данных одного scrubbing’а
Это то ради чего написана эта заметка. Я нигде не видел статей или обсуждений на эту тему, но это то что избавило нас от проблем связанных со скраббингом.
Суть в том, что бы позволить scrubbing’у идти круглые сутки но читать данные очень мелкими порциями максимально снижая нагрузку на OSD в момент времени.
Задать в ceph.conf:
[osd]_x000D_ osd scrub sleep = .2_x000D_ osd scrub chunk min 1 # default - 5_x000D_ osd scrub chunk max 2 # default - 25_x000D_ ...
Задать в рантайме(без рестарта OSD):
ceph tell osd.* injectargs '--osd_scrub_sleep .2'_x000D_ ceph tell osd.* injectargs '--osd-scrub-chunk-min 1'_x000D_ ceph tell osd.* injectargs '--osd-scrub-chunk-max 2'
С этими параметрами вы будете видеть больше активных скрабов в выводе ceph -s но каждый из них будет минимально влиять на OSD на которой он идет.
При использовании этого подхода, на мой взгляд лучше сменить планировщик на deadline.
Данный подход представлен в этой статье как один из вариантов и возможно для вас окажется не таким эффективным как для нас. В общем попробуйте и решите сами.
Помогла ли вам статья?