Сессии dds.session: зерно и правила сборки #131

Closed
opened 2026-08-22 10:26:26 +03:00 by ddmitry · 1 comment
Owner

Part of #127.

Вопрос

Как собирается сессия из событий: зерно и состав dds.session, правила
нарезки (пауза 30 минут, граница суток), отношение к полю VisitID
генератора — стенд считает сессии сам и сверяется с эталоном, или берёт
поле готовым (и что тогда остаётся лабе сессий)? Движок, ключи,
шардирование, пересборка дня.

Сначала прочитать

  • CONTEXT.md: «Визит», «Граница суток», «День активности»;
  • мастер-спека, раздел 7 (dds.session — наследник dds.click);
  • docs/architecture/storage.md, раздел «Раскладка по шардам».
Part of #127. ## Вопрос Как собирается сессия из событий: зерно и состав `dds.session`, правила нарезки (пауза 30 минут, граница суток), отношение к полю `VisitID` генератора — стенд считает сессии сам и сверяется с эталоном, или берёт поле готовым (и что тогда остаётся лабе сессий)? Движок, ключи, шардирование, пересборка дня. ## Сначала прочитать - `CONTEXT.md`: «Визит», «Граница суток», «День активности»; - мастер-спека, раздел 7 (`dds.session` — наследник `dds.click`); - `docs/architecture/storage.md`, раздел «Раскладка по шардам».
ddmitry added the wayfinder:grilling label 2026-08-22 10:26:29 +03:00
ddmitry added a new dependency 2026-08-22 10:27:10 +03:00
ddmitry self-assigned this 2026-08-24 20:01:20 +03:00
Author
Owner

Резолюция

Кто режет сессии. Стенд сессионизирует сам — режет события по правилу визита (пауза 30 минут, граница суток) оконной сессионизацией над dds.event_v. Стенд играет роль сессионизатора, которую в бою играет Метрика; VisitID генератора — не источник, а эталон самопроверки (принятое отступление спеки, раздел 1.2). Готовый VisitID превратил бы сборку в GROUP BY по чужому полю и съел бы центральный урок слоя.

Зерно. Одна строка — один визит; в нарезку входят все три типа событий. День сессии = EventDate её событий (сессия сутки не пересекает) — готовая колонка партиции без пересчёта.

Идентификатор. session_id — детерминированный хеш cityHash64(кука, начало сессии): суррогат чеканит сессионизатор, а пересборка партиции обязана выдать те же id (счётчик и UUID отвергнуты). Не ключ сортировки и не ключ шардирования — ручка для лабы и разбора DQ-расхождений; витрины сессий читают таблицу напрямую, в соединениях id не участвует.

Состав строки. По образцу таблицы визитов Метрики: времена и длительность (в поясе счётчика), счётчики событий/просмотров/корзин/покупок, входная и выходная страницы, UTM первого события (в v1 было последнее касание — заменено осознанно), паспорт куки с первого события, служебные _load_id/_load_ts по правилу слоя. Осознанные расхождения с образцом: денег нет (выручка — только по бэкенду), целей нет (их место — счётчики торговых событий).

Движок и наполнение. MergeTree без версий, партиция — день сессии, ключ сортировки — (кука, начало), шардирование cityHash64(ClientID) — ко-локация с dds.identity_map. Сборка — дневной батч после прихода слепка заказов: события дня к этому моменту полны, партиция только что прожитого дня собирается один раз и целиком, идемпотентность — замена партиции. Асимметрия с заказами: там батч пересобирает до K «дышащих» дней, у сессий день замерзает сразу. Внутри живого дня «сегодня» смотрят через dds.event_v.

Сверка с эталоном. Счётная DQ-проверка, зерно «кука × день»: число сессий нарезки = uniqExact(VisitID). Эталон в модель не тащится; поштучное сопоставление — материал лабы сессий (менти собирает сам до знакомства с кодом стенда). Дом проверки — контур DQ этапа 4.

Разведка по v1: dds.click был склейкой device+geo эпохи четырёх топиков, сессионизации в v1 не было вовсе (dm.v_session_overview группировал по готовому click_id) — «менти собирает сам» в v2 не перенос, а осознанный апгрейд.

Дока: docs/architecture/dds/session.md (PR #142), там же полный список отклонённых вариантов.

## Резолюция **Кто режет сессии.** Стенд сессионизирует сам — режет события по правилу визита (пауза 30 минут, граница суток) оконной сессионизацией над `dds.event_v`. Стенд играет роль сессионизатора, которую в бою играет Метрика; `VisitID` генератора — не источник, а эталон самопроверки (принятое отступление спеки, раздел 1.2). Готовый `VisitID` превратил бы сборку в `GROUP BY` по чужому полю и съел бы центральный урок слоя. **Зерно.** Одна строка — один визит; в нарезку входят все три типа событий. День сессии = `EventDate` её событий (сессия сутки не пересекает) — готовая колонка партиции без пересчёта. **Идентификатор.** `session_id` — детерминированный хеш `cityHash64(кука, начало сессии)`: суррогат чеканит сессионизатор, а пересборка партиции обязана выдать те же id (счётчик и UUID отвергнуты). Не ключ сортировки и не ключ шардирования — ручка для лабы и разбора DQ-расхождений; витрины сессий читают таблицу напрямую, в соединениях id не участвует. **Состав строки.** По образцу таблицы визитов Метрики: времена и длительность (в поясе счётчика), счётчики событий/просмотров/корзин/покупок, входная и выходная страницы, UTM первого события (в v1 было последнее касание — заменено осознанно), паспорт куки с первого события, служебные `_load_id`/`_load_ts` по правилу слоя. Осознанные расхождения с образцом: денег нет (выручка — только по бэкенду), целей нет (их место — счётчики торговых событий). **Движок и наполнение.** `MergeTree` без версий, партиция — день сессии, ключ сортировки — (кука, начало), шардирование `cityHash64(ClientID)` — ко-локация с `dds.identity_map`. Сборка — дневной батч после прихода слепка заказов: события дня к этому моменту полны, партиция только что прожитого дня собирается один раз и целиком, идемпотентность — замена партиции. Асимметрия с заказами: там батч пересобирает до K «дышащих» дней, у сессий день замерзает сразу. Внутри живого дня «сегодня» смотрят через `dds.event_v`. **Сверка с эталоном.** Счётная DQ-проверка, зерно «кука × день»: число сессий нарезки = `uniqExact(VisitID)`. Эталон в модель не тащится; поштучное сопоставление — материал лабы сессий (менти собирает сам до знакомства с кодом стенда). Дом проверки — контур DQ этапа 4. Разведка по v1: `dds.click` был склейкой device+geo эпохи четырёх топиков, сессионизации в v1 не было вовсе (`dm.v_session_overview` группировал по готовому `click_id`) — «менти собирает сам» в v2 не перенос, а осознанный апгрейд. Дока: `docs/architecture/dds/session.md` (PR #142), там же полный список отклонённых вариантов.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: ddmitry/clickstream-data-platform#131