Спроектируем доставку изменений так, чтобы повторы и задержки не портили поисковую проекцию.
Примеры course-products используют учебную схему и товар из главы 5 «Mapping и типы полей». Разборы упражнений ниже используют отдельный публичный набор тренажёра.
- Транзакция БД + outbox
- Очередь + повторы
- Поисковая проекция
Спроектируем доставку изменений так, чтобы повторы и задержки не портили поисковую проекцию.
Курс ориентирован на Elasticsearch 9.4.3. Разборы упражнений используют публичный набор products; остальные запросы показывают отдельные учебные индексы и могут требовать подготовки или прав, недоступных в тренажёре. Ответы сокращены, score может меняться. Для расширенных функций проверяйте лицензию и вариант развёртывания.
Операции и частичный успех
Index заменяет документ по _id, create требует его отсутствия, update изменяет существующее представление, delete удаляет. Bulk использует NDJSON с завершающим переводом строки, а не один JSON-массив. Ответ проверяют по каждой операции: повтор всего пакета после частичного успеха может повторить уже применённые действия. Повторяют только временно неудачные операции с ограничением попыток и backoff.
СамопроверкаПорядок и идемпотентность
Стабильный _id делает полную замену документа устойчивее к повторной доставке, но не защищает от старого события после нового. Нужны версия источника, упорядочивание или стратегия чтения актуального состояния. if_seq_no и if_primary_term защищают конкурентное изменение версии Elasticsearch, а не автоматически порядок событий вашей БД. Для удаления также нужен устойчивый контракт доставки.
СамопроверкаДоставка и преобразование
Очередь отделяет запись БД от индексации, но простая отправка после commit может потеряться при сбое процесса. Outbox фиксирует бизнес-изменение и событие в одной транзакции; CDC читает поток изменений. Измеряйте lag, ошибки и возраст неуспешных событий. Ingest pipeline нормализует и обогащает документ, но не заменяет транзакционный механизм доставки.
Повторная полная запись с тем же id не создаёт второй товар; порядок событий всё ещё требует защиты.
{
"name": "Running headphones",
"sku": "sku-1",
"price": 99
}Как читать результат
Повторная полная запись с тем же id не создаёт второй товар; порядок событий всё ещё требует защиты.
Разбор на примере каталога
Событие версии 12 меняет цену на 100, версия 13 — на 90. Если очередь доставит 13, затем 12, обычный index по тому же _id вернёт устаревшую цену 100. Отсутствие дублей здесь не означает корректность. Храните монотонную версию источника и применяйте подходящий контракт версионирования либо пересобирайте документ из текущего состояния БД. При повторе после сетевого timeout учитывайте, что запись могла уже выполниться, даже если подтверждение не было получено.
СамопроверкаСамопроверка
Сначала ответьте самостоятельно, затем раскройте объяснение.
1. Bulk HTTP 200 означает полный успех?
Нет, проверяются errors и каждый item.
2. Стабильный _id решает порядок событий?
Нет, старое событие всё ещё может перезаписать новое.
3. Зачем outbox?
Чтобы изменение БД и запись события фиксировались атомарно.
4. Что защищают seq_no и primary_term?
Конкурентное изменение конкретной версии документа Elasticsearch.
5. Что измерять кроме ошибок?
Задержку доставки и возраст отставших изменений.
Краткая памятка
- Нет, проверяются errors и каждый item.
- Нет, старое событие всё ещё может перезаписать новое.
- Чтобы изменение БД и запись события фиксировались атомарно.
- Конкурентное изменение конкретной версии документа Elasticsearch.
- Задержку доставки и возраст отставших изменений.
Официальная документация
Готовы применить знания?
Подтвердите прочтение, чтобы сохранить своё место. Чтение и решение заданий учитываются отдельно в этом браузере с помощью гостевой cookie.