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

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

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

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

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

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