сущности, каждый раз когда появляется новая сущность, он пишет ее в топик кафки, кликхаус этот топик слушает и заполняет таблицу.
Дальше появляется кейс когда объект на сервисе начинает обновлять свое состояние, соответственно в кх его надо актуализировать. Полистал доку кх, кажется больше всего тут подходит VersionedCollapsedMergeTree. Сервис владелец при каждом изменении состояния объекта шлёт в отельный топик его новые состояния, а другой консьюмер кх его слушает и инсертит в таблицу выполняя схлопывание.
Но тут встает вопрос партиций в кафке, очередность там гарантируется только в пределах партиций, соответственно более раннее состояние может быть вычитано позднее актуального.
Как наиболее канонично такие ситуации обыгрывать? На сервисе владельце тоже явно вести инкремент версии состояния и в кх его юзать при запросе на инсерт? Или как-то вокруг таймстампа кафка-мессаджа обыгрывают консистентность.
Судя по всему вопрос тут вообще не столько про кх, сколько про правильный eventual consistency, но кафка у нас только-только внедряется для целей bi, поэтому не все бестпрактисы ее использования ещё впитаны.
там время есть как поле? если изменения внутри одной PARTITION BY (см. CREATE TABLE в clickhouse) в целевой clickhouse таблице, то он сольются в дальнейшем на background merge вообще VersionedCollapsing просто работает для одинаковых ORDER BY сортируется по version и дальше схлопывание... ну и вам знания о SELECT .. FROM table FINAL не помешает https://kb.altinity.com/altinity-kb-queries-and-syntax/altinity-kb-final-clause-speed/
Время апдейта состояния? Вообще да, есть два поля на объекте: created_at, updated_at. Партиционирование выполнено по created_at. Тут вопрос как правильно держать именно актуальное состояние. В топике кафки с изменениями состояния объекта например 2 партиции. В 1 партиции более позднее состояние, во 2 более раннее. Мы не можем знать какое из них кх прочитает быстрее, но в кх должно остаться более позднее. Мы могли бы ориентироваться на updated_at, но как сравнить его значение с тем что уже в кх? Ведь выборка предыдущего состояния из кх происходит с помощью агрегации HAVING sum(Sign)>1, при этом дока говорит что агрегатные min/max нельзя использовать. Я же не могу написать HAVING sum(Sign) > 1 AND max(updated_at) < new_updated_at?
не надо про updated_at это просто "время апдейта", его в качестве version можно использовать
еще раз. "одинаковость" строк определяется значениями полей которые перечислены в ORDER BY
Обсуждают сегодня