- PVSM.RU - https://www.pvsm.ru -

Дизайн и эволюция Хоттабыча

Нынче в каждой приличной организации, разрабатывающей серьезное программное обеспечение, принято делиться, какими путями создавались и развивались ее проекты. Мы считаем это отличной тенденцией и готовы поведать свой вариант развития одного из внутренних проектов компании «СБИС». Он влияет самым серьезнейшим образом на все ее остальные продукты, и его ласково называют — «Хоттабыч», ибо делает волшебство!

Каждые 100 секунд он обновляет какое-нибудь приложение в боевом или в тестовом окружении. Приложений у нас только в «продакшн» около 200, а на тестовых стендах — больше 1000. Количество виртуальных серверов, на которых развернуто каждое приложение – от двух до нескольких сотен. Итак, по порядку…

Дизайн и эволюция Хоттабыча - 1

До Большого взрыва

Online CБИС вышел недавно — в 2010 году. До этого мы были как все приличные приложения — desktop. Сначала жили под DOS, потом под консолью Windows, затем стали полноценным Windows приложением, ну все как у людей. Данные клиентов хранили либо в СУБД «Pervasive», либо в базе собственного изготовления с загадочным названием «Muzzle». Обновлением своего СБИС тогда занимались сами клиенты. Самым сложным в обновлении была конвертация базы. Для этой операции использовалась специальная утилита Jinnee.

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

Большой взрыв вот-вот начнется

Внезапно в 2010 году СБИС стал web-сервисом под IIS и сменил хранилища данных на PostgreSQL. Клиентам от этого, конечно, стало проще — у них уже не болела голова об обновлении, а мы еще не осознавали, во что вляпались и пока по старинке обновляли свой web-сервис, как это делали с desktop-приложением. Все так же ручками запускали Jinnee, научив его конвертировать PostgreSQL. И как-то это не напрягало, сервис был практически один, база одна, online-клиентов еще было немного. Все усилия были направлены в тот момент на совершенствование конвертации PostgreSQL с помощью Jinnee.

Но скоро web-сервисы стали плодиться, и число клиентов стремительно выросло до 300 тыс. Нужно было обновлять уже десяток сервисов, располагавшихся на полусотне серверов. Вручную это делать невыносимо, да и обновления проходили по ночам в выходные. Тогда еще во время обновления клиенты работать не могли, получая парковочную страницу с текстом «Извините, приложение временно недоступно, идут технические работы, ожидаемое время разблокировки 6:00».

Налицо нарисовались три проблемы:

  1. исключить ручную работу при обновлении, а значит, ускорить саму работу и уменьшить ошибки из-за человеческого фактора;
  2. минимизировать простои клиентов во время обновления;
  3. дать выспаться командам.

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

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

Такой необычный способ хранения дает нам следующие плюшки:

  1. можно конвертировать данные одного клиента независимо от другого;
  2. можно легко перегонять данные клиента из одной базы в другую;
  3. клиент никогда не сможет увидеть чужие данные.

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

Дизайн и эволюция Хоттабыча - 2

Большой взрыв начинается

К концу осени 2012 года мы задумали новый сервис для реализации обновления «с человеческим лицом». Сформировали команду из трех человек, и, помолясь, приступили…

Архитектура системы обновления сложилась сразу из следующих компонент:

  • управляющий обновлениями сервис;
  • сервис метаинформации и конфигурации сервисов облака;
  • диспетчер;
  • агенты обновления;
  • хранилище дистрибутивов приложений.

Управляющий сервис получил название «Хоттабыч», это также была аллюзия на утилиту «Jinnee», умевшую конвертировать базы.

Сервис метаинформации и конфигурации сервисов облака был у нас с самого начала и неплохо функционировал, мы называем его «Управление облаком». Для нужд обновления его задача — выдать информацию, где топологически расположены роботы, web-сервисы и какие у них настройки. Именно он командует диспетчерами, чтобы они выдавали парковочные страницы о недоступности сервисов. Использование диспетчеров изначально задумывалось как простых балансировщиков http-запросов, но потом их функции стали существенно шире.

Агенты обновления(агенты Хоттабыча) — это службы на хостах сервисов, призванные как раз выполнять команды на их обновление.

Хранилище дистрибутивов — название говорит за себя. Дистрибутивы тоже существовали к этому моменту, не было только хранилища.

Взаимодействовать это примерно должно было так:

  1. Хоттабыч получает команду на обновление приложения на нужную версию;
  2. Обращается в сервис управления облаком за топологией сервиса;
  3. Скачивает на расшаренный диск дистрибутив нужной версии;
  4. Делит все сервера сервисов пополам — одна часть будет обновляться, пока вторая будет работать;
  5. Рассылает команды агентам первой части серверов на обновление с указанием, где лежит дистрибутив;
  6. Агенты закачивают себе дистрибутив, распаковывают его и меняют старую версию на новую
  7. Затем управляющий сервис делает то же самое для оставшейся части серверов;
  8. Когда все агенты отчитались об окончании работы, управляющий сервис переходит в состояние ожидания подтверждения обновления, ведь его могут и откатить.

Оставалось разработать сам сервис с интерфейсом, агентов обновления и организовать хранилище дистрибутивов с выкладкой туда.

Первое детище..

На первой итерации нам требовалось только обновление без конвертации данных. Хранилище дистрибутивов решили делать на SVN — вот дураки!

Структурно организация хранилища была иерархической:

дистрибутив такой-то
    |- версия такая-то
        |- сам дистрибутив + файлы информации о нем
    |- версия сякая-то
        |- сам дистрибутив + файлы информации о нем

Хоттабыча решили писать на своей же платформе СБИС. Как раз это мы хорошо умели делать, тут сомнений не было. С агентом обновления были сомнения, но в итоге его тоже стали делать на платформе СБИС (это С++). Для агентов было поставлено жесткое условие — они должны регулярно и максимально информативно отчитываться Хоттабычу о своей работе.

Дизайн и эволюция Хоттабыча - 3Обновление разбили на три основные фазы:

1. Фаза подготовки — во время нее доставляются файлы дистрибутивов на хосты приложений, делаются различные подготовительные действия, которые никак не нарушают работы сервисов.
2. Фаза обновления — на ней, собственно, выполняется обновление, вот здесь работа сервиса как раз иногда может быть приостановлена.
3. Фаза подтверждения — здесь доделываются второстепенные задачи обновления, зачищаются ненужные файлы, и т.п. Сервисы в этот момент уже работают.

Весь процесс контролируется с фронтенда ответственным, и его всегда можно приостановить, продолжить или откатиться. По каждому узлу обновления во фронтенде можно увидеть, в каком состоянии он находится, что на нем происходит, происходило, а может уже и все…

Дизайн и эволюция Хоттабыча - 4

Большой взрыв состоялся

Дизайн и эволюция Хоттабыча - 5
Наконец, весной 2013 мы смогли провести первое обновление в боевом окружении, затем второе, третье, и это так всем понравилось, что на радостях обновления стали делать днем в рабочее время. Такой вид обновления мы назвали «легким» т. к. оно проходило без особых проблем для всех — как для нас, так и для клиентов. Это был прорыв!

Вселенная расширяется

После первых успехов у нас вылезла первая проблема. На тестовых стендах дистрибутивы загружали в хранилище так часто и размера до 1.5Гб, что SVN затрещал по швам. Конечно, он не годился для хранения больших бинарных файлов, и мы быстренько ушли на хранение дистрибутивов на linux-сервере. Тоже так себе решение, т. к. пришлось с windows-серверов держать шару на linux-диск, но стало уже намного лучше.
Дизайн и эволюция Хоттабыча - 6
Впереди ждало обновление сервисов с конвертациями баз. В этой итерации Jinnee, умевший конвертировать базы, доставлялся агентом на один из серверов обновляемого. Агент его запускал, командуя, какую базу конвертировать.

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

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

И вновь о конвертации баз

Базы клиентов конвертировались подолгу — несколько часов. Это нас совсем не устраивало. Мы в состоянии конвертировать данные одного клиента в базе независимо от данных другого. Тогда клиент вместо часов простоя может получить приостановку работы от нескольких секунд до нескольких минут. И нужно быть очень несчастливым, чтобы нарваться на эти секунды. При таком подходе часть клиентов во время обновления в базе будет жить на старой версии данных и обслуживаться старой логикой, а другая часть — на новой версии данных и обслуживаться новой логикой. Обновляемый клиент должен просто ждать.

Остановились на следующем решении. Предварительно фронтовые диспетчера переводятся в режим «поклиентного обновления». Это значит, что на каждый запрос от клиента они обращаются в Redis за информацией, в каком состоянии клиент: обновлен, не обновлён или еще обновляется. Дизайн и эволюция Хоттабыча - 7 Информацию туда выкладывает Хоттабыч, когда принимает решение об обновлении клиента. Если клиент не обновлен, диспетчер бросает запрос на пул не обновленных серверов; если обновлен, то на пул обновленных серверов; а если обновляется, выдает клиенту парковочную страницу.

Этот вариант мы выкатили в «продакшн» в конце 2014-го. Он так прижился, что стал практически основным вариантом конвертации. Конечно, не все наши базы можно так конвертировать, но не все наши базы конвертируются так долго.

Сейчас у нас более 1 млн. клиентов, и они располагаются более чем на 650 базах. И конвертации проходят достаточно незаметно.

И пришел Linux …

Годы эксплуатации сервисов под IIS, привели нас к устойчивой мысли — IIS нам не нужен, да и Windows тоже, т.к., по сути, стек технологий Microsoft мы не использовали. А под Linux меньше накладных расходов на серверную ОС, лучше оптимизируется код на С++, больше выбора серверного оборудования, например, IBM Power, и т.п.

Дизайн и эволюция Хоттабыча - 8И вот в 2015 году наступило крупное событие. Команда, разрабатывающая ядро наших сервисов, подготовила почву для миграции на Linux, и миграция началась. Мы этим воспользовались для отказа от SSH при обновлении сервисов на Linux и портировали на него агента Хоттабыча.

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

И снова возвращаемся к конвертации баз

Простой клиента мы минимизировали и это здорово. Но все-таки как его вообще убрать? Частенько конвертацию можно проводить, вообще не останавливая работу базы. Например, добавляя индекс или какое-нибудь поле. Мы назвали такую конвертацию «легкой». Но вот вопрос, а как узнать можно ли «легкую» конвертацию проводить? На это нам дает ответ все та же чудодей-Jinnee. Ему на вход подается новый дистрибутив и базы-кандидаты на конвертацию, он по ним проводит анализ ожидаемых изменений и выдает рекомендации, какую конвертацию проводить.

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

О патчах

Часто в работе сервиса обнаруживается ошибка и ее исправление нужно получить как можно быстрее. Правка обычно небольшая — один файлик, а сборка нового дистрибутива может быть достаточно долгой, да и нет в этом необходимости. Такой вид обновления мы назвали «патчем». Исправленный файл передается Хоттабычу, он заменяет его в существующем дистрибутиве, поднимая его версию, и накатывает на сервис. Все происходит очень быстро.

Упорядочение неупорядоченного

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

В итоге, мы остановились на таком решении. Разработчик реализует логику скрипта в виде обычного кода запроса, исполняемого на сервисе. Так он получает всю внутреннюю инфраструктуру сервиса. Хоттабыч доставляет код запроса на сервис и вызывает его, отслеживая исполнение на каждой из баз сервиса. Администратору ЦОД остается только нажимать кнопку в интерфейсе Хоттабыча, всю остальную логику он берет на себя. Сейчас это самый популярный вид обновления.

После большого взрыва

Дизайн и эволюция Хоттабыча - 9
Хоттабыч продолжает развиваться, переход на Linux открыл нам новые возможности, на очереди контейнеризация наших сервисов. Также мы планируем добиться, чтобы клиенты даже при агрессивной конвертации не получали минимальных простоев в работе. Из-за внедренной сети агентов Хоттабыча на сервера нашего ЦОД, мы получили дополнительные преимущества на которые сразу не рассчитывали. Например, агенты Хоттабыча теперь не только обновляют, но и выполняют перезагрузки процессов сервисов по требованию, конфигурационные задачи, некоторый мониторинг.

Сейчас в «хозяйство» Хоттабыча входит ~ 5 тыс. серверов, и он с этим неплохо справляется. Число баз, которые периодически конвертируются ~ 2 тыс. Все это обновляется с минимумом простоя для более чем 1 млн. клиентов вот уже длительное время.

Автор: Алексей Терентьев

Автор: tensor_sbis

Источник [1]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/postgresql/254456

Ссылки в тексте:

[1] Источник: https://habrahabr.ru/post/327476/