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

Серия вебинаров "Разработка надёжных высоконагруженных систем" началась в прошлом 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

At one of the biggest russian tech conferences Highload++-2014 I've been giving two talks (both in Russian):

"Applications under load": on the common things in development of client-side applications and backend services, problems of communication, network and so on:

Second talk, "Anatomy of web-service", was about multitasking, network IO and architecture of web server: how these things affect performance of web application:

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 позволяет избежать этой проблемы.

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

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

Read more…

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

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

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

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

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

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

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

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

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

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

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

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

highload training

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

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

aptly 0.6

aptly 0.6 has been released on June, 7th. 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 -

Most important new features are:

Multi-Component Repository Publishing

aptly is based on concept of list of packages. Snapshots, mirrors and local repositories are list of packages (more precisely, list of references to packages). When merging, pulling, copying or moving packages might move from one list into another. Component is a way to break down packages into groups, usually these groups make sense only in published repository. At the same time mapping from package to component is not universal, there's Debian way to group packages into main, contrib and non-free components, Ubuntu uses different schema of components, some 3rd party repositories use components in place of different distributions (like squeeze, wheezy etc.) or to separate stable and testing versions of software.

In order to keep aptly simple, I decided that there's no mapping from package to component and package lists internally aren't split by component. Each list (snapshot, mirror and local repository) is mono-component (actually there's no component at all). When publishing repository, several lists could be published as separate components.

By default, aptly mirrors all components from remote repository and merges them into one "single component". If we'd like to preserve package split by components, individual mirrors should be created for each component:

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

We can create snapshots from each of the mirrors:

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

And publish all snapshots as single repository preserving component structure (publishing distribution wheezy under prefix upstream):

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

aptly is smart enough to figure out component names and distribution from the mirrors, so I can omit them (commas left to identify number of components):

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

Of course we could do all regular aptly operations: merging snapshots, pulling packages, etc.

Handling Package Conflicts

Package in Debian universe is identified by triple (architecture, name, version). If two packages have the same (architecture, name, version) but different content, they are called conflicting packages. Debian guidelines prohibit including conflicting packages in repositories that could be used together (which could be present in one apt.sources file). Unfortunately, in real word there are conflicting packages, one such package has been reported in squeeze + security updates, another example was puppet repository which contains packages with the same triple but for different Debian distributions in several components.

Before 0.6, aptly would complain when it detects such conflicts and stop processing. In this version special handling has been added that considers packages with same (architecture, name, version) and different files as different package entires. There's one restriction though: you can't put packages with duplicate (architecture, name, version) into one list (one mirror, snapshot, local repo, published repository). This is in line with Debian guidelines that one repository shouldn't contain duplicate packages.

This feature works transparently when upgrading from older versions of aptly: conflicts would be just gone. In the background aptly would be updating references to packages when you update mirrors, create new snapshots, etc.

Empty Repository Publishing

Many people are using aptly to handle package repository from various automation tools, e.g. configuration management systems. For such usage it is convenient to create local repository (empty initially), publish it, and then add packages and update published repository.

Before 0.6, aptly would refuse to publish empty repositories. Now this is possible, but correct architecture list should be supplied when publishing (as aptly can't figure out architecture list automatically from package list). List of architectures can't be changed when published repository is updated, you would have drop published repository and create new one if required.

Merging Snapshots: 3rd Strategy

There's a feature in aptly that allows to merge two snapshots: this is useful to combine for example main repository and security updates or main repository and 3rd-party repository. With 0.6, three merge strategies are available:

  • for packages with same (architecture, name) package which comes from latest snapshot on the command line wins (default);
  • for packages with same (architecture, name) package with latest version wins (-latest);
  • all versions of packages are preserved (-no-remove, new in 0.6).

All Changes

Full list of changes in 0.6:

  • 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;
  • я могу централизовано управлять виртуальными машинами: готовить к следующему заданию и т.п.

Read more…

Contents © 2015 Andrey - Powered by Nikola