Cost reduction - весьма популярное направление, особенно в дни кризиса IT. Вполне естественным является желание оптимизации расходов на “железо” с минимальной потерей производительности, ведь чем больше данных хранится, тем больше может оказаться профит. В данной статье описан кейс эксплуатации Cassandra на HDD дисках как один из способов оптимизации, имеющей смысл при достаточно большом объеме данных.
В отличие от некоторых баз данных, согласно документации, не возбраняется запускать Cassandra на HDD дисках, по причине использования под капотом LSM-tree.
Cassandra на SSD - убрать нельзя оставить?
Рассмотрим cassandrа-кластер, использующийся как центральный storage в системе. Организация данных внутри - разнообразная, но ничего выбивающегося за принятые стандарты эксплуатации нет. Суммарный объем данных ~500Tb
c прогнозом ежегодного увеличения на ~100Tb
и ежедневной записью ~1Tb
.
Для таблиц, в которых скорость чтения критична используется resource intensive Leveled сompaction strategy, там где чтение или обновление данных происходит реже - SizeTiered compaction strategy. Так как обе стратегии имеют место быть, в “железной” конфигурации заложен оверхэд как на cpu, так и на дисковое пространство.
В нашем случае около 20%
данных использовало Leveled compaction, остальные - SizeTiered. С точки зрения оверхеда с учетом схемы данных это > 100TB
SSD.
Немного о compaction strategies
LSM архитектура Cassandra подразумевает накопление на диске большого количества файлов с данными (SSTable). Поэтому для обеспечения разумного количества таких файлов, а также эффективного последовательного чтения, существует процедура уплотнения - compaction. В Cassandra есть несколько встроенных compaction strategies, подробное описание можно найти в документации. Выделим основные особенности каждой:
Leveled. Самая “дорогая” в плане утилизации cpu, iops стратегия, гарантирующая что не batch READ с большой долей вероятности будет происходить из одной SSTable. Подходит для случаев, когда, скорость не batch READ операций важна, а записи обновляются достаточно часто. Визуально, данный процесс выглядит беспрерывным - таблицы постоянно находятся в процессе compactiona.
SizeTieredCompactionStrategy. Более экономная в плане сpu, iops стратегия, требующая запаса дискового пространства(50% от объема хранящихся данных), так как сам compaction запускается тогда когда SSTable достигли определенного размера, чтобы слить их в одну. Выгодна в случаях преобладания write операций над read и отсутствия “жестких” требований к read latency, так как возможно чтение из нескольких SSTable.
TimeWindowCompactionStrategy. Оптимальна для данных типа time series, самая “экономная” в плане ресурсов стратегия, так как данные уплотняются в SSTable в рамках временного окна. SSTable, которые уже были уплотнены, больше не участвуют в этом процессе и могут лишь быть удалены по прошествии TTL. Поэтому, для эффективного чтения, данные, прошедшие финальное уплотнение, не должны изменяться.
А что если вместо SSD просто использовать HDD?
Теоретически перенос данных как c Leveled, так и с SizeTiered compaction strategy на HDD диски - верный путь к провалу, так как в первом случае нагрузка на диск будет интенсивной и практически непрерывной, во втором - при достижении SSTable пороговых размеров, даже при условии того, что возможностей диска будет с запасом хватать для определенной интенсивности записи и чтения. Отбросим дополнительные нюансы вроде необходимости запуска full repair и просто посмотрим как повлияет переход с SSD на HDD на практике:
при использовании Leveled compaction упираемся в пороговые значения iops практически сразу
с SizeTiered compaction дела обстоят лучше: если compaction в данный момент не запущен - все хорошо. Однако, когда данных становится больше, а следовательно растет количество SSTable и их размер, тогда compaction процессу требуется все больше и больше iops. Как итог, данный процесс может идти беспрерывно, а время записи/чтения устремляется вверх.
Нестандартные задачи требуют нестандартных решений?
Смотря на вышеизложенные результаты, можно сделать вывод, что мы упираемся в пороговые возможности HDD диска не по причине интенсивности чтения/записи непосредственно запросами, а по причине того, что compactor постоянно утилизирует диск. Данное заключение порождает 2 вопроса:
нужен ли вообще compaction для нашей схемы данных?
возможно ли снизить его интенсивность?
Ответ на 1 вопрос - НЕТ, так как отключение compaction теоретически может породить огромное количество SSTable и мы упремся в лимит inode
. Также, даже если compaction запускается в ручном режиме, его отключение не имеет смысла для таблиц с Leveled strategy, ведь, подразумевается, что для таких данных скорость чтения критична. Для таблиц с SizeTiered strategy отключение compaction возможно, особенно если есть совершенно “ненагруженное” окно, когда будет запускаться ручной compaction (уточним, что compaction процесс необходимо запускать как минимум для отработки retention механизма). В нашем случае такого “окна” нет, так как нагрузка на чтение/запись равномерна в течение дня.
Становится очевидным то, что требуется найти способ снизить интенсивность compaction. И здесь на помощь приходит сама Cassandra: помимо Leveled и SizeTiered стратегий существует еще одна - Time Window Compaction Strategy. Ее смысл в том, что данные группируются в SSTable в рамках заданных временных окон, то есть все записи с разными partition key, пришедшие в один и тот же интервал все равно попадут в одну SSTable. SSTable удаляется, когда подходит к окончанию время жизни всех записей.
Остается только понять возможно ли изменить текущую схему данных под характер запросов, основываясь на данных, что возможностей диска хватает для равномерно распределенной записи ~1Tb
данных в день, учитывая требование быстрого чтения.
Было замечено, что в силу специфики бизнес-логики записываемые данные не изменяемы со временем, а большинство запросов на чтение оперируют временным промежутком от 1 до 6 часов
. Следовательно, если выбрать промежуток уплотнения в 1 день, то в худшем случае чтение будет происходить из 2 SSTable, что приемлемо. Проведенные нагрузочные тесты для новой схемы данных продемонстрировали жизнеспособность данного подхода. Несомненно, такое изменение схемы данных в продукте потребовало усилий со стороны разработчиков.
Cassandra рекомендует проверять любую гипотезу нагрузочными тестами. Для этого можно использовать cassandra-stress, которая поставляется вместе с ней.
Послесловие
Смогли ли мы полностью отказаться от Cassandra на SSD - конечно же нет, схема данных с Leveled compaction осталась на SSD кластере - это 100Tb
. Однако, 70%
данных использующих ранее SizeTiered compaction, теперь живет в новом кластере Cassandra на HDD, а это 280Tб
из ранее 400Tб
. То есть, переработав схему данных, нам удалось сократить расход SSD на 280+140 (оверхед для SizeTiered) = 420 Tb
в пользу 300Tb
HDD (закладываем 20Tb
оверхеда про запас).
Можно подытожить, что для каждого big data хранилища очень важно учитывать характер запросов и структуру хранения данных. Порой, если пересмотреть архитектуру хранения, то можно достаточно эффективно оптимизировать инфраструктурные издержки.