Система удаляет запись в источнике, но аналитическая витрина продолжает считать её действительной. Какой сигнал должен передать поток данных, чтобы удаление не потерялось?
Поток должен передать явное событие удаления — tombstone или CDC-запись с признаком операции удаления и ключом удалённой сущности. Одного отсутствия записи недостаточно: потребитель не может отличить удаление от задержки, сбоя доставки или неполной выгрузки.
Потребитель применяет такой сигнал к витрине: удаляет строку, помечает её неактивной или закрывает период её действия. Выбор действия зависит от требований к истории и повторной обработке данных.
В пакетных интеграциях удаление часто обнаруживали сравнением полного снимка источника с предыдущей копией. Такой подход позволял увидеть исчезнувшие строки, но требовал полного чтения и сравнения наборов данных.
В потоковой передаче каждое изменение должно быть представлено отдельным сообщением. Поэтому для удаления появился специальный маркер — tombstone: он сообщает, что объект с определённым ключом больше не существует, даже если его полезная нагрузка отсутствует.
Если поток передаёт только создания и изменения, аналитическая система видит последнюю известную версию строки. После удаления в источнике эта версия не исчезает сама собой, поэтому отчёты завышают количество объектов, суммарные значения или число активных клиентов.
Нельзя трактовать отсутствие сообщения как удаление. Сообщение могло задержаться, потеряться из-за ошибки маршрутизации, оказаться за пределами выбранного периода чтения или ещё не быть сформированным источником.
Неверная обработка удаления особенно опасна при повторной загрузке. Если витрина пересоздаётся из потока, в котором не осталось сведений об удалённых объектах, старые строки могут снова появиться.
Источник или CDC-коннектор должен публиковать запись с устойчивым ключом сущности, временем или порядком изменения и операцией DELETE. Для потоковой платформы это может быть отдельное tombstone-сообщение, а для прикладного события — событие удаления с ключом и метаданными.
Потребитель находит строку по ключу и применяет согласованную политику:
Обработка должна быть идемпотентной. Повторная доставка того же удаления не должна приводить к ошибке или изменению результата. Для этого используют устойчивый идентификатор изменения, версию сущности или правило применения только более новых версий.
Важен порядок относительно более ранних изменений. Удаление с версией 12 не должно быть перезаписано запоздавшим обновлением с версией 11. Если глобальный порядок невозможен, применяют порядок на ключ сущности, версии источника или условие сравнения метаданных изменения.
Tombstone нельзя удалять из потока сразу после обработки, если система поддерживает восстановление, новые потребители или повторное построение витрины. Срок хранения должен покрывать период гарантированного чтения и восстановления, иначе новый потребитель увидит последнюю версию строки, но не узнает, что она была удалена.
Компромисс состоит в выборе между физическим удалением и сохранением истории. Физическое удаление упрощает запросы текущего состояния и экономит место, но уничтожает контекст. Логическое удаление сохраняет аудируемость, однако требует фильтрации неактивных строк и дисциплины в запросах.
В CRM удалили клиента. Поток изменений передал обновления заказов, но не передал операцию удаления клиентов. В витрине клиентов осталась активная строка, поэтому отчёт по активной клиентской базе включал удалённого клиента.
Рассматривались три варианта. Полная ночная сверка со снимком CRM обнаруживала удаления, но добавляла нагрузку и задержку. Периодическая очистка клиентов, не обновлявшихся долгое время, была дешёвой, но могла удалить временно неактивные записи. Явное CDC-событие удаления обеспечивало точность и небольшую задержку, но требовало поддержки удаления во всех потребителях.
Выбрали третий вариант: CDC публиковал операцию удаления с ключом клиента и версией изменения, а витрина закрывала его текущую запись. Период хранения событий оставили достаточным для восстановления витрины, а повторные удаления сделали идемпотентными. В результате текущие отчёты перестали учитывать удалённых клиентов, при этом исторические отчёты сохранили сведения о ранее существовавших связях.
Вопрос: Почему нельзя надёжно восстановить удаления только по последнему снимку, если снимок неполный?
Ответ: В неполном снимке отсутствие ключа неоднозначно. Оно может означать удаление, фильтрацию по правам, временную недоступность источника или ошибку выгрузки. Для безопасного вывода об удалении нужен полный согласованный снимок либо отдельный достоверный сигнал от источника.
Вопрос: Что произойдёт, если tombstone будет обработан раньше обновления той же сущности из-за нарушения порядка?
Ответ: Более старое обновление может воскресить удалённую строку. Поэтому потребитель должен проверять версию, последовательный номер или время изменения и принимать только более новую операцию. Одного времени доставки недостаточно: оно описывает транспорт, а не порядок изменений в источнике.
Вопрос: Чем опасно немедленное удаление tombstone после первого успешного чтения?
Ответ: Новый или восстановленный потребитель может прочитать поток начиная с позиции, где tombstone уже отсутствует, и получить устаревшую строку без признака удаления. Это нарушает возможность воспроизведения состояния. Tombstone хранят в течение окна восстановления и гарантированного подключения потребителей либо дополнительно поддерживают периодические полные снимки для реконструкции текущего состояния.