Инкрементальная обработка: Быстрые обновления пайплайна
Эта статья объясняет, как SEO-пайплайн использует инкрементальную обработку для работы за секунды вместо часов.
Проблема: Полная переобработка медленная
Запуск всего пайплайна с нуля занимает часы:
-
Шаг 0 (Эмбеддинг исходных данных): 15 минут (65 000 товаров)
-
Шаг 1 (Получение запросов): 10 минут (API-вызовы)
-
Шаг 2 (Кластеризация запросов): 30 минут (схожесть 65K×65K)
-
Шаг 3 (Сопоставление фраз): 20 минут (эмбеддинг + сопоставление)
-
Шаг 4 (Сопоставление товаров): 45 минут (запросы × товары)
-
Шаг 5 (Похожие запросы): 25 минут (схожесть запрос × запрос)
Итого: ~2.5 часа для полного пайплайна
Проблема: Ежедневные обновления тратили бы 2.5 часа на пересчет неизменившихся данных.
Решение: Трехуровневая инкрементальная стратегия
Мы используем три техники, чтобы пропускать ненужную работу:
1. Пропуск шагов (Крупнозернистая)
Пропускать целые шаги, если вывод актуален и скрипт не менялся.
2. Инкрементальный эмбеддинг (Среднезернистая)
Эмбеддить только новые/измененные элементы, повторно использовать кэшированные эмбеддинги.
3. Чекпоинты (Мелкозернистая)
Сохранять прогресс во время долгих операций, возобновлять с чекпоинта при сбое.
Стратегия пропуска шагов
Как это работает
Перед каждым шагом проверять:
Существует ли вывод? Если нет — запустить шаг.
Возраст вывода: Если старше 7 дней — запустить шаг.
Скрипт менялся? Если скрипт изменялся с момента генерации вывода — запустить шаг.
Все проверки пройдены? Пропустить шаг.
Реализация
def should_skip_step(output_path, script_path, days=7):
# Проверить, существует ли вывод
if not os.path.exists(output_path):
# ... (детали реализации опущены)
Использование
Каждый скрипт проверяет при запуске:
from seo_common import should_skip_step
if should_skip_step(SEO_SOURCE_EMBEDDINGS_PATH, __file__):
print("✓ Пропускаем: Вывод актуален и скрипт не менялся")
return
Преимущества
Быстрые ежедневные запуски: Большинство шагов пропускается, если данные не менялись
Автоматическая инвалидация: Изменения скрипта запускают пересчет
Настраиваемая свежесть: Настраивать параметр days для каждого шага
Стратегия инкрементального эмбеддинга
Как это работает
При эмбеддинге элементов (товаров, запросов, фраз):
Загрузить кэш: Прочитать ранее эмбедженные элементы и их ключи
Сравнить ключи: Определить новые, измененные и удаленные элементы
Эмбеддить только новые: Эмбеддить только элементы, отсутствующие в кэше
Объединить: Скомбинировать кэшированные эмбеддинги с новыми в правильном порядке
Сохранить: Записать обновленный кэш
Реализация
Функция incremental_embed_with_keys обрабатывает это:
def incremental_embed_with_keys(
items, # Текущие элементы для эмбеддинга
keys, # Уникальные ключи для элементов
# ... (детали реализации опущены)
Процент попаданий в кэш
Типичный процент попаданий в кэш после первого запуска:
Исходные данные (товары, детали, статьи):
-
Первый запуск: 0% (эмбеддить все 65 000 элементов)
-
Ежедневный запуск: 99.5% (только ~300 новых/измененных элементов)
Запросы (из GSC, Ads, live):
-
Первый запуск: 0% (эмбеддить все 65 000 запросов)
-
Ежедневный запуск: 99.2% (только ~500 новых запросов)
Сопоставления фраз:
-
Первый запуск: 0% (эмбеддить все 5 000 фраз)
-
Ежедневный запуск: 99.8% (только ~10 новых фраз)
Влияние на производительность
Первый запуск (холодный кэш):
-
Эмбеддинг исходных данных: 15 минут (65 000 элементов)
-
Эмбеддинг запросов: 10 минут (65 000 запросов)
-
Эмбеддинг фраз: 2 минуты (5 000 фраз)
Ежедневный запуск (теплый кэш):
-
Эмбеддинг исходных данных: 10 секунд (300 элементов, 99.5% попаданий)
-
Эмбеддинг запросов: 5 секунд (500 запросов, 99.2% попаданий)
-
Эмбеддинг фраз: 1 секунда (10 фраз, 99.8% попаданий)
Ускорение: в 90–180 раз быстрее
Стратегия чекпоинтов
Как это работает
Для долгих операций (эмбеддинг 65 000 элементов):
Пакетная обработка: Обрабатывать элементы пакетами (например, по 1 000)
Сохранять чекпоинт: После каждого пакета сохранять накопленные результаты
Возобновлять при сбое: Если процесс падает, возобновить с последнего чекпоинта
Финальное сохранение: После всех пакетов сохранить полные результаты
Реализация
Чекпоинты встроены в incremental_embed_with_keys:
checkpoint_every = 1000 # Сохранять каждые 1 000 элементов
embeddings_list = []
# ... (детали реализации опущены)
Преимущества
Восстановление после сбоя: Возобновление с последнего чекпоинта вместо начала с нуля
Видимость прогресса: Видеть прогресс каждые 1 000 элементов
Эффективность памяти: Обработка пакетами, не загружать все сразу
Интеграция по всему пайплайну
Инкрементальная обработка используется на нескольких шагах:
Шаг 0: Эмбеддинг исходных данных
Инкрементальный: Эмбеддить только новые/измененные товары, детали, статьи
Чекпоинты: Сохранять каждые 1 000 элементов
Логика пропуска: Пропускать, если выводу < 7 дней и скрипт не менялся
Смотрите: Эмбеддинг исходных данных
Шаг 1: Получение запросов
Инкрементальный: API-вызовы получают только новые данные (с момента последнего запуска)
Логика пропуска: Пропускать, если выводу < 1 день
Смотрите: Получение запросов
Шаг 3b: Эмбеддинг запросов
Инкрементальный: Эмбеддить только новые запросы
Чекпоинты: Сохранять каждые 1 000 запросов
Логика пропуска: Пропускать, если выводу < 7 дней и скрипт не менялся
Смотрите: Эмбеддинг запросов
Шаг 4: Расширение сопоставления фраз
Инкрементальный: Эмбеддить только новые фразы
Чекпоинты: Сохранять каждые 1 000 фраз
Логика пропуска: Пропускать, если выводу < 7 дней и скрипт не менялся
Смотрите: Сопоставление фраз с фильтрами
Шаг 6: Сопоставление товаров
Инкрементальный: Сопоставлять только новые запросы
Логика пропуска: Пропускать, если выводу < 7 дней и скрипт не менялся
Смотрите: Сопоставление товаров
Конфигурация
Инкрементальная обработка настраивается для каждого шага:
Порог свежести
# Пропускать, если выводу < 7 дней (по умолчанию)
should_skip_step(output_path, script_path, days=7)
# Пропускать, если выводу < 1 день (для часто меняющихся данных)
should_skip_step(output_path, script_path, days=1)
Частота чекпоинтов
# Сохранять каждые 1 000 элементов (по умолчанию)
incremental_embed_with_keys(..., checkpoint_every=1000)
# Сохранять каждые 5 000 элементов (для более быстрой обработки, меньше безопасности)
incremental_embed_with_keys(..., checkpoint_every=5000)
Размер пакета
# Эмбеддить по 32 элемента за пакет (по умолчанию, сбалансированно)
incremental_embed_with_keys(..., batch_size=32)
# Эмбеддить по 64 элемента за пакет (быстрее на GPU, больше памяти)
incremental_embed_with_keys(..., batch_size=64)
Мониторинг и отладка
Статистика кэша
Каждый шаг выводит статистику кэша:
✓ Найден существующий кэш, проверяем изменения...
Существующие: 65 000 элементов
Текущие: 65 300 элементов
Повторно используем: 64 800 эмбеддингов
Новые: 500 элементов для эмбеддинга
Сообщения о пропуске
Когда шаги пропускаются:
✓ Пропускаем 0_embed_source_data.py: Вывод актуален и скрипт не менялся.
Сообщения о чекпоинтах
Во время долгих операций:
Эмбеддим 65 000 элементов (чекпоинты каждые 1 000)...
Пакет 0-1000...
✓ Чекпоинт сохранен (всего 1 000)
Пакет 1000-2000...
✓ Чекпоинт сохранен (всего 2 000)
...
Ссылки
Технические концепции
-
Инкрементальное обучение — Википедия
-
Чекпоинтинг — Википедия
-
Кэширование — Википедия
Связанные статьи
-
Обзор SEO-пайплайна — Полная архитектура пайплайна
-
Эмбеддинг исходных данных — Инкрементальный эмбеддинг товаров
-
Эмбеддинг запросов — Инкрементальный эмбеддинг запросов
-
Сопоставление фраз с фильтрами — Инкрементальный эмбеддинг фраз
Резюме
Инкрементальная обработка ускоряет пайплайн в 90–180 раз:
Трехуровневая стратегия:
-
✅ Пропуск шагов (пропускать целые шаги, если вывод актуален)
-
✅ Инкрементальный эмбеддинг (эмбеддить только новые/измененные элементы)
-
✅ Чекпоинты (сохранять прогресс, возобновлять при сбое)
Производительность:
-
✅ Первый запуск: ~2.5 часа (полный пайплайн)
-
✅ Ежедневный запуск: ~5 минут (инкрементальные обновления)
-
✅ Процент попаданий в кэш: 99%+ после первого запуска
Преимущества:
-
✅ Быстрые ежедневные обновления (минуты вместо часов)
-
✅ Автоматическая инвалидация (изменения скрипта запускают пересчет)
-
✅ Восстановление после сбоя (возобновление с чекпоинта)
-
✅ Эффективность памяти (пакетная обработка)
Эта стратегия позволяет выполнять ежедневные запуски пайплайна без траты вычислительных ресурсов на неизменившиеся данные.