Upgrade without downtime
От: Шубин Евгений Россия http://erladvisor.blogspot.de/
Дата: 05.07.19 18:18
Оценка:
Вот есть у нас приложение (язык вам на выбор), которое лезет в реляционную базу, Postgres для простоты.
Допустим приложение одно и не надо его разбивать на микросервисы, чтобы отсечь пустой трёп людей с SOA-головного мозга.
Естественно схема базы данных может менятся при релизах. Пусть даже будет master-slave репликация базы.
Как же выкатить релиз 100% без downtime при условии что меняется и схема базы и код приложения?

Я видел попытки в aws beanstalk, где делают swap dns имён и sticky connections в loadbalancer, но ведь при любом сценарии обновления сервера приложений будет ситуация, когда код будет ожидать другую схему базы.
Я знаю про hot code upgrade в erlang, но это не просто сложно, а очень сложно.
И не надо писать что код должен уметь работать и с последней схемой базы и с предпоследней — это тоже не реально практически.

У меня есть чувтво что master-slave и wal файлы могут прийти на помощь, но даже теоретически не вижу такой сценарий.

Поделитесь опытом как такое делается.
Re: Upgrade without downtime
От: Gurney Великобритания www.kharlamov.biz
Дата: 05.07.19 21:38
Оценка: 6 (1)
Здравствуйте, Шубин Евгений, Вы писали:

ШЕ>Вот есть у нас приложение (язык вам на выбор), которое лезет в реляционную базу, Postgres для простоты.

ШЕ>Допустим приложение одно и не надо его разбивать на микросервисы, чтобы отсечь пустой трёп людей с SOA-головного мозга.
ШЕ>Естественно схема базы данных может менятся при релизах. Пусть даже будет master-slave репликация базы.
ШЕ>Как же выкатить релиз 100% без downtime при условии что меняется и схема базы и код приложения?

В общем случае никак не делается. Хорошо что это нафиг никому не нужно.

1. Statement репликация базы с ограничениями на модификацию схемы, все изменения приводящие к нарушению совместимости репликации запрещены. Плюс код работающий с новой и старой базами.
2. Репликация на уровне входных комманд. Делается snapshot входной схемы, конвертится в новую, а потом накатывается лог бизнес операций. То есть одни и теже запросы идут в две системы и поразному приземляются в базу.

ШЕ>И не надо писать что код должен уметь работать и с последней схемой базы и с предпоследней — это тоже не реально практически.

Тогда никак это нельзя сделать, кэп.

ШЕ>У меня есть чувтво что master-slave и wal файлы могут прийти на помощь, но даже теоретически не вижу такой сценарий.

Сервер с новой _совместимой_ схемой ставится slave-ом. Когда достигается синхронизм — slave становится мастером и трафик переключается на новую версию бизнес логики.
Re: Upgrade without downtime
От: RushDevion Россия  
Дата: 06.07.19 10:25
Оценка: 6 (1)
ШЕ>И не надо писать что код должен уметь работать и с последней схемой базы и с предпоследней — это тоже не реально практически.
Это как раз самый реальный сценарий (хотя и довольно геморойный).
Особенно с микросервисным подходом, когда база сравнительно невелика и объем разовых изменений тоже мал.
Делаем так:
1. Выкатываем новую версию на отдельную ноду (бд+код),которая
1.1 Для запросов на запись пишет в новом и в старом формате.
1.2 Для запросов на чтение читает новый формат, если не получилось, то читает старый (и конвертирует в новый, либо это делает фоновый процесс)
2. Заруливаем часть трафика на новую версию. Мониторим.
3. Если все ОК — заруливаем остальной трафик.
4. Отслеживание процент конверсии данных. По достижении 100% чистим рудименты предыдущей версии.
Re: Upgrade without downtime
От: wildwind Россия  
Дата: 06.07.19 12:25
Оценка: 6 (1)
Здравствуйте, Шубин Евгений, Вы писали:

ШЕ>Поделитесь опытом как такое делается.


Один из вариантов. Реализуется репликация на прикладном уровне. Дальше поднимается копия БД, проводится миграция, запускается репликация. Клиенты постепенно переводятся на новый узел.


Оракл пытался реализовать нечто подобное на уровне БД. Не знаю насколько успешно, не вникал.
Re: Upgrade without downtime
От: Cyberax Марс  
Дата: 06.07.19 21:46
Оценка: 6 (1)
Здравствуйте, Шубин Евгений, Вы писали:

ШЕ>Как же выкатить релиз 100% без downtime при условии что меняется и схема базы и код приложения?

Делать "three step dance", как это мы называли в Амазоне:
1) Меняем схему и добавляем код, который пишет одновременно новые и старые данные. Чтение данных идёт старым кодом.
2) Переключаем чтение на новую схему.
3) Удаляем старый код и схему.

В первом шаге, понятное дело, схема не должна меняться так, что старый код будет ломаться.
Sapienti sat!
Re: Upgrade without downtime
От: vsb Казахстан  
Дата: 06.07.19 22:34
Оценка:
Здравствуйте, Шубин Евгений, Вы писали:

ШЕ>И не надо писать что код должен уметь работать и с последней схемой базы и с предпоследней — это тоже не реально практически.


Для некоторых изменений — только так. Ну или с даунтаймом.

ШЕ>Поделитесь опытом как такое делается.


Каждое изменение БД разбивается на серию маленьких изменений, которые не блокируют базу и деплоятся по очереди, возможно с деплоем новых версий приложения. Конечно приложение должно быть кластирозовано, хотя бы в двух копиях, чтобы обновлять их по очереди без даунтайма для конечного пользователя.

На хабре была статья от яндекса, где они подробно расписывали какие изменения в БД как делаются, чтобы не приводить к блокировкам. В целом там ничего сложного нет, просто надо аккуратно всё делать и, конечно, предварительно проверять на тестовой базе. Статья хорошая, даже если на 100% даунтайм не нужен, полезно знать, чтобы не делать ненужный даунтайм.
Отредактировано 06.07.2019 22:37 vsb . Предыдущая версия . Еще …
Отредактировано 06.07.2019 22:35 vsb . Предыдущая версия .
Re[2]: Upgrade without downtime
От: Дельгядо Филипп Россия  
Дата: 07.07.19 16:11
Оценка:
vsb>Каждое изменение БД разбивается на серию маленьких изменений, которые не блокируют базу и деплоятся по очереди, возможно с деплоем новых версий приложения. Конечно приложение должно быть кластирозовано, хотя бы в двух копиях, чтобы обновлять их по очереди без даунтайма для конечного пользователя.

На самом деле даже дополнение nullable column блокирует базу. И хотя сама операция в большинстве БД мгновенна, требование блокировки можно приводить к довольно длительным задержкам по записи в таблицу, так что нужно понимать, как он работает.
Re: Upgrade without downtime
От: Дельгядо Филипп Россия  
Дата: 07.07.19 16:30
Оценка:
Выкладка без простоя — стандартная практика для всех 24*7 систем.
Легко внедряется даже в команде со средним уровнем разработчиков.
Есть несколько разных сценариев.

1. Если обновление сервиса и БД не больше 1-2 секунд, то допустимо перестартовать сервис полностью, но нужно выстраивать кэши и очередь операций/retry-политик на вызывающих сервисах. Для монолита решение малореально.

2. Использование только обратно-совместимых изменений в БД (про это уже писали выше). Фактически — только добавление колонок.
Тут тоже есть тонкость, так как даже nullable колонки создаются с блокировкой, необходимо перед изменением БД прекратить все длинные транзакции.
Это достаточно просто в реализации, особенно если делать выкладки не раз в полгода, а гораздо чаще.
В общем виде изменение колонки приводит к нескольким операциям (и нескольким версиям сервиса):
— добавить колонку
— писать данные в новую и старую колонку, читать из старой
— запустить миграцию данных из старой в новую
— писать и в старую и в новую, читать из новой (после конца миграции)
— писать в новую, читать из новой.
— удалить старую колонку (если БД позволяет это сделать без блокировки или быстро или через переключение через View)

3. Во API при несовместимых изменениях необходимо создавать новые entrypoint, а не изменять существующие.

В любом случае необходимо уметь тестировать процесс выкладки, работу двух экземпляров сервиса разных версий одновременно, откат на предыдущую версию и т.п.

Для многосервисных систем (а большие системы всегда, в конечном счете, многосервисные) есть стандартные подходы canary deployment (надежнее, но сложнее в реализации, если нет service mesh) и green-blue deployment, стоит почитать.

Но вообще по этой теме много всего и в google и не только.
Re: Upgrade without downtime
От: Шубин Евгений Россия http://erladvisor.blogspot.de/
Дата: 08.07.19 14:26
Оценка: +1
Здравствуйте, Шубин Евгений, Вы писали:

ШЕ>Поделитесь опытом как такое делается.


Прочитал ответы, получается, что для среднестатистического веб приложения легче поставить заглушку на пару минут при деплое, чем заставить программистов поддерживать 2 версии базы в любимом ОРМчике.
Re[2]: Upgrade without downtime
От: Cyberax Марс  
Дата: 08.07.19 19:18
Оценка: 6 (1)
Здравствуйте, Шубин Евгений, Вы писали:

ШЕ>Прочитал ответы, получается, что для среднестатистического веб приложения легче поставить заглушку на пару минут при деплое, чем заставить программистов поддерживать 2 версии базы в любимом ОРМчике.

Именно так. Для подавляющего большинства приложений проще всего повесить баннер: "Плановые работы с 6:00 до 6:15" и не заморачиваться.
Sapienti sat!
Re[2]: Upgrade without downtime
От: Дельгядо Филипп Россия  
Дата: 09.07.19 22:17
Оценка:
ШЕ>Прочитал ответы, получается, что для среднестатистического веб приложения легче поставить заглушку на пару минут при деплое, чем заставить программистов поддерживать 2 версии базы в любимом ОРМчике.

Это не решение, так как не удастся откатить деплой в случае каких-то проблем. Т.е. если простой на часы допустим, то так можно делать.
Но даже для среднего веб-проекта с таким подходом можно выкатываться только ночью.
Но ОРМ — да, заметно мешает делать надежные приложения.
Re: Upgrade without downtime
От: Ночной Смотрящий Россия  
Дата: 10.07.19 10:00
Оценка:
Здравствуйте, Шубин Евгений, Вы писали:

ШЕ>Как же выкатить релиз 100% без downtime при условии что меняется и схема базы и код приложения?


По БД — схему меняют так, чтобы старый код не сломался. Т.е. новые элементы можно добавлять смело, удаляются элементы только после обновления кода, а то и через релиз, при изменениях как правило остаются и старые и новые элементы, данные копируются скриптом миграции. Сложность только в дельте между обновлением схемы и накаткой нового кода, но обычно их так или иначе тоже можно решить, например чтобы скрипт миграции умел отрабатывать дельту и его можно было запускать несколько раз.
По коду — как правило такие сервисы не на одной машине выполняются, а на нескольких. При апгрейде кода отключается часть машин, обновляется, потом еще часть, и так пока не будут обновлены все машины.

ШЕ>Я видел попытки в aws beanstalk, где делают swap dns имён


Своп ДНС не самое лучшее решение — дорого, так как на время деплоя нужно удваивать инфраструктуру.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re: Upgrade without downtime
От: hlt Россия  
Дата: 31.07.19 08:13
Оценка:
Здравствуйте, Шубин Евгений, Вы писали:
ШЕ>Поделитесь опытом как такое делается.

Blue-green deployment
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.