# Введение

Здесь описано предложение по изменению подхода к обновлению регулярного отчета о полноте покрытия графов дорог снимками.

# Проблемы текущего решения

1) Ввиду особенности реализации текущее решение при каждом запуске перевычисляет  историю изменения покрытия за все время. Для этого ему приходится загружать все снимки, приматчивать их к ребрам дорожного графа, вычислять хронологию изменения актуальности покрытия. В ростом объема данных, а также добавлением новых типов графов для отслеживания полноты процесс требует все больше памяти и времени для своей работы.

2) Большой объем данных получается не только при вычислении покрытия, но и при отображении аналитического отчета. Выходная таблица graph_coverage содержит информацию о "времени жизни" каждого фрагмента покрытия. Для отображения графика изменения полноты или актуальности покрытия данные из graph_coverage еще аггрегируются во время выполнения запроса. В результате объем данных по таким крупным регионам как "Россия" стал настолько большим, что превысил доступные на Clickhouse ресурсы.

3) Другой недостаток является продолжением одного из достоинств текущего подхода. Поскольку данные пересчитываются каждый раз за все время, было легко изменять контролируемые метрики и изменения применялись сразу ко всему временному срезу данных. Однако, если новая версия сервиса содержала ошибку, значительно искажающую график метрики, это изменение было бы трудно заметить на графике из-за отсутствия "ступеньки".

# Предлагаемая схема работы

Новая схема работы будет отличаться следующим:
1) Результирующие таблицы будут храниться в YT, а для отображения данных будет использоваться механизм [ClickHouse over YT (CHYT)](https://docs.yandex-team.ru/cloud/solutions/datalens/data-from-ch-over-yt)

2) Таблица будут хранить на каждую дату результируещее значение метрики. Структура таблицы:

| date | dataset | fc | is_toll | geo_id | private_area | graph_type | camera_deviation | age_category | length |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |

Таблица будет отсортирована по дате.

3) Для отображения графика изменения полноты и актуальности покрытия достаточно будет отфильтровать значения по значениям фильтрующих атрибутов и аггрегировать по дате.

Если сконвертировать текущие данные в новую схему хранения, получим таблицу размером 120 млн. записей, 1.3ГБ.

Однако, предлагаемая схема исправляет только 2-ю и 3-ю проблему. Если не отказываться от вычисления покрытия от каждого датасетов в отдельности, не получится избавиться от формирования соответствий между всеми снимками и ребрами графов. Если реализовать [задачу по обновлению привязки фотографий к ребрам графов](https://st.yandex-team.ru/MAPSMRC-2548), то можно будет частично исправить 1-/ проблему.

# Оптимизации для ускорения вычисления соответствий между фотографиями и ребрами

Есть несколько оптимизаций, которые должны снизить потребление памяти процессом и ускорить общее время работы.

Одно из изменений -- исключить загрузку данных о снимках из базы на этапе [построения индекса снимков из базы](https://a.yandex-team.ru/arc/trunk/arcadia/maps/wikimap/mapspro/services/mrc/long_tasks/graph_coverage_export/lib/coverage_export.cpp?rev=r8613006#L59), вместо этого можно использвоать использовать fb-датасет `yandex-maps-mrc-pro`, генерацию которого включить в [регулярный процесс экспорта](https://a.yandex-team.ru/arc/trunk/arcadia/maps/wikimap/mapspro/services/mrc/long_tasks/export_gen?rev=r8613006).

Вторая оптизация -- на этапе [построения соответствия между ребрами ](https://a.yandex-team.ru/arc/trunk/arcadia/maps/wikimap/mapspro/services/mrc/long_tasks/graph_coverage_export/lib/coverage_export.cpp?rev=r8613006#L96) рассматривать только те ребра, которые присутствуют в mrc-индексе соответствующего графа (yandex-maps-mrc-graph-pro, yandex-maps-mrc-pedestrian-graph-pro).


# Детали реализации перехода на новую схему хранения

На новую схему можно перейти, лишь слегка изменив текущую реализацию. Предположим, что нам нужно вычислить данные за период `[from_date, to_date]`. Изменить потребуется следующие шаги:
1) при [вычислении истории изменения покрытия ребра](https://a.yandex-team.ru/arc/trunk/arcadia/maps/wikimap/mapspro/services/mrc/long_tasks/graph_coverage_export/lib/graph_coverage.cpp?rev=r8613006#L421) можно ограничиться только теми покрытиями, которые по времени пересекаются с `[from_date, to_date]`
2) Вместо [выгрузки покрытий в clickhouse](https://a.yandex-team.ru/arc/trunk/arcadia/maps/wikimap/mapspro/services/mrc/long_tasks/graph_coverage_export/lib/coverage_export.cpp?rev=r8613006#L145) выполнить Reduce-операцию на [YT-таблице graph_coverage](https://yt.yandex-team.ru/hahn/navigation?path=//home/maps/core/mrc/production/graph_coverage_export/graph_coverage), сгрупированной по значению полей
`camera_deviation, dataset, fc, geo_id, graph_type, is_toll, private_area`, и вычислить суммарные длины покрытия для каждого из наборов значений атрибутов. В самой операции будут выполняться те же шаги, которые в настоящее время выполняются в UI [при подготовке загруженных из clickhouse данных](https://datalens.yandex-team.ru/editor/fpb9zjva9i8ud-graph-coverage?maxFc=7&minFc=1&region=213&dataset=agents&graph_type=0&privateArea=%3D%200&camera_deviation=0):
- массив интервалов времен жизни покрытий конвертируется в массив событий добавления и удаления покрытий
- массив событий сортируется по времени
- за один проход по полученному массиву вычисляется суммарная длина покрытия для выбранных значений полей `camera_deviation, dataset, fc, geo_id, graph_type, is_toll, private_area` за каждую из дат в интервале `[from_date, to_date]`.

