Перейти к основному содержимому
Перейти к основному содержимому

Могу ли я использовать ClickHouse в качестве ключ-значение хранилища?

Краткий ответ — "нет". Нагрузка на ключ-значение находится на верхних позициях в списке случаев, когда НЕ следует использовать ClickHouse. В конце концов, это система OLAP, в то время как существуют множество отличных систем хранения ключ-значение.

Тем не менее, могут быть ситуации, когда всё же имеет смысл использовать ClickHouse для запросов, подобных ключ-значение. Обычно это какие-то недорогие продукты, где основная нагрузка является аналитической по своей природе и хорошо подходит для ClickHouse, но есть и какой-то вторичный процесс, который требует шаблона ключ-значение с не такой высокой пропускной способностью запросов и без строгих требований по задержке. Если бы у вас был неограниченный бюджет, вы бы установили вторичную базу данных ключ-значение для этой вторичной нагрузки, но на самом деле есть дополнительные затраты на обслуживание еще одной системы хранения (мониторинг, резервное копирование и т. д.), которых хотелось бы избежать.

Если вы решите пойти против рекомендаций и выполнять некоторые запросы, подобные ключ-значение, против ClickHouse, вот несколько советов:

  • Основная причина, по которой точечные запросы дороги в ClickHouse, — это его разреженный первичный индекс основной семьи движков таблиц MergeTree. Этот индекс не может указывать на каждую конкретную строку данных, вместо этого он указывает на каждую N-ю строку, и системе необходимо сканировать от соседней N-й строки к нужной, считывая избыточные данные на пути. В случае с ключ-значение может быть полезно уменьшить значение N с помощью настройки index_granularity.
  • ClickHouse хранит каждую колонку в отдельном наборе файлов, поэтому для сборки одной полной строки ему нужно пройти через каждый из этих файлов. Их количество увеличивается линейно с количеством колонок, поэтому в случае с ключ-значение может иметь смысл избегать использования множества колонок и поместить все ваши данные в одну String колонку, закодированную в каком-либо формате сериализации, таком как JSON, Protobuf или любой другой, который имеет смысл.
  • Существует альтернативный подход, который использует Join движок таблиц вместо обычных таблиц MergeTree и функцию joinGet для получения данных. Это может обеспечить лучшую производительность запросов, но могут возникнуть некоторые проблемы с удобством и надежностью. Вот пример использования.