У вас две проблемы в одной.Давайте разделим его на две отдельные вещи:
- О реляционной модели, куда писать.
- О отбрасывании старых проекций.
Первое, что выНеобходимо проанализировать, контролируете ли вы свои читатели или нет, и если они развернуты мономолитически со всем проектом или нет.
Обычно для небольших проектов это будет справедливо, когда вы кодируете один или несколько десятков кодеров.Вместо этого, если в вашей компании есть сотни кодеров, и вы не знаете, кто именно читает ваши прогнозы, то вам лучше разработать «коммуникационный план» для ваших товарищей по команде, чтобы сделать старые прогнозы устаревшими в запланированном календаре.
Предположим, вы находитесь в сложной ситуации.
a.Проектирование новых таблиц
Проектирование новых таблиц для нового проектора, например, если ваши таблицы были Monitors
, Mouses
, Keyboards
и AudioDevices
, вы можете теперь захотеть создать Monitors_v2
,Mouses_v2
, Keyboards_v2
и Audiodevices_v2
или любое другое значимое имя / чистое кодовое имя, которое оно представляет для вашей компании (например, MonitorsWithManufacturerInformation
)
Если ваши мониторы изменились, а ваши клавиатуры - нет, яСоветую также составить полностью отдельный набор таблиц всех агрегатов и связанных с ними концепций, чтобы избежать какого-либо взаимодействия со старым.Если у вас есть Keyboards_v2
и Keyboard
с дублированными данными, никто не будет жаловаться.Если вы заставите их быть в одной таблице, вы будете убиты взаимодействиями.
b.Кодирование новых проекторов
У меня обычно внутри проектора есть возможность оставлять и создавать свои собственные таблицы или таблицы.Например, все мои проекторы реализуют метод resetState()
, принудительно вызванный интерфейсом Projector
, который, как правило, просто отбрасывает и создает несколько таблиц:
public function resetState()
{
$this->dropAndCreateTables();
$this->resetLastProcessedEventPointer();
}
private function dropAndCreateTables()
{
$this->dropAndCreateTableFormSubmissions();
$this->dropAndCreateTableDashboard();
$this->dropAndCreateTableStateTypes();
}
Затем добавьте возможность Projecto для обработки:
- отдельное событие
- , а также все ожидающие события
Все ожидающие события будут означать чтение, где находится указатель, чтение всех событий от указателя до настоящегои обработайте каждый из них по порядку, затем обновите указатель так, чтобы последующие вызовы для обработки всех ожидающих событий были идемпотентными .
c.Разверните и запустите
Разверните новый код (для предварительной подготовки, если он у вас есть) и выполните следующее:
- состояние сброса
- обработка всех событий
Даже если у вас нет предварительной подготовки и вы запускаете ее в производство, это безопасно, поскольку никто не знает о существовании новых таблиц.Оттуда никто не читает.
d.Повторите кодирование и развертывание
Проверьте, имеет ли проекция желаемую форму.Если у них нет нужного вам аспекта, вы можете безопасно отредактировать эти проекторы и заново запустить их с нуля: уничтожить таблицы, заново создать их и сохранить проецируемые данные (кеши текущего состояния).
Повторно осматривайте и так далее, пока не получите удовлетворительный результат.
e.Подключитесь к живому потоку
После того, как вы выполнили первоначальное отслеживание, убедитесь, что ваши проекторы прослушивают поток и обновляют прогнозы каждый раз, когда появляется новое событие.
Это не имеет значения дляэтот ответ, если он инициируется записью, синхронизацией или чтением и не имеет значения, обрабатываете ли вы событие потока по событию или в пакетах, просто убедитесь, что после первоначального «сброса» поток получает данные из кэшей.
ф.Общайтесь с товарищами по команде, заставляя читателей
Как только вы это подготовите, вы можете безопасно сообщить товарищам по команде, которые отвечают за кодирование читателей, у которых вы уже развернули новый кеш, в этих новых реляционных таблицах.
г.Обратная совместимость: да или нет?
Не удаляйте старые версии, если у вас нет отзывов от всех и каждого ваших читателей об успешном обновлении до новых версий.
Если вы сомневаетесь (т.е. уверены, что 99.999999999%), просто не удаляйте старые версии.
Если вы уверены (то есть: уверены на 100,000000%) отключите проекторы для некоторых циклов продукта (это будут минуты, дни или недели в зависимости от вашего проекта) и убедитесь, что никто не жалуется на чтение испорченных данных (повторная проверка).
Если кто-то жалуется: очень легко запустить старые проекторы, чтобы узнать последние события и подключить их заново.Дождитесь, пока читатель скажет «Я обновился до v2», и повторите.
Если никто не жалуется, вы можете удалить таблицы базы данных (они , а не нуждаются в каком-либо резервном копировании, как все они былисозданный в прошлом из событий источников), и вы также можете удалить старый код проектора, чтобы очистить вашу кодовую базу (если вам когда-нибудь понадобится что-то предпринять в отношении того, как был сделан старый проект, вот почему у вас есть git или подобное).
Если у вас есть «ошибки» в старых проецируемых данных, никакое программное обеспечение не спасет вас от дружеского общения со всеми вашими товарищами по команде, сообщающими, что они «должны» перейти на новых читателей, если они не согласятся обрабатывать неправильные данные (этоможет произойти ошибка, не влияющая на читателя, и этот код может справиться с сохранением старой версии).
Если вы являетесь единственным программистом или работаете с небольшой командой, скажем, из 20 человек, этоочень легко контролировать выключение.Но я бы рекомендовал придерживаться этого «удвоения перед падением», даже если вы в небольшой команде.
Итак, резюмируем: краткие ответы
Ваш вопрос № 1: Как это возможно?чтобы корректно справиться с этим обновлением, если я проецирую на реляционную модель, как бы мне было сделать так, чтобы переключение было максимально плавным, учитывая, что в обоих проекциях будут использоваться разные таблицы (возможно, даже в разных базах данных).
- Найдите время, чтобы выбрать имена чистых кодов для ваших новых таблиц и убедитесь, что ваши новые проекторы никогда не касаются старого вывода, так как имена не конфликтуют.Итерируйте, пока новый повар не будет готов.Когда он пахнет хорошо, подайте его потребителям.Потребители должны переключаться в своем собственном темпе.
У вас вопрос № 2: можно ли полностью избавиться от старой проекции на этом этапе или было бы разумно сохранить конфигурациюстарая проекция где-то валяется в хранилище?(Однако я не могу придумать причину, по которой вам нужно было бы создать более старую проекцию)
- Вы не можете удалить ни данные, ни код, если вы не уверены на 100%, что читатели не торчат.Когда читателей нет, вы можете отключить их на некоторое время, чтобы повысить осведомленность в последнюю минуту (существует ли это слово?).После безопасного времени без жалоб вы можете безопасно удалить данные без необходимости резервного копирования, так как фактически они были «функцией» событий.Вы также можете безопасно удалить код старого проектора, если для вашего кода используется система контроля версий.
Надеюсь на помощь!