Развертывание без простоя - переходная схема БД

14

Достижение нулевого времени простоя Развертывание затронуло ту же проблему, но мне нужен совет по стратегии, которую я рассматриваю.

контекст

Веб-приложение с Apache / PHP для обработки на стороне сервера и MySQL DB / filesystem для сохранения.

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

Я намерен применять обновления к приложению без каких-либо простоев. Я очень старался, когда проектировал инфраструктуру, чтобы обеспечить 100% работоспособность; Было бы очень обидно, если бы после каждого обновления было 10-15 минут простоя. Это особенно важно, так как у нас будет очень быстрый цикл выпуска (иногда он может достигать одного или нескольких выпусков в день).

Топология сети

Это краткое изложение сети:

                      Load Balancer
             |----------------------------|
              /       /         \       \  
             /       /           \       \ 
 | Web Server |  DB Server | Web Server |  DB Server |
 |-------------------------|-------------------------|
 |   Host-1   |   Host-2   |   Host-1   |   Host-2   |
 |-------------------------|-------------------------|
            Node A        \ /        Node B
              |            /            |
              |           / \           |
   |---------------------|   |---------------------|
           Switch 1                  Switch 2

   And onward to VRRP enabled routers and the internet

Примечание: серверы БД используют репликацию мастер-мастер

Предлагаемая стратегия

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

  1. Веб-сервер на узле A отключен; трафик продолжает обрабатываться веб-сервером на узле B.
  2. Изменения переходной схемы применяются к серверам БД
  3. Веб-сервер База кода обновляется, кэши очищаются, и выполняются любые другие действия по обновлению.
  4. Веб-сервер A подключен к сети, а веб-сервер B отключен.
  5. Обновлена ​​база кода веб-сервера B, очищены кэши и предприняты любые другие действия по обновлению.
  6. Веб-сервер B подключен к сети.
  7. Окончательные изменения схемы применяются к БД

«Переходная схема» будет разработана для создания кросс-версии совместимой БД. В основном это будет использовать представления таблиц, которые имитируют схему старой версии, а сама таблица будет изменена на новую схему. Это позволяет старой версии взаимодействовать с БД в обычном режиме. Имена таблиц будут включать номера версий схемы, чтобы не было путаницы в том, в какую таблицу писать.

«Final Schema» удалит обратную совместимость и приведёт схему в порядок.

Вопрос

Короче, будет ли это работать?

более конкретно:

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

  2. Существуют ли более простые методы, обеспечивающие такую ​​степень стабильности, а также позволяющие выполнять обновления без простоев? Также предпочтительно избегать «эволюционной» стратегии схемы, так как я не хочу быть привязанным к обратной совместимости схемы.

Marvin
источник

Ответы:

4

Похоже, что то, что вы действительно ищете, - это не столько высокая доступность, сколько постоянная доступность .

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

Производство Один

Эта среда является вашей текущей действующей версией программного обеспечения, используемого пользователями. Он имеет свои собственные веб-серверы, серверы приложений, серверы баз данных и табличное пространство. Он работает независимо от любой другой среды. Балансировщик нагрузки, которому принадлежит конечная точка разрешения домена для этих служб, в данный момент указывает на эти веб-серверы.

Производство Два

Это в основном промежуточная среда релиза, идентичная Production One. Вы можете выполнить обновления релиза здесь и провести тесты на работоспособность до начала мероприятия. Это также позволяет вам безопасно выполнять изменения базы данных в этой среде. Балансировщик нагрузки не указывает на эту среду в настоящее время.

Производство ДР

Это еще один дубликат в отдельном дата-центре, расположенном в другом регионе мира. Это позволяет переключаться при сбое в случае катастрофического события путем переключения DNS на балансировщике нагрузки.

Go Live

Это событие по существу обновляет запись DNS для циклического преобразования в производство два из производства один или наоборот. Это займет некоторое время для распространения по всем DNS-серверам мира, поэтому вы оставляете обе среды на некоторое время включенными. Некоторые пользователи МОГУТ работать в существующих сессиях над старой версией вашего программного обеспечения. Большинство пользователей будут устанавливать новые сеансы на обновленной версии вашего программного обеспечения.

Перенос данных

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

Вывод

После того, как вы полностью завершили событие выпуска, Production Two станет вашим основным и вы приступите к установке следующего выпуска в Production One для следующего цикла развертывания.

Недостатки

Это сложная настройка среды, и для ее успешного выполнения требуется большой объем системных ресурсов, часто в два-три раза больше системных ресурсов. Работа таким способом может быть дорогой, особенно если у вас очень большие системы интенсивного использования.

maple_shaft
источник
Итак, если я правильно понял, вы предлагаете вместо «переходного» изменения схемы БД, которое применяется, пока Db все еще используется, Db-A остается в сети со старой схемой, в то время как Db-B обновляется до новой схемы. Когда обновление готово к выпуску, веб-серверы переключаются, и данные, записанные в Db A во время подготовки обновления, переносятся в Db B (предположительно, путем применения всех изменений после определенной отметки времени).
Марвин
@PeterScott Вы получили это. Просто имейте в виду, что вы не хотите запускать сценарий, пока не убедитесь, что все активные сеансы в старой системе завершены, и прошло достаточно много времени, чтобы все кэши DNS были обновлены до нового CNAME или IP-адреса.
maple_shaft
1
Я должен быть хорошо в обоих этих пунктах; сеансы сохраняются в БД, а не в серверном хранилище, чтобы избежать привязки сеансов к конкретным виртуальным машинам, и в настоящее время я намерен попробовать использовать балансировщик нагрузки не на основе DNS. У меня не будет избыточности на уровне центра обработки данных, но это может подождать год или около того после запуска приложения.
Марвин
2

Ваша стратегия здорова. Я бы только предложил рассмотреть вопрос о расширении «переходной схемы» в полный набор «таблиц транзакций».

В случае таблиц транзакций SELECT (запросы) выполняются для нормализованных таблиц, чтобы гарантировать правильность. Но все INSERT, UPDATE и DELETE базы данных всегда записываются в денормализованные таблицы транзакций.

Затем отдельный параллельный процесс применяет эти изменения (возможно, с использованием хранимых процедур) к нормализованным таблицам в соответствии с установленными бизнес-правилами и требованиями схемы.

В большинстве случаев это будет практически мгновенно. Но разделение действий позволяет системе учитывать чрезмерную активность и задержки обновления схемы.

Во время изменений схемы в базе данных (B) обновления данных в активной базе данных (A) попадают в ее таблицы транзакций и немедленно применяются к ее нормализованным таблицам.

При восстановлении базы данных (B) транзакции из (A) будут применены к ней путем записи их в таблицы транзакций (B). Как только эта часть будет выполнена, (A) может быть отключен, и изменения схемы будут применены там. (B) завершит применение транзакций из (A), одновременно обрабатывая свои текущие транзакции, которые будут стоять в очереди точно так же, как (A), и «живые» будут применяться так же, как и при возврате (A).

Строка таблицы транзакций может выглядеть примерно так ...

| ROWID | TRANSNR | DB | TABLE | SQL STATEMENT
    0        0       A    Name   INSERT INTO Name ...
    1        0       A    Addr   INSERT INTO Addr ...
    2        0       A    Phone  INSERT INTO Phone ...
    3        1       A    Stats   UPDATE Stats SET NrOfUsers=...

«Таблицы» транзакций могут фактически быть строками в отдельной базе данных NoSQL или даже последовательными файлами, в зависимости от требований к производительности. Бонус заключается в том, что кодирование приложения (в данном случае веб-сайта) становится немного проще, поскольку оно выполняет запись только в таблицы транзакций.

Идея следует тем же принципам, что и двойная бухгалтерия, и по тем же причинам.

Таблицы транзакций аналогичны бухгалтерскому «журналу». Полностью нормализованные таблицы аналогичны бухгалтерской «бухгалтерской книге», где каждая таблица чем-то напоминает бухгалтерскую «учетную запись».

В бухгалтерском учете каждая транзакция получает две записи в журнале. Один для «списанной» учетной записи, а другой для «зачисленной» учетной записи.

В РСУБД «журнал» (таблица транзакций) получает запись для каждой нормализованной таблицы, которая будет изменена этой транзакцией.

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

DocSalvager
источник
1
Мне нравится сравнение с бухгалтерским учетом. Итак, если я понял, таблицы транзакций позволяют мне помещать очень небольшую задержку при записи данных в конкретную нормализованную таблицу, чтобы я мог применить все изменения схемы без риска прерывания в середине изменений? Затем, с обновленной схемой таблицы, я могу возобновить процесс, который применяет денормализованные транзакции к нормализованным таблицам (этот процесс способен отображать запросы данных старой схемы в новую схему)?
Марвин
1
Да. Вы бы изменили хранимые процедуры сопоставления (или что-то еще), чтобы приспособить как старые, так и новые данные. Новые столбцы NOT-NULL могут заполняться из старых данных кодом, который означает «запросить это при обновлении пользователя». Столбцы, которые нужно разделить (т.е. FULLNAME на FIRST и LAST), требуют некоторого алгоритма. Я рекомендую добавить 1 или более столбцов типа комментариев в таблицы для новых требований к бизнесу. Если вы этого не сделаете, я гарантирую, что пользователи будут использовать другие столбцы для этой цели, и исправление данных будет практически невозможно.
DocSalvager
Как бы вы предотвратили запросы SELECT, структурированные для старой схемы, применяемые к новой схеме? Я мог бы использовать создание табличного представления и переименовать таблицу схемы (с номером версии схемы), но это все еще было бы проблематично, пока изменения схемы применяются, поскольку они применяются непосредственно к нормализованной таблице.
Марвин
1
Когда вы добавляете таблицу, столбец или что-либо еще в RDBMS, вы на самом деле просто добавляете строки в набор внутренних таблиц, в которые может записываться только механизм RDBMS. Администраторы баз данных управляют базой данных, запрашивая их через VIEW. Поскольку Oracle, IBM, MS и т. Д. Являются экспертами и говорят, что это лучший способ, похоже, мы должны следовать их примеру. Создайте набор VIEW для каждой версии приложения. Вы можете смоделировать их после (обычно довольно денормализованных) таблиц, которые разработчики хотят, чтобы вы создали, чтобы вы могли должным образом нормализовать, чтобы предотвратить повреждение данных.
DocSalvager
Благодарю. Мне нужно подумать об этом. я создаю в приложении уровень ORM, который полностью удаляет всю логику сохранения состояния из основного домена; Будучи более основанным на программировании на стороне сервера, я склонен решать проблемы больше с этой стороны, чем со стороны администрирования БД. Используя мою текущую стратегию, Db вполне бы справился с ORM, активно управляя необработанными таблицами. Добавление табличных представлений и, возможно, журнала транзакций увеличивает сложность ORM, но также позволяет поддерживать несколько версий схемы без разделения данных.
Марвин