Task #6118
closedTask #6116: EPIC: Speed up the stats updater daemon (scripts/workflow/update_stats.sh)
Fetch only the missing date tail instead of re-downloading 365 days every round
100%
Description
Problem¶
All three metric commands hardcode a full-year window and re-fetch it from scratch on every iteration of the daemon loop:
-
InitialStatsGatheringCommand.downloadStatsData—dateStart = now - 365d,dateEnd = today -
PartnersMetricsGatheringCommand.downloadStatsData— same -
UsersMetricsGatheringCommand.downloadStatsData— same
IikoStatsGatheringService.getMetricValuesFromIikoDateDesc then walks that window day by day (line 117) and issues one OLAP request per day. Nothing consults what is already in stat_slices — the same 364 days are downloaded again on every round, forever, and re-inserted.
Proposed change¶
Before walking the window, look up the newest slice already stored for the metric name being gathered (the name is composed in IikoOlapV2MetricFetchingService.generateMetricName from prefix + company ids + field, so it is queryable) and start from there instead of from now - 365d.
- default window =
max(storedDateEnd, now - 365d)…today - always re-fetch a small trailing overlap (the current day, and ideally the previous one) since today's figures are still moving
- keep the full 365-day backfill available behind an explicit
--full/--fromoption on all three commands, for the initial load and for repairs
Steady state should be ~1–2 days of data per metric per round instead of 365.
Acceptance¶
- Second consecutive run of
iiko-stats-data-syncover unchanged data issues only the overlap-window requests. -
--fullstill performs the complete 365-day backfill. - No duplicate slices accumulate for days already stored.
Updated by Redmine Admin about 9 hours ago
- Status changed from New to Resolved
- % Done changed from 0 to 100
Реализовано в ветке speedup/stats-daemon, коммит 50a6ebef.
Решение вышло чуть иначе, чем в описании, — не сдвигом dateStart, а пропуском уже сохранённых интервалов:
IikoStatsGatheringService.getMetricValuesFromIikoDateDesc получил параметры skipAlreadyStored (по умолчанию true) и alwaysRefetchLatest (по умолчанию 2). Перед обходом окна один раз читаются уже сохранённые срезы — statSliceBaseService.findByMetricNameAndSlicesInRange(...), имя метрики собирается тем же IikoOlapV2MetricFetchingService.generateMetricName, что и при сохранении, — и раскладываются по dateEnd. Дальше интервал, который уже есть в базе, отдаётся из неё же, без похода в iiko.
Почему так, а не сдвигом окна: dateStart при isMonthCumulative считается по-другому, а dateEnd — единый ключ для обоих режимов, так что пропуск по dateEnd работает одинаково для всех метрик. В установившемся режиме на метрику остаётся один SELECT и два запроса в iiko вместо 365.
Два самых свежих интервала перекачиваются всегда — сегодняшние цифры ещё меняются.
Полный проход доступен флагом --full (-f) на всех трёх командах: iiko-stats-data-sync, iiko-partner-metrics-sync, iiko-users-metrics-sync. Заодно добавлен --days (-d) для глубины окна, по умолчанию прежние 365.
Дублей не возникает: интервал, который уже есть, повторно не сохраняется.
Updated by Redmine Admin about 7 hours ago
- Related to Task #6129: Индексы под горячий путь демона: stat_slices вообще без индексов added