Можно ли использовать ClickHouse в качестве хранилища ключ-значение?
Краткий ответ — "нет". Нагрузки типа ключ-значение находятся на верхних позициях в списке случаев, когда НЕ следует использовать ClickHouse. Это, в конце концов, система OLAP, в то время как существует множество отличных систем хранения ключ-значение.
Тем не менее, могут быть ситуации, когда использование ClickHouse для запросов, подобных ключ-значение, имеет смысл. Обычно это недорогие продукты, где основная нагрузка аналитическая по своей природе и хорошо подходит для ClickHouse, но существует также вторичный процесс, которому требуется модель ключ-значение с не таким высоким объемом запросов и без строгих требований к задержке. Если бы у вас был неограниченный бюджет, вы бы установили вторичную базу данных ключ-значение для этой вторичной нагрузки, но на практике существует дополнительная стоимость поддержки еще одной системы хранения (мониторинг, резервное копирование и т. д.), от которой, возможно, следует отказаться.
Если вы решите пойти против рекомендаций и запустить некоторые запросы, подобные ключ-значение, против ClickHouse, вот несколько советов:
- Главная причина, почему точечные запросы дорогие в ClickHouse, — это его разреженный первичный индекс основной семьи движков таблиц MergeTree. Этот индекс не может указывать на каждую конкретную строку данных, вместо этого он указывает на каждую N-ую строку, и системе необходимо просканировать соседние N-ые строки до желаемой, читая избыточные данные по пути. В сценарии ключ-значение может быть полезно уменьшить значение N с помощью настройки
index_granularity
. - ClickHouse хранит каждый столбец в отдельном наборе файлов, поэтому для сборки одной полной строки ему нужно просмотреть каждый из этих файлов. Их количество увеличивается линейно с увеличением количества столбцов, поэтому в сценарии ключ-значение может иметь смысл избегать использования множества столбцов и поместить все ваши данные в один столбец
String
, закодированный в каком-либо формате сериализации, таком как JSON, Protobuf или любой другой, который имеет смысл. - Существует альтернативный подход, который использует Join как движок таблиц вместо обычных таблиц
MergeTree
и функцию joinGet для извлечения данных. Это может обеспечить лучшую производительность запросов, но может иметь проблемы с удобством использования и надежностью. Вот пример использования.