Анализ архитектуры проекта: VK Live Analytics
Этот документ описывает архитектуру, потоки данных и взаимодействие компонентов системы сбора и обработки онлайн-статистики для VK-эфиров. Он основан на предоставленном коде, схемах баз данных и описаниях.

1. Общая концепция
Система предназначена для решения следующих задач:

Сбор данных: Фиксация присутствия зрителей (пинги) на активных прямых эфирах.

Агрегация: Накопление статистики просмотров по каждому зрителю в рамках каждого эфира.

Онлайн-трекинг: Поддержание актуального списка зрителей, находящихся онлайн в данный момент.

Аналитика: Создание периодических "снимков" (снепшотов) аудитории по различным сегментам (длительность просмотра, статус подписки).

Обогащение данных: Получение и кеширование подробной информации о профилях пользователей VK и их подписках.

Система разделена на два основных домена, представленных двумя базами данных:

LiveVID: Ядро для сбора и обработки данных, специфичных для прямых эфиров.

VKPeople: Общая служебная база данных для хранения и управления информацией о пользователях и группах VK, которая используется в том числе и для обогащения данных в LiveVID.

[Изображение схемы архитектуры системы]

2. Анализ баз данных
2.1. База данных LiveVID
Содержит все данные, напрямую связанные с эфирами.

streams: Каталог эфиров. Ключевые поля is_active и live_status управляют жизненным циклом эфира и определяют, какие из них подлежат обработке.

raw_view_ping: "Источник правды". Сюда попадают все сырые данные о просмотрах. Таблица является основной для всех последующих расчетов.

viewer_stream: Агрегированные данные по каждому зрителю на каждом стриме. Хранит время первого и последнего просмотра, общую длительность и количество "пингов".

online_now: Таблица-кеш, показывающая, кто онлайн "прямо сейчас". Полностью перезаписывается на основе viewer_stream с учетом заданного временного окна.

snapshots_intervals10: Wide-таблица со срезами аудитории. Содержит агрегированные данные по сегментам смотрения и членству в группе.

watch_segments_config: Справочник, определяющий временные интервалы для сегментации в snapshots_intervals10.

rollup_state: Служебная таблица для инкрементальной обработки (High-Water Mark), хранящая метку времени последнего обработанного пинга по каждому стриму.

vw_online_membership_split: VIEW, которое обогащает данные из online_now флагом is_member, используя данные из VKPeople.

2.2. База данных VKPeople
Централизованное хранилище данных о пользователях и группах VK.

user_core: Кеш профилей пользователей VK. Содержит основную информацию (имя, город, фото, количество подписчиков и т.д.).

groups_cache: Кеш информации о группах VK.

user_groups: Историческая таблица подписок пользователей на группы. Фиксирует время подписки и отписки (removed_ts IS NULL означает активную подписку).

competitor_groups: Справочник отслеживаемых групп-конкурентов, для которых daemon_live_scout.php будет искать эфиры.

user_inbox: Очередь входящих событий для обработки. Сюда попадают ID пользователей, чьи профили нужно обновить или создать в user_core.

jobs: Универсальная очередь фоновых задач (например, плановая актуализация старых профилей или проверка подписок).

vw_user_active_groups: VIEW, предоставляющее список активных подписок (где removed_ts IS NULL).

3. Скрипты и их взаимодействие
Система состоит из набора демонов (фоновых скриптов), которые запускаются по расписанию (cron), и вспомогательных скриптов.

3.1. Демоны сбора данных (LiveVID)
daemon_live_scout.php (Разведчик):

Задача: Поиск новых/активных прямых эфиров.

Логика:

Читает список групп из vkpeople.competitor_groups.

Через VK API (video.get, wall.get) проверяет наличие активных трансляций в этих группах.

Найденные или завершившиеся эфиры добавляет/обновляет в таблице livevid.streams.

daemon_live_fetch.php (Сборщик пингов):

Задача: Сбор сырых данных о зрителях с активных эфиров.

Логика:

Выбирает активные стримы из livevid.streams (is_active=1, live_status='started').

Для каждого стрима через VK API (video.liveGetSpectators) постранично получает список ID зрителей.

Записывает данные в две точки:

В livevid.raw_view_ping: создает "сырые пинги" (stream_id, vk_user_id, seen_ts).

В vkpeople.user_inbox: ставит в очередь ID пользователей для обогащения их профилей.

live_rollup_by_cron.php (Агрегатор):

Задача: Инкрементальная обработка сырых пингов и построение аналитики.

Логика (ключевой скрипт):

Роллап: На основе rollup_state (HWM) читает новые пинги из raw_view_ping.

Агрегация: Обновляет viewer_stream, увеличивая total_view_sec и обновляя last_seen_ts.

Обновление онлайна: Перестраивает online_now для обработанных стримов на основе viewer_stream (попадают те, у кого last_seen_ts в пределах окна).

Создание снепшота: Инсертит новую запись в snapshots_intervals10, агрегируя данные из online_now и viewer_stream согласно конфигу watch_segments_config и данным о членстве из vw_online_membership_split.

Обновление HWM: Сохраняет last_seen_ts последнего обработанного пинга в rollup_state.

Очистка: Удаляет старые обработанные пинги из raw_view_ping.

3.2. Демоны обогащения данных (VKPeople)
daemon_enricher.php (Обогатитель профилей):

Задача: Обработка очереди user_inbox.

Логика:

Выбирает пачку записей из user_inbox со статусом new.

Разделяет ID пользователей на тех, кто уже есть в user_core (существующие), и тех, кого нет (новые).

Для существующих: обновляет last_seen_ts в user_core и помечает задачу в user_inbox как done.

Для новых: через VK API (users.get) запрашивает их профили и создает новые записи в user_core. После этого помечает задачу как done.

Реализована логика ретраев с экспоненциальной задержкой.

Периодически удаляет старые done записи из очереди.

daemon_actualizer.php (Актуализатор профилей):

Задача: Плановое обновление устаревших профилей в user_core.

Логика:

Находит в user_core профили, которые не обновлялись больше недели (profile_fresh_ts).

Ставит для них задачи в jobs с типом profile.

Другая часть скрипта берет эти задачи из jobs, запрашивает свежие данные через users.get и обновляет user_core.

daemon_subscriptions.php (Сборщик подписок):

Задача: Проверка и обновление подписок пользователей.

Логика:

Берет задачи типа subscriptions из таблицы jobs.

Для каждого vk_user_id через groups.get получает полный список его подписок.

Актуализирует user_groups:

Добавляет новые подписки.

Проставляет removed_ts для тех групп, на которые пользователь больше не подписан.

Кеширует информацию о группах в groups_cache.

3.3. Вспомогательные скрипты
api_inbox.php: HTTP API-endpoint, который принимает POST-запросы с vk_user_id и создает запись в очереди user_inbox. Используется daemon_live_fetch.php.

competitors_admin.php: Простой веб-интерфейс для управления списком отслеживаемых групп в competitor_groups.

4. Потоки данных (Data Flow)
[Изображение диаграммы потоков данных]

Поиск и регистрация эфира:
competitor_groups -> daemon_live_scout -> livevid.streams

Сбор "сырых" данных о просмотрах:
livevid.streams -> daemon_live_fetch -> (livevid.raw_view_ping + vkpeople.user_inbox)

Обогащение профилей пользователей:
vkpeople.user_inbox -> daemon_enricher -> vkpeople.user_core

Агрегация и аналитика:
raw_view_ping -> live_rollup_by_cron -> (viewer_stream -> online_now -> snapshots_intervals10)

Плановая актуализация данных:

Профили: user_core -> daemon_actualizer -> jobs -> daemon_actualizer -> user_core

Подписки: jobs -> daemon_subscriptions -> user_groups

5. Готовность к дальнейшей работе
Проект имеет четкую, модульную структуру. Разделение на LiveVID и VKPeople является сильной стороной, позволяя переиспользовать данные о пользователях. Использование очередей (user_inbox, jobs) обеспечивает отказоустойчивость и асинхронность.

Теперь, когда у нас есть общее видение архитектуры, мы можем переходить к конкретным задачам по доработке и развитию проекта.