feat(clickhouse): справочники вынесены в зону dic, словарь читает подложку #107

Merged
ddmitry merged 4 commits from feat/105-dictionary-home into main 2026-08-20 12:26:41 +03:00
3 changed files with 20 additions and 14 deletions
Showing only changes of commit d77acfdf6c - Show all commits
+12 -9
View File
@@ -26,7 +26,7 @@
## Почему зона, а не прописка в слое ## Почему зона, а не прописка в слое
**Справочник читают несколько слоёв, а производит его ни один.** Каталог нужен **Справочник читают несколько слоёв, а не производит ни один.** Каталог нужен
модели заказов в DDS и витрине выручки в DM; будущие регионы — представлению модели заказов в DDS и витрине выручки в DM; будущие регионы — представлению
событий в DDS; `analyst` читает его напрямую. Писателя нет вовсе: содержимое событий в DDS; `analyst` читает его напрямую. Писателя нет вовсе: содержимое
приходит из файла репозитория. Прописка внутри `dds` приписывала слою модели приходит из файла репозитория. Прописка внутри `dds` приписывала слою модели
@@ -82,7 +82,7 @@ DM объекта, лежащего в DDS, — течение вниз, ров
**Историзацию и представление «последняя загрузка» из образца не берём.** В **Историзацию и представление «последняя загрузка» из образца не берём.** В
промышленном примере таблица копит загрузки с меткой времени, а представление промышленном примере таблица копит загрузки с меткой времени, а представление
берёт последнюю: источник приезжал извне, и версий у него не было нигде. У нас берёт последнюю: источник приезжал извне, и версий у него не было нигде. У нас
версии есть — **история каталога это git**. Дублировать её в ClickHouse значит версии есть — **история каталога это и есть git**. Дублировать её в ClickHouse значит
поставить конструкцию, у которой на стенде нет причины, а расшифровывать её поставить конструкцию, у которой на стенде нет причины, а расшифровывать её
менти всё равно придётся. менти всё равно придётся.
@@ -137,17 +137,20 @@ DM объекта, лежащего в DDS, — течение вниз, ров
- **Обновление словаря на кластере не атомарно, и это заявленное свойство.** - **Обновление словаря на кластере не атомарно, и это заявленное свойство.**
Случайный момент внутри окна разводит опросы разных серверов, чтобы они не Случайный момент внутри окна разводит опросы разных серверов, чтобы они не
ходили к источнику разом. Побочный эффект — ноды перезагружают словарь в ходили к источнику разом. Побочный эффект — ноды перезагружают словарь в
разное время, и на нашей паре расхождение доходит до 30 секунд: правка разное время. Ждать правки каталога каждой из них приходится от нуля до
каталога полминуты видна одной ноде и не видна другой. Прежнее решение верхней границы окна, а фазы у них независимы, поэтому расходиться они могут
`LIFETIME(0)` эту неатомарность предотвращало; теперь она предъявлена почти на все полторы минуты: одна перезагрузилась сразу после правки, вторая
намеренно. Урок записан опорной точкой в мастер-спеке, тащить его в курс — ещё нет. Прежнее решение `LIFETIME(0)` окно не закрывало, а сжимало до
разброса исполнения `SYSTEM RELOAD DICTIONARY ON CLUSTER`; теперь оно
раскрыто намеренно. Урок записан опорной точкой в мастер-спеке, тащить его в курс —
отдельное решение. отдельное решение.
- **Номенклатура товаров — медленно изменяющийся справочник**, и в предметной - **Номенклатура товаров — медленно изменяющийся справочник**, и в предметной
области это так. Стенд упрощает: файл в репозитории под версией git. области это так. Стенд упрощает: файл в репозитории под версией git.
Историзации в хранилище нет, и обещать её этот документ не должен. Историзации в хранилище нет, и обещать её этот документ не должен.
- Витрина выручки представление, поэтому категория подставляется в момент - Витрина выручки спроектирована представлением, поэтому категория будет
запроса, и правка каталога меняет отчёт задним числом. Материализуй мы подставляться в момент запроса, и правка каталога изменит отчёт задним
категорию при приёме — не изменила бы. числом. Материализуй мы категорию при приёме — не изменила бы. Самой витрины
ещё нет, она приходит этапом 4.
## Что проверено ## Что проверено
+4 -3
View File
@@ -696,9 +696,10 @@ v2, этап 0).
- словарь регионов из CSV той же машинерией, что каталог товаров (оживляет - словарь регионов из CSV той же машинерией, что каталог товаров (оживляет
`RegionCityID`); `RegionCityID`);
- неатомарное обновление словаря на кластере: ноды перезагружают его в - неатомарное обновление словаря на кластере: ноды перезагружают его в
случайный момент внутри окна `LIFETIME`, и после правки каталога до случайный момент внутри окна `LIFETIME`, фазы у них независимы, и после
тридцати секунд две ноды отвечают на один `dictGet` по-разному. Обвязка правки каталога две ноды отвечают на один `dictGet` по-разному — почти всё
готова ([ADR 0012](../adr/0012-dictionary-home.md)), урок остаётся на выбор; окно целиком. Обвязка готова ([ADR
0012](../adr/0012-dictionary-home.md)), урок остаётся на выбор;
- лаба сессий: менти сначала собирает сессии сам, и только после — рассказ, - лаба сессий: менти сначала собирает сессии сам, и только после — рассказ,
что с октября 2025 Метрика отдаёт `VisitID` прямо в хитах; частично что с октября 2025 Метрика отдаёт `VisitID` прямо в хитах; частично
синтетическая постановка — осознанный приём; синтетическая постановка — осознанный приём;
+4 -2
View File
@@ -35,8 +35,10 @@ ENGINE = File(CSVWithNames, './catalog/products.csv');
-- --
-- Окно обновления вместо LIFETIME(0): словарь перезагружается сам в случайный -- Окно обновления вместо LIFETIME(0): словарь перезагружается сам в случайный
-- момент внутри окна. Случайность разводит обращения разных серверов к -- момент внутри окна. Случайность разводит обращения разных серверов к
-- источнику, и цена у неё заявленная — ноды обновляются вразнобой, до 30 -- источнику, и цена у неё заявленная — ноды обновляются вразнобой. Ждать
-- секунд одна видит правку каталога, а вторая ещё нет. -- правки каталога каждой из них приходится от нуля до верхней границы окна,
-- фазы у них независимы, поэтому расходиться они могут почти на все
-- полторы минуты: одна перезагрузилась сразу после правки, вторая ещё нет.
-- --
-- Ключ строковый, поэтому COMPLEX_KEY_HASHED: числовой FLAT здесь неприменим. -- Ключ строковый, поэтому COMPLEX_KEY_HASHED: числовой FLAT здесь неприменим.
-- --