Первый вебинар из серии "Разработка надёжных высоконагруженных систем"

Серия вебинаров "Разработка надёжных высоконагруженных систем" началась в прошлом 2014 году первым бесплатным вебинаром, на котором мы рассмотрели состав курса, основные темы, а также сделали небольшое введение в мир высоконагруженных и надежных приложений. До старта основной части из шести вебинаров осталось чуть больше недели, самыми сложными будут первые два вебинара про хранение данных 20-21 января. Мы поговорим о том, как устроены базы данных, как они работают, почему так сложно масштабировать хранение данных, и о том, как осуществить это масштабирование. Мы расшифруем "страшные" аббревиатуры ACID и CAP, поговорим об AP, CP и CA-системах. Еще есть время зарегистрироваться и оплатить свое участие!

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

Вот запись первого бесплатного вебинара "Введение":

Серия вебинаров "Разработка надёжных высоконагруженных систем"

То, о чем многие спрашивали, наконец-то случилось! Мы с Олегом Буниным открыли регистрацию на серию вебинаров "Разработка надёжных высоконагруженных систем". По содержанию вебинары будут на 90% соответстовать мастер-классу, который проходил два раза этим летом. С точки зрения формата вебинар и мастер-класс значительно отличаются:

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

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

Тема надежности находится очень близко к теме высоких нагрузок: это и отказоустойчивость, избыточность, надежность хранения данных, разворачивание системы в нескольких дата-центрах. Моя задача - дать такой набор знаний и приемов, чтобы после серии вебинаров участник мог построить подходящую архитектуру самостоятельно. Это не будет курс о тюнинге MySQL или о настройке отказоустойчивого nginx, но мы будем говорить о том, почему MySQL устроен так, как он устроен, какие из этого вытекают характеристики, и, соответственно, что делать, чтобы заставить его работать быстрее. Мы поговорим о том, почему nginx использует несколько процессов и асинхронный сетевой ввод-вывод, а также о том, как может быть обеспечена отказоустойчивость прокси-сервера без состояния.

Курс ориентирован на разработчиков веб-приложений (серверная часть, предоставляющая API, и клиентская - HTML/JS/Deskop/Mobile). Теоретический рассказ перемешивается с анализом существующих продуктов, примерами архитектур высоконагруженных и отказоустойчивых систем, мы будем вместе решать задачи по проектированию и искать ответы на вопросы.

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

Первый вебинар, "Введение" будет посвящен общим вопросам отказоустойчивости и высоких нагрузок, мы разберем примеры, поговорим о том, как внедрять изменения в команде разработки (или на уровне компании). Участие бесплатно, вебинар пройдет 18-го декабря, необходимо только зарегистрироваться.

Основные шесть вебинаров (данные I+II, приложение, архитектура, клиент и тестирование, эксплуатация) пройдут с 20-го января по 17-е февраля, подробная программа и ссылки на регистрацию опубликованы на сайте вебинара. Сегодня участие в каждом из шести вебинаров стоит 4000 рублей, а все вместе - 16000 рублей (скидка 33%). По мере приближения даты вебинаров цена будет расти, так что торопитесь :)

HighLoad++-2014

На Highload++-2014 в этом году я выступал с двумя докладами.

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

Перед докладом показывали шаржи на докладчиков:

Ну и слайды самого доклада:

Второй доклад ("Анатомия веб-сервиса 2.0") был переработанной версией весеннего доклада с РИТ-2014. Основная идея: то, как устроен backend внутри (многозадачность, сетевой ввод-вывод, обработка входящих и исходящих соединений) влияет на характеристики полученного решения.

Слайды:

aptly 0.7 - S3 publishing, complex queries

aptly 0.7 has been released today. aptly is a Debian repository management tool, it allows to mirror remote repositories, create local package repositories, manage repositories snapshots and publish them back as Debian repository. aptly main idea is "owning your own repository": you can mix and match official repos, 3rd-party repositories, your own packages, creating your own stable/testing/whatever repositories, allowing reproducible package installations along with controlled upgrades. It is available for download as binary executables or from Debian repository:

deb http://repo.aptly.info/ squeeze main

When installing from repository, don't forget to import key used to sign the release:

$ gpg --keyserver keys.gnupg.net --recv-keys 2A194991
$ gpg -a --export 2A194991 | sudo apt-key add -

Aptly has new logo, soon I'm going to launch new website:

aptly logo

Most important new features are:

Publishing to Amazon S3

aptly can publish repositories directly to Amazon S3.

First, create new S3 bucket using AWS console. Let it be aptly-repo. Remember Amazon region you have used to create, I'll be using us-west-1 in this example. If you're going to have public repository, enable website hosting for that bucket.

Go to IAM page, create new user, save access key ID and secret access key and create bash script aws.creds.sh:

# Access Key ID:
# AKIAISHG7G3H8AWBCFG
# Secret Access Key:
# E7aujXChaMZwp3ghfk45+Zabd55

export AWS_ACCESS_KEY_ID="AKIAISHG7G3H8AWBCFG" AWS_SECRET_ACCESS_KEY="E7aujXChaMZwp3ghfk45+Zabd55"

In IAM console, attach new custom policy for that user:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1405592139000",
      "Effect": "Allow",
      "Action": [
        "s3:DeleteObject",
        "s3:GetObject",
        "s3:ListBucket",
        "s3:PutObject",
        "s3:PutObjectAcl"
      ],
      "Resource": [
        "arn:aws:s3:::aptly-repo/*", "arn:aws:s3:::aptly-repo"
      ]
    }
  ]
}

This user would have limited access only to the bucket you've created.

Now, configure aptly, edit configuration file ~/.aptly.conf and add key S3PublishEndpoints:

"S3PublishEndpoints": {
  "aptly-repo": {
    "region": "us-west-1",
    "bucket": "aptly-repo",
    "acl": "public-read"
  }
}

If you're going to have public repository, set acl to public-read, otherwise set acl to private. Now you're ready to do your first publish. For example, to publish snapshot my-snapshot to the mentioned bucket, run:

aptly publish snapshot my-snapshot s3:aptly-repo:

As with publishes to local filesystem, you can publish under prefix:

aptly publish snapshot my-snapshot s3:aptly-repo:debian/

All regular publish commands are supported: you can switch between snapshots (atomically), update published local repositories, drop published repos, etc. aptly would do its best to upload package files only once to package pool in S3.

In order to use published repository, for public repositories use regular HTTP protocol in /etc/apt/sources.list:

deb http://s3-us-west-1.amazonaws.com/aptly-repo wheezy main

For private repositories you would need special apt s3 transport, after installing transport you can use it like that:

deb s3://AWS_ACCESS_ID:[AWS_SECRET_KEY_IN_BRACKETS]@s3-us-west-1.amazonaws.com/aptly-repo wheezy main

Package Queries

Before 0.7, aptly supported only Debian dependency-like package queries. In version 0.7, complex queries were introduced. Query syntax matches reprepro query language, reference could be found in the docs. I'll give some examples.

Now you can filter mirrors to include only packages with limited priorities:

aptly mirror create -filter="Priority (required)" wheezy-required http://mirror.yandex.ru/debian/ wheezy main

Or download single packages and all its dependencies:

aptly mirror create -filter="nginx" -filter-with-deps wheezy-required http://mirror.yandex.ru/debian/ wheezy main

Pull packages with complex conditions:

aptly snapshot pull snapshot1 source snapshot2 '!Name (% *-dev), $Version (>= 3.5)'

Or remove packages based on query:

aptly repo remove local-repo 'Name (% http-*) | $Source (webserver)'

In the next version, package queries would be used to filter snapshots, search for packages in repos/snapshots and local repos, and do whole "world" package searching.

Other Features

aptly can now pull all matching packages with aptly snapshot pull command using flag -all-matches, e.g. one can pull subset of versions from 0.7 to 0.9:

aptly snapshot pull stable1 foo-snapsot stable2 'foo (>= 0.7), foo (<= 0.9)'

Download speed could be limited while mirroring using config option downloadSpeedLimit, so that aptly won't consume all bandwidth.

All Changes

Full ist of changes since 0.7:

Golang Meetup July 2014

Вчера прошел отличный Golang Moscow Meetup в офисе Google. Было очень много участников, что не может не радовать. Интересный crash course Go от Дмитрия Вьюкова, "секретный" проект по автоматической генерации кода от Алексея Палажченко. Всем большое спасибо!

Выкладываю слайды своего доклада:

Exponential Backoff или как "не завалить сервер"

Этот пост был написан по материалам мастер-класса про высокие нагрузки и надежность.

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

Мы сегодня поговорим об интервале повторов запроса. Через какой период времени после неудачного запроса можно его повторить? Давайте рассмотрим две стратегии: повтор через фиксированный интервал времени и экспоненциальное откладывание (exponential backoff). Мы увидим на симуляции, что при условии наличия большого числа клиентов повтор через фиксированный интервал может не дать серверу "подняться", а использование exponential backoff позволяет избежать этой проблемы.

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

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

Читать далее…

Отзывы на мастер-класс

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

Вот некоторые из отзывов:

«Семинар позволил мне упорядочить знания, получить новые сведения и обратить более пристальное внимание на известные мне проекты.»

—Денис Котляров

«Очень нравится способ подачи материала через постоянный диалог с аудиторией - для меня это очень эффективно.»

—Павел Крюков

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

—Евгений Кузовлев

«Всё отлично. Очень много разных тем. При этом все подробно. При этом все что непонятно, быстро и подробно объясняется.»

—Иван Ремизов

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

highload training

Приходите на мастер-класс 4-го, 5-го и 6-го июля, будет еще интереснее, чем в первый раз!

Другие материалы в моем блоге о мастер-классе:

aptly 0.6

Новая версия aptly 0.6 была выпущена 7-го июня. aptly можно скачать в виде исполняемых файлов или подключив Debian-репозиторий:

deb http://repo.aptly.info/ squeeze main

При установке из репозитория в первый раз, не забудьте проимпортировать ключ, которым подписан релиз:

$ gpg --keyserver keys.gnupg.net --recv-keys 2A194991
$ gpg -a --export 2A194991 | sudo apt-key add -

Вот самые важные новые возможности этой версии:

Публикация репозиториев из нескольких компонентов

Одной из основных идей aptly является список пакетов: snapshotы, зеркала и локальные репозитории - это списки пакетов (если быть более точным, списки ссылок на пакетов). Когда происходит операции слияния, перетаскивания, копирования или перемещения пакетов - пакеты перемещаются между списками. Компоненты - это способ разбить список пакетов на группы, обычно эти группы имеют смысл только для опубликованных репозиториев. В то же самое время сопоставление пакета и компонента не является универсальным: Debian группирует пакеты в компоненты main, contrib и non-free, Ubuntu использует другое разделение на компоненты, а сторонние репозитории используют компоненты для разделения пакетов для разных версий Debian (например, squeeze, wheezy и т.п.) или для обозначения стабильных и тестовый версий пакетов.

Чтобы не переусложнять aptly, я решил, что не стоит создавать отображение пакетов на компоненты и не разбивать списки пакетов на компоненты. Каждый список (snapshot, зеркало или локальный репозиторий) состоит из "одного компонента" (на самом деле в нем нет компонентов вообще). Во время публикация репозитория несколько таких списков могут быть опубликованы как отдельные компоненты.

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

aptly mirror create wheezy-main http://ftp.ru.debian.org/debian/ wheezy main
aptly mirror create wheezy-contrib http://ftp.ru.debian.org/debian/ wheezy main
aptly mirror create wheezy-non-free http://ftp.ru.debian.org/debian/ wheezy non-free

aptly mirror list -raw | xargs -n 1 aptly mirror update

Затем мы создадим snapshot для каждого зеркала:

aptly snapshot create wheezy-main-7.5 from mirror wheezy-main
aptly snapshot create wheezy-contrib-7.5 from mirror wheezy-contrib
aptly snapshot create wheezy-non-free-7.5 from mirror wheezy-non-free

И опубликуем все snapshotы в едином репозитории, сохраняя исходную структуру компонентов (мы публикуем distribution wheezy в префикс upstream):

aptly publish snapshot -component=main,contrib,non-free -distrubtion=wheezy wheezy-main-7.5 wheezy-contrib-7.5 wheezy-non-free-7.5  upstream

aptly достаточно умен, чтобы самостоятельно определить имена компонентов и название дистрибутива, так что можно опустить их имена (запятые необходимы, чтобы aptly знал количество компонентов):

aptly publish snapshot -component=,, wheezy-main-7.5 wheezy-contrib-7.5 wheezy-non-free-7.5 upstream

Конечно, мы могли выполнять все обычные операции, которые поддерживает aptly: объединение snapshotов, перетаскивание пакетов и т.п.

Обработка конфликтов пакетов

Пакет во вселенной пакетов Debian идентифицируется тройкой (architecture, name, version). Если у двух пакетов одинаковые (architecture, name, version), но разное содержимое, такую ситуацию называют конфликтом пакетов. Руководство Debian запрещение включение конфликтующих пакетов в репозитории, которые могут использоваться совместно на одной машине (такие репозитории, которые могут быть включены в один файл apt.sources). К сожалению, в действительности такие конфликты встречаются не так уж редко: один такой пакет существует в репозиториях squeeze + security updates, другая такая же ситуация в репозитории puppet, где собраны одни и те же версии пакетов для разных дистрибутивов Debian в одном репозитории и разных компонентах.

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

Это изменение незаметно для пользователей, обновившихся до версии 0.6: aptly в фоновом режиме по мере обновления зеркал или создания новых snapshot обновляет способ хранения ссылок на пакеты.

Публикация пустых репозиториев

Многие люди используют aptly для автоматизации каких-то процессов, в том числе и с использованием систем управления конфигурацией. Для таких сценариев использования удобно создать локальный репозиторий (пустой), сразу его опубликовать, чтобы создать точку для apt.sources, а потом добавлять пакеты и обновлять опубликованный репозиторий.

До версии 0.6 aptly не позволял публиковать пустые репозитории, теперь это ограничение снято. При публикации пустого репозитория необходимо сразу корректно задать список архитектур (обычно aptly автоматически определяет список архитектур по списку пакетов, в случае пустого списка это невозможно). После публикации изменить список архитектур уже неовзможно, для его изменения потребуется удалить опубликованный репозиторий и опубликовать заново.

Объединение snapshotов: новая стратегия

aptly поддерживает слияние snapshotов - это может быть полезно для объединения основного репозитория с обновлениями безопасности или со сторонним репозиторием. В версии 0.6 доступно три стратегии объединения:

  • из пакетов с одинаковой парой (architecture, name) остается тот, который принадлежит snapshotу, который расположен "правее" в командной строке (по умолчанию);
  • из пакетов с одинаковой парой (architecture, name) остается тот, версия которого больше (-latest);
  • все версии пакетов сохраняются (-no-remove, новое в 0.6).

Полный список изменений

Вот полный список изменений в версии 0.5:

  • support for multi-component published repositories (#36)
  • handling duplicate packages with different content gracefully (#60)
  • repositories published by aptly now can be consumed by debian-installer (#61)
  • new flag: -no-remove for aptly snapshot merge to merge snapshots with all package versions preserved (#57)
  • publishing of empty snapshots/repositories is possible (#55)
  • aptly repo add now exists with 1 if any of files failed to add (#53)
  • bug fix: Package: line comes first in package metadata (#49)
  • bug fix: when command parsing fails, aptly returns exit code 2 (#52)
  • bug fix: pulling more than 128 packates at once (#53)
  • bug fix: aptly graph may get confused with package pull requests (#58)

Практические задания на мастер-классе

Первый мастер-класс о высоких нагрузках и надежности прошел успешно, оказалось, что 900 слайдов на три дня даже слишком много :) В следующий раз теоретическая часть будет немного покороче, а практики будет побольше. На мастер-классе было 7 практических заданий, каждое из которых работало корректно у всех 25 участников на протяжении всех трех дней. Я не ожидал, что не будет ни одной проблем.

Когда я начинал подготовку к мастер-классу, я понимал, что:

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

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

  • одинаковое окружение у всех участников (как по составу, так и по производительности);
  • участникам требуется только ssh;
  • я могу централизовано управлять виртуальными машинами: готовить к следующему заданию и т.п.

Читать далее…

Contents © 2015 Andrey - Powered by Nikola