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

Как команда инженеров Airbnb «разбила» основную БД проекта за пару недель

Примечание переводчика: На Хабре и в нашем блоге о корпоративном IaaS [1] мы много пишем об облачных технологиях, и рассматриваем интересные инфраструктурные проекты различных компаний. Ранее мы рассказывали [2] о масштабировании Apache Storm в Spotify, создании [3] 20- и 30-гигабитных соединений в сетях Ethernet командой проекта 45 Drives, а сегодня речь пойдет о том, как инженеры Aribnb занимались [4] разбиением основной базы данных проекта.

Как команда инженеров Airbnb «разбила» основную БД проекта за пару недель - 1

Каждый год трафик Airbnb растет в 3,5 раза быстрее, а его пик приходится на летний период

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

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

В попытке сэкономить несколько недель работы сотрудников один из наших блестящих [5] разработчиков предложил интересную идею – использовать репликации в MySQL для обеспечения целостности данных. Жертвуя небольшим количеством времени простоя, мы тем самым можем выполнить реорганизацию БД без написания лишних строчек кода на хранение промежуточных результатов и миграцию данных.

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

Как команда инженеров Airbnb «разбила» основную БД проекта за пару недель - 2

«Приготовьтесь, скоро наступит лето»

Небольшая предыстория

Мы с нашими друзьями из Asana [6] и Percona [7] пришли к общему мнению о том, что горизонтальная фрагментация вызывает слишком много сложностей, поэтому мы отдаем предпочтение вертикальному разбиению по выполняемым функциям, для того чтобы распределить нагрузку и устранить возможные сбои.

К примеру, для каждого независимого Java и Rails сервиса у нас имеется своя выделенная база данных, каждая из которых работает на собственном экземпляре RDS. Однако исторически сложилось так, что большая часть основных данных все еще находится в исходной базе данных, оставшееся со временен, когда Airbnb было монолитным приложением на Rails.

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

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

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

Во-вторых, несмотря на то, что к началу 2015 года у нас имелось 130 разработчиков, наши команды работали в самых разных направлениях развития наших продуктов – от персонализированного поиска, средств обслуживания клиентов, обеспечения безопасности и проведения международных платежей до надежных мобильных приложений с ограниченными возможностями связи – лишь небольшая доля сотрудников занималась нашей инфраструктурой. Учитывая эти обстоятельства, мы решили воспользоваться возможностью репликации MySQL, чтобы упростить процесс проектирования и затратить на это минимум усилий.

План действий

Решение использовать встроенную репликацию MySQL для переноса данных означало, что нам больше не нужно было прилагать особых усилий для обеспечения целостности, потому что репликация является проверенной методикой. Наша база данных MySQL работает на основе сервиса Amazon RDS, так что создать новые копии, доступные для чтения (read replicas) и перевести копию в режим самостоятельного мастер-сервера относительно несложно.

После внесенных изменений наша модель имела следующий вид:

Как команда инженеров Airbnb «разбила» основную БД проекта за пару недель - 3

Мы создали новую реплику (message-master, или «мастер сообщений») из нашей основной базы данных на мастер-сервере, которая выполняла бы роль нового отдельного мастер-сервера после ее преобразования. Затем мы «прикрепили» к ней вторичную реплику (message-replica, или «реплика сообщений»), которая бы играла роль реплики для мастера сообщений.

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

Стоит отметить, что во время работы со своей базой данных можно использовать фильтры [8] репликации, чтобы избежать копирования ненужных таблиц и, возможно, сократить время, необходимое для преобразования.

Первый этап: подготовка

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

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

Далее, у нас есть расширенный конвейер данных (data pipeline), на базе которого осуществляется аналитика офлайн-данных и дальнейшая их обработка. Поэтому следующим шагом подготовительного этапа был перенос всех необходимых операций конвейерной обработки с целью получения данных из реплики мастера сообщений, гарантировав, таким образом получение самых последних данных после преобразования.

Одним из побочных явлений нашего плана по переносу данных был тот факт, что новая база данных имела бы то же имя, что и наша текущая база данных (не путайте с именем наших экземпляров RDS, например, «мастер сообщений» и «реплика мастера сообщений»), хотя после преобразования данные в них будут отличаться. Тем не менее, у нас появилась возможность упорядочить все имена в наших конвейерах данных, поэтому мы решили не переименовывать БД.

И, наконец, так как предоставлением доступа на запись в эти таблицы занималось исключительно основное приложение Airbnb на Rails, мы могли перенаправить весь необходимый служебный трафик в новую реплику БД сообщений, для того чтобы упростить проведение основной операции.

Второй этап: реализация

Как команда инженеров Airbnb «разбила» основную БД проекта за пару недель - 4

Важный день для членов команды по работе с инфраструктурой

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

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

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

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

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

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

Проверить, все ли готово к репликации, убедившись, что:

  1. Последние вводимые данные в папке входящих сообщений находятся в таблицах мастера сообщений и реплики мастера сообщений;
  2. Закрыты все соединения с базой данных сообщений на главном мастер-сервере;
  3. Установлены новые соединения с мастером сообщений.

Провести преобразование мастера сообщений. По своему опыту мы знаем, что доступ к базе данных полностью отсутствует в течение около 30 секунд в процессе преобразования на RDS и что в это время данные с мастер-сервера считать нельзя. Запросы на запись, в свою очередь, не будут обработаны примерно в течение четырех минут, так как перед началом преобразования должно пройти около 3,5 минут.

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

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

Если бы эта операция провалилась, мы бы восстановили настройки хоста для базы данных в Zookeeper, а обмен сообщениями возобновился бы почти мгновенно. Однако мы потеряли бы все записи, сделанные в новых независимых базах данных сообщений.

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

Итог

Как команда инженеров Airbnb «разбила» основную БД проекта за пару недель - 5

Заметное снижение числа записей в основной базе данных на мастер-сервере

В итоге этот проект занял около двух недель. За это время произошло не более семи 30-секундных простоев сервиса входящих сообщений, а размер нашей основной базы данных сократился на 20%.

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

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

Как команда инженеров Airbnb «разбила» основную БД проекта за пару недель - 6

Синьао, ведущий разработчик проекта, отмечает его успешное окончание

Автор: ИТ-ГРАД

Источник [10]


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

Путь до страницы источника: https://www.pvsm.ru/it-infrastruktura/106838

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

[1] блоге о корпоративном IaaS: http://iaas-blog.it-grad.ru/

[2] рассказывали: http://habrahabr.ru/company/it-grad/blog/264549/

[3] создании: http://habrahabr.ru/company/it-grad/blog/267629/

[4] занимались: http://nerds.airbnb.com/how-we-partitioned-airbnbs-main-db/

[5] блестящих: https://github.com/schleyfox

[6] Asana: https://eng.asana.com/2015/04/sharding-is-bitter-medicine/

[7] Percona: https://www.percona.com/blog/2009/08/06/why-you-dont-want-to-shard/

[8] фильтры: https://dev.mysql.com/doc/refman/5.7/en/change-replication-filter.html

[9] Multi-AZ: http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html

[10] Источник: http://habrahabr.ru/post/273583/