Развертывание (единственного node) веб-приложения Django с практически нулевым временем простоя на EC2

Вопрос: Каковы хорошие стратегии достижения 0 (или как можно ближе к 0) времени простоя при использовании Django?

Большинство ответов, которые я читал, говорят "используйте юг" или "используйте ткань", но это очень расплывчатый ответ ИМХО. Я фактически использую оба, и я все еще задаюсь вопросом, как достичь нулевого времени простоя как можно больше.

Некоторые сведения:

У меня есть приложение Django с приличным размером, которое я размещаю на EC2. Я использую Юг для переноса схем и данных, а также fabric с boto для автоматизации повторяющихся задач развертывания/резервного копирования, которые запускаются с помощью набора Jenkins (сервер непрерывной интеграции). Используемая база данных является стандартным экземпляром PostgreSQL 9.0.

У меня есть...

  • промежуточного сервера, который постоянно редактируется нашей командой со всем новым контентом и загружается с последним и самым лучшим кодом и...

  • живой сервер, который продолжает меняться с учетными записями пользователей и пользовательскими данными - все записано в PostgreSQL.

Текущая стратегия развертывания:

При развертывании нового кода и содержимого создаются два моментальных снимка EC2 на обоих серверах (live и staging). Живой эфир переключается на страницу "Обновление нового контента"...

Время простоя начинается.

Сервер live-clone переносится в ту же версию схемы, что и сервер промежуточного уровня (с использованием юга). Создается дамп только таблиц и последовательностей, которые я хочу сохранить из живых (в частности, учетные записи пользователей вместе с их данными). Как только это будет сделано, дамп будет загружен на сервер клонирования. Таблицы, которые были сохранены в реальном времени, усекаются и данные вставляются. По мере того, как данные на моем живом сервере растут, на этот раз явно увеличивается.

Как только нагрузка будет завершена, эластичные ips живого сервера будут заменены на стадион-клон (и, таким образом, он стал новым живым). Экземпляр live и экземпляр live-clone завершаются.

Время простоя.

Да, это работает, но по мере роста данных мое "виртуальное" нулевое время простоя становится все дальше и дальше. Конечно, что-то, что перешло мне в голову, - это как-то использовать репликацию и начать изучать репликацию PostgreSQL и "в конечном итоге последовательные" подходы. Я знаю, что есть какая-то магия, которую я мог бы сделать, возможно, с балансировщиками нагрузки, но проблема создания учетных записей в то же время делает ее сложной.

На что бы вы порекомендовали меня?

Обновление

У меня есть типичное приложение Django node.. Я надеялся на решение, которое будет углубляться с конкретными проблемами django. Например, идея использования поддержки Django для нескольких баз данных с настраиваемыми маршрутизаторами наряду с репликацией перешла мне в голову. Есть вопросы, связанные с тем, на что я надеюсь, что ответ затронет.

Ответ 1

Что может заинтересовать, это техника под названием Canary Releasing. В прошлом году я увидел отличную презентацию Jez Humble на конференции по программному обеспечению в Амстердаме; речь шла о выпуске с низким уровнем риска, слайды здесь.

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

Ответ 2

Живой сервер не должен мигрировать. Этот сервер должен быть доступен с двух промежуточных серверов, server0 и server1. Первоначально сервер0 является живым, и изменения вносятся в server1. Когда вы хотите сменить программное обеспечение, переключитесь на живые серверы. Что касается нового контента, это не должно быть на промежуточном сервере. Это должно быть на реальном сервере. Добавьте столбец в свои таблицы с номером версии для таблиц содержимого и измените базу кода, чтобы использовать правильный номер версии контента. Разрабатывайте программное обеспечение для копирования старых версий в новые строки с обновленными номерами версий по мере необходимости. Поместите текущий номер версии в свои settings.py на server0 и server1, чтобы у вас было центральное место для программного обеспечения, которое можно было бы использовать при выборе данных, или создать приложение для доступа к базе данных, которое можно обновить, чтобы получить правильные версии контента. Конечно, для файлов шаблонов они могут быть на каждом сервере и будут подходящими.

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

Ответ 3

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

Почему вы создаете новый сервер в первую очередь? Почему бы не перенести базу данных на место (конечно, после того, как вы тщательно протестировали миграцию), и, как только это будет сделано, обновите код и "перезапустите" свои процессы (например, gunicorn может принять сигнал HUP, который сделает он перезагружает приложение, не отбрасывая соединения в очереди).

Во многих миграциях не будет необходимости блокировать таблицы базы данных, поэтому это безопасно. Для остальных есть другие способы сделать это. Например, если вы хотите добавить новый столбец, который должен быть заполнен с правильными данными, вы можете сделать это в следующих шагах (кратко описано):

  • Добавьте столбец как принимающий значения NULL и сделайте запись django в этот столбец, чтобы новые записи имели правильные данные.
  • Заполните заполняющие записи.
  • Создайте django для чтения из нового столбца.

Ответ 4

Чтобы достичь 0 времени простоя, вы должны иметь как минимум 2 сервера + балансировщик. И обновляйте их последовательно. Если вы хотите обновить как базу данных, так и приложение - и иметь 0 простоя - у вас должно быть 2 сервера db. Никаких чудес, ни серебряной пули, ни джанго вы не уйдете из проблем с развертыванием.