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 на практике:

  1. при использовании Leveled compaction упираемся в пороговые значения iops практически сразу

  2. с 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 хранилища очень важно учитывать характер запросов и структуру хранения данных. Порой, если пересмотреть архитектуру хранения, то можно достаточно эффективно оптимизировать инфраструктурные издержки.

Комментарии (2)


  1. kasthack_phoenix
    31.05.2023 10:10

    Суммарный объем данных ~500Tb c прогнозом ежегодного увеличения на ~100Tb

    Несомненно, такое изменение схемы данных в продукте потребовало усилий со стороны разработчиков.

    Эти операции с движением данных туда-обратно вообще окупаются? 500TB — всего три десятка HDD, не считая резервирования / HA-нод. 100TB в год, соответственно — это несколько тысяч долларов по текущим ценам. На SSD цены несколько выше, но это по-прежнему единицы тысяч долларов. Если бы у вас 500 PB было, смысл операции был бы более очевиден.

    Сколько стоит время ваших разработчиков / QA / админов, которое было потрачено на правки в коде / тестирование / миграции? Стоит ли полученная экономия, если она ещё была после расходов на создание решения, полученной просадки по производительности?


    1. softError Автор
      31.05.2023 10:10
      +1

      Добрый день. Краткий ответ - да, затраты окупились.

      Здесь не указаны все детали продукта, поэтому соглашусь, что понятно "а стоит ли оно того?". В рамках данного продукта это был большой профит. Эта была не единственная инсталляция и при запуске новых мы уже могли полагаться на архитектуру с HDD, что значительно сокращало начальную стоимость. По поводу просадки в производительности не соглашусь, т.к. она для конечного пользователя не пострадала на видимом уровне за счет уменьшения изначального размера partition с которым работал запрос на чтение. Фактически, overuse iops'ов не давал никакого преимущества и был спокойно упразднен в пользу HDD

      Пожалуй, главный посыл этой заметки был о важности выбора правильной структуры хранения данных и как это помогает снизить затраты на инфраструктуру. А вот уж момент, когда делать/не делать этот выбор, зависит от многих факторов