12 апреля мы запустили большой новый проект — «Битрикс24»: социальный интранет, SaaS-сервис, объединяющий в себе классические инструменты командной работы (календари, задачи, CRM, работа с документами) и социальные коммуникации («лайки», социальный поиск, мгновенные сообщения и многое другое).
Первый прототип этого сервиса был запущен еще в феврале прошлого года. На одном сервере, без каких-либо особенных возможностей для масштабирования, без резервирования на уровне датацентра… :) Только концепт.
Этой публикацией мы откроем серию постов, в которых хотели бы рассказать вам, что было сделано за год разработки, какой получилась итоговая архитектура проекта; что мы делаем для того, чтобы обеспечить настоящие «24» часа работы проекта в сутки; какие изменения пришлось сделать в платформе разработки «1С-Битрикс»; особенности работы в облаке Amazon и многое другое.
Очень хотим, чтобы наш опыт оказался полезен для всех разработчиков, которые только планируют запускать или уже эксплуатируют и поддерживают крупные веб-проекты и сервисы.
* * *
Итак, первый пост — об архитектуре проекта в целом. Поехали!
В процессе разработки самой идеи «Битрикс24» мы сформулировали для себя несколько бизнес-задач:
- С самого начала мы предполагали, что первый тариф на «Битрикс24» будет бесплатным.
- Это значит, что себестоимость такого бесплатного аккаунта для нас должна быть очень низкой.
- Наш проект — это бизнес-приложение, и значит нагрузка на него будет очень неравномерной: больше днем, меньше ночью. В идеале — хорошо бы уметь масштабироваться (в обе стороны) и в каждый момент времени использовать ровно столько ресурсов, сколько нужно.
- При этом — для любого бизнес-приложения крайне важна надежность: постоянная доступность данных и их сохранность.
- Мы стартовали сразу на нескольких рынках: Россия, США, Германия.
Эти бизнес-требования в итоге сформировали два больших «фронта» работ: формирование масштабируемой отказоустойчивой (забегая немного вперед — «облачной») платформы разработки и выбор технологической платформы для инфраструктуры проекта.
Платформа разработки «1С-Битрикс»
Традиционное устройство веб-приложений очень плохо масштабируется и резервируется. В лучшем случае — мы можем разнести по разным серверам само приложение, кэш и базу. Можем как-то масштабировать веб (но при этом должны будем решить вопрос синхронизации данных на веб-серверах). Кэш и база масштабируются уже хуже. А о распределенном гео-кластере (для резервирования на уровне датацентров) речь вообще не идет.
Огромным шагом в развитии платформы «1С-Битрикс» стало появление модуля «Веб-кластер» в версии 10.0 весной прошлого года.
Мы подробно писали о нем на Хабре. Кратко повторю основные возможности:
- Вертикальный шардинг (вынесение отдельных модулей на отдельные серверы MySQL)
- Репликация MySQL и балансирование нагрузки между серверами на уровне ядра платформы
- Распределенный кеш данных (memcached)
- Непрерывность сессий между веб-серверами (хранение сессий в базе данных)
- Кластеризация веб-сервера
В итоге мы получили возможность представить наш проект в виде веб-кластера взаимозаменяемых серверов. Все выглядело очень и очень неплохо: при увеличении посещаемости можно было быстро добавить в кластер новые серверы; в случае выхода из строя одного или нескольких серверов кластера все продолжало работать на оставшихся серверах, система продолжала беспрерывно обслуживать клиентов.
Но до идеала было еще далеко, оставались «узкие» места:
- Не был до конца решен вопрос синхронизации файлов на разных веб-серверах. На собственном сайте мы использовали csync2, он очень неплохо себя зарекомендовал. Однако на больших объемах данных мы просто не успевали бы передавать изменения по всем серверам.
- Выход из строя master-сервера в репликации MySQL означал какие-то ручные или полуавтоматические операции по переводу одного из slave'ов в режим master'а. Это требовало времени, а значит мы не могли гарантировать бесперебойную работу сервиса.
- slave'ы позволяют распределить нагрузку на базу на чтение, а master все равно остается один. Это значит, что запись остается узким местом в работе базы.
- Как показал наш собственный печальный опыт, молнии попадают в датаценты и могут их полностью вывести из строя. Значит, нужно резервировать не только отдельные серверы, но и целиком датацентр.
В платформе «1С-Битрикс» версии 11.0, вышедшей осенью 2011 года, мы решили и эти задачи. Поддержка облачных файловых хранилищ решила проблему синхронизации статического контента, а реализация поддержки master-master репликации в MySQL позволила строить географически распределенные веб-кластеры.
И мы вплотную подошли ко второй большой задаче…
Платформа для разворачивания инфраструктуры
Если честно, выбор был не очень сложным. :)
«Облако» или не «облако» — такой вопрос даже не стоял. :)
Собственное или арендуемое оборудование требует достаточно серьезных вложений в инфраструктуру на старте проекта. Масштабировать физические «железки» достаточно сложно (долго и дорого). Администрировать (особенно в разных ДЦ) — неудобно.
Поэтому — «облако»!
Какое именно? Мы выбрали Amazon AWS.
Все наши сайты работают в Амазоне достаточно давно. Нам нравится то, что есть множество уже готовых сервисов, которые можно просто брать и использовать в своем проекте, а не изобретать собственные велосипеды: облачное хранилище S3, Elastic Load Balancing, CloudWatch, AutoScaling и многое другое.
В очень упрощенном виде вся архитектура «Битрикс24» выглядит примерно так:
Web – автоматическое масштабирование
Приложение (веб) масштабируется у нас не вертикально (увеличение мощности сервера), а горизонтально (добавляем новые машины).
Для этого мы используем связку Elastic Load Balancing + CloudWatch + Auto Scaling. Все клиентские запросы (HTTP и HTTPS) поступают на один или несколько балансировщиков Amazon (ELB). Рост и снижение нагрузки мониторим через CloudWatch. Есть две интересные метрики – состояние нод EC2 (% CPU Utilization) и балансировщика (время latency – в секундах).
Мы в качестве основной характеристики используем данные о загрузке машин, так как latency может варьироваться не только из-за реальной нагрузки, но и по каким-то иным причинам: сетевые задержки, ошибки в приложении и т.п. В таком случае возможны «ложные» срабатывания, и тогда мы крайне неэффективно будем добавлять новые машины.
Сейчас в итоге автоматически стартуют новые машины, если средняя утилизация CPU (в терминах Амазона) превышает 60%, и автоматически останавливаются и выводятся из эксплуатации, если средняя нагрузка менее 30%.
Мы достаточно долго экспериментировали с этими пороговыми значениями и сейчас считаем их оптимальными. Если верхний порог ставить больше (например, 70-80%), то начинается общая деградация системы – пользователям работать некомфортно (долго загружаются страницы). Нижний порог меньше — система балансировки становится не очень эффективной, машины долго могут работать вхолостую.
Статический контент пользователей сервиса
В описанной выше схеме веб-ноды по сути становятся «расходным материалом». Они могут в любой момент стартовать и в любой момент гаситься. А это значит, что никакого пользовательского контента на них быть не должно.
Именно поэтому при создании каждого нового портала в «Битрикс24» для него создается персональный аккаунт в Амазоне для хранение данных в S3. Тем самым данные каждого портала полностью изолированы друг от друга.
При этом само хранилище S3 очень надежно. Сам Амазон подробно описывает его устройство (и, в принципе, нет поводов им не верить).
Данные в S3 реплицируются в несколько точек. При этом – в территориально распределенные точки (разные датацентры).
Каждое из устройств хранилища мониторится и быстро заменяется в случае тех или иных сбоев.
Когда вы загружаете новые файлы в хранилище, ответ об успешной загрузке вы получите только тогда, когда файл будет полностью сохранен в нескольких разных точках.
Обычно данные реплицируются в три и более устройств – для обеспечения отказоустойчивости даже в случае выхода из строя двух из них.
Иными словами, с надежностью – все хорошо. Тот же Амазон, например, говорит о том, что их архитектура S3 устроена таким образом, что они готовы обеспечить доступность на уровне двух девяток после запятой. А вероятность потери данных – одна миллиардная процента.
Два датацентра и master-master репликация
Весь проект сейчас размещается в двух датацентрах. Мы решаем этим сразу две задачи: во-первых, распределяем нагрузку (сейчас российские пользователи работают в одном ДЦ, а американские и европейские — в другом), а во-вторых, резервируем все сервисы — в случае выхода из строя одного из ДЦ, мы просто переключаем траффик на другой.
Чуть-чуть подробнее — как это все устроено.
База в каждом ДЦ является мастером относительно слейва во втором ДЦ и одновременно слейвом — относительно мастера.
Важные настройки в MySQL для реализации этого механизма — auto_increment_increment и
auto_increment_offset. Они задают смещения значений для полей auto_increment — для того, чтобы избежать дублирования записей. Грубо говоря, в одном мастере — только четные ID, в другом — только нечетные.
Каждый портал (все зарегистрированные в нем сотрудники), заведенный в «Битрикс24» в каждый конкретный момент времени работает только с одним ДЦ и одной базой. Переключение на другой ДЦ осуществляется только в случае какого-либо сбоя.
Базы в разных датацентрах синхронны, но при этом независимы друг от друга: потеря связности между датацентрами может составлять часы, данные синхронизируются после восстановления.
Надежность, надежность, надежность
Один из важнейших приоритетов в «Битрикс24» – постоянная доступность сервиса и его отказоустойчивость.
Помните простую схему сервиса? В итоге (все равно упрощенно, но тем не менее :)) она выглядит примерно так:
В случае аварии на одной или нескольких веб-нодах Load Balancing определяет вышедшие из строя машины и, исходя из заданных параметров группы балансировки (минимально необходимое количество запущенных машин), автоматически восстанавливается нужное количество инстансов.
Если теряется связность между датацентрами, то каждый датацентр продолжает обслуживать свой сегмент клиентов. После восстановления коннективити, данные в базах автоматически синхронизируются.
Если же выходит из строя полностью датацентр, или же, например, происходит сбой на базе, то весь траффик автоматически переключается в работающий датацентр.
Если это вызывает повышенную нагрузку на машины, то CloudWatch определяет возросшую утилизацию CPU и добавляет нужное количество машин уже в одном датацентре в соответствие с правилами для AutoScaling.
При этом у нас приостанавливается мастер-мастер репликация. После проведения нужных работ (восстановительных — в случае аварии, или плановых — мы, например, точно по такой же схеме в какой-то момент осуществили переход со стандартного MySQL на Percona Server — при этом без какого-либо downtime'а для пользователей сервиса), включаем базу в работу и восстанавливаем репликацию.
Если все прошло штатно, траффик снова распределяется на оба датацентра. Если при этом средняя нагрузка стала ниже порогового значения, то лишние машины, которые мы поднимали для обслуживания возросшей нагрузки, автоматически гасятся.
* * *
Этот первый пост я постарался сделать «легким», обзорным. :) Если бы вместил все то, чем хочется поделиться, в один текст и рассказал обо всем нашем опыте сразу, то получилось бы слишком много букв. :)
Мне кажется более логичным сделать серию тематических постов. Темы которые, мы уже готовим:
- Нюансы Амазона: неочевидные лимиты, разные режимы работы балансировщиков, работа с образами AMI
- Специфика веб-нод: механизмы обновления ПО, Apache/не Apache, безопасность и изоляция пользователей
- MySQL: почему Percona, особенности master-master, репликация большого объема данных, нюансы работы query cache, шардинг
- Бэкапы данных и главное — их восстановление
- Мониторинг тысяч объектов, как не заспамить себя алертами, автоматизируем реакцию на уведомления
Что наиболее интересно для вас? Можно провести спонтанное голосование и отмечать прямо в комментариях. :)
Ну и конечно — пробуйте сам «Битрикс24»! Первый тариф — бесплатный. Если его лимитов или функционала не хватит — можно будет перейти на старшие тарифы. :)
Подключайтесь — и работайте с удовольствием!