2. Структура лекции
Первый блок:
•
•
•
•
•
•
Знакомство;
Цель обучения;
Принципы масштабируемости;
Архитектурные решения;
Виды масштабирования;
Трёхзвенная структура.
Второй блок:
• Архитектурные паттерны;
• Алгоритм проектирования высоконагруженных систем.
Третий блок:
• Примеры: профили на сайте знакомств, новостной сайт, френдлента;
Если успеем:
• Ошибки в разработке высоконагруженных систем;
• Хаки;
• Эксплуатация.
2
4. Олег Бунин
• Председатель Программного комитета конференции
разработчиков высоконагруженных систем HighLoad++ вот уже
семь лет;
4
5. Олег Бунин
• Председатель Программного комитета конференции
разработчиков высоконагруженных систем HighLoad++ вот уже
семь лет;
• Руководитель компании по разработке и консалтингу в области
высоконагруженных проектов;
5
6. Олег Бунин
• Председатель Программного комитета конференции
разработчиков высоконагруженных систем HighLoad++ вот уже
семь лет;
• Руководитель компании по разработке и консалтингу в области
высоконагруженных проектов;
• Руководитель отдела веб-разработки компании Рамблер (ещё
тогда, когда Рамблер был номером один);
6
8. Кто вы?
• У кого пользователей больше 10 тысяч в сутки?
8
9. Кто вы?
• У кого пользователей больше 10 тысяч в сутки?
100 тысяч в сутки?
9
10. Кто вы?
• У кого пользователей больше 10 тысяч в сутки?
100 тысяч в сутки?
500 тысяч в сутки?
10
11. Кто вы?
• У кого пользователей больше 10 тысяч в сутки?
100 тысяч в сутки?
500 тысяч в сутки?
миллион в сутки?
11
12. Кто вы?
• У кого пользователей больше 10 тысяч в сутки?
100 тысяч в сутки?
500 тысяч в сутки?
миллион в сутки?
10 миллионов в сутки?
12
13. Кто вы?
• У кого есть в управлении сайты, расположенные на
выделенном сервере?
13
14. Кто вы?
• У кого есть в управлении сайты, расположенные на
выделенном сервере?
более, чем на двух выделенных серверах?
14
15. Кто вы?
• У кого есть в управлении сайты, расположенные на
выделенном сервере?
более, чем на двух выделенных серверах?
более, чем на пяти выделенных серверах?
15
16. Кто вы?
• У кого есть в управлении сайты, расположенные на
выделенном сервере?
более, чем на двух выделенных серверах?
более, чем на пяти выделенных серверах?
более, чем на двадцати выделенных серверах?
16
18. Цель нашей встречи
• Состоит в том, чтобы вы глубоко начали понимать смысл
происходящего в вашим программным кодом;
• Знание нескольких принципов заменяет знание множества
фактов;
18
20. В чём суть репликации?
Запись
Мастер
Слейв
Репликация
Слейв
Слейв
Чтение
20
21. Репликация
• В чём суть репликации?
• Что происходит на серверах физически?
21
22. Репликация
• В чём суть репликации?
• Что происходит на серверах физически?
• Решает ли репликация любую проблему и всегда ли она полезна?
22
23. Репликация
• В чём суть репликации?
• Что происходит на серверах физически?
• Решает ли репликация любую проблему и всегда ли она полезна?
23
24. Репликация
• В чём суть репликации?
• Что происходит на серверах физически?
• Решает ли репликация любую проблему и всегда ли она полезна?
• Записей больше, чем чтения;
24
25. Репликация
• В чём суть репликации?
• Что происходит на серверах физически?
• Решает ли репликация любую проблему и всегда ли она полезна?
• Записей больше, чем чтения;
• Отсутствие консистентности данных;
25
26. Репликация
• В чём суть репликации?
• Что происходит на серверах физически?
• Решает ли репликация любую проблему и всегда ли она полезна?
• Записей больше, чем чтения;
• Отсутствие консистентности данных;
• Слишком много слейвов;
26
27. Репликация
• В чём суть репликации?
• Что происходит на серверах физически?
• Решает ли репликация любую проблему и всегда ли она полезна?
•
•
•
•
Записей больше, чем чтения;
Отсутствие консистентности данных;
Слишком много слейвов;
Слишком много данных;
27
29. Кеширование
• Поход в кеш занимает 20 миллисекунд;
• Поход к базе данных занимает 100 миллисекунд;
29
30. Кеширование
• Поход в кеш занимает 20 миллисекунд;
• Поход к базе данных занимает 100 миллисекунд;
• Попадание в кеш = 20 миллисекунд, промах = 120 миллисекунд;
30
31. Кеширование
• Поход в кеш занимает 20 миллисекунд;
• Поход к базе данных занимает 100 миллисекунд;
• Попадание в кеш = 20 миллисекунд, промах = 120 миллисекунд;
• Если количество промахов составляет:
•
•
•
•
10% -> кеш ускоряет выполнение приложения в 3.3 раза;
40% -> кеш ускоряет выполнение приложения в 1.7 раз;
80% -> кеш не приносит пользы;
90% -> кеш замедляет выполнение приложения.
31
32. Кеширование
• Поход в кеш занимает 20 миллисекунд;
• Поход к базе данных занимает 100 миллисекунд;
• Попадание в кеш = 20 миллисекунд, промах = 120 миллисекунд;
• Если количество промахов составляет:
•
•
•
•
10% -> кеш ускоряет выполнение приложения в 3.3 раза;
40% -> кеш ускоряет выполнение приложения в 1.7 раз;
80% -> кеш не приносит пользы;
90% -> кеш замедляет выполнение приложения.
• Вы знаете своё соотношение hit/miss?
32
34. Индексы полезны?
• Индекс – это возможность по значению столбца или группы
столбцов быстро найти весь кортеж, всю строку в базе данных;
34
35. Индексы полезны?
• Индекс – это возможность по значению столбца или группы
столбцов быстро найти весь кортеж, всю строку в базе данных;
• Каждый индекс:
• замедляет выполнение операции вставки строки;
• увеличивает количество требуемой оперативной памяти;
• усложняет работу планировщика запросов.
35
36. Индексы полезны?
• Нужно учитывать селективность индекса;
• Индексы с низкой селективностью, не просто бесполезны, они
вредны;
36
38. Основная логика масштабируемости
• Рано или поздно в процессе оптимизации мы упираемся в
производительность аппаратного обеспечения;
• Значит надо сделать так, чтобы задачу можно было выполнять
одновременно на нескольких машинах;
• Это легко сделать в парадигме запрос-ответ, в которой работает
веб;
Как нужно учитывать будущее масштабирование?
38
42. Сервис-ориентированная архитектура
Каждый сервис решает строго определенную задачу.
Основной минус этого подхода заключается в наличии
оверхеда на интеркоммуникацию сервисов между собой и на
обработку API взаимодействия между слоями.
44. Монолитное приложение
Приложение представляет из себя монолитный программный код.
Плюсы:
• Отсутствие какого-либо оверхеда на интеркоммуникацию сервисов;
Минусы:
• Высокая сложность разработки;
• В случае проблемы встает все;
• Невозможность вести распределенную разработку.
47. Ремесленный подход
• Быстрая разработка любых новых решений;
• Высокие требования к квалификации разработчиков – низкая
масштабируемость разработки;
• Максимально эффективное использование технологий и
аппаратного обеспечения;
50. Промышленный подход
• Очень долгая разработка общих инструментов;
• Очень быстрая разработка приложений – происходит сборка
страниц как в конструкторе Lego;
• Возможность использовать для разработки приложений
программистов средней и низкой квалификации – высокая
масштабируемость разработки;
• Повышенные требования к аппаратному обеспечению;
57. Масштабирование “во времени”
Различные данные имеют различные требования к
обновлению. Это позволяет нам отложить часть обработки
данных до более удобного случая.
72. Очереди
Структура данных с дисциплиной доступа к элементам FIFO (First In
First Out).
Применения:
1. Отложенная обработка (рассылки, обновления лент новостей);
2. Межсервисная коммуникация;
73. Очереди: модерация
Резервный датацентр
Erang-фронтенд
Erlang-фронтенд
Erlang-фроненд
Фронтенд для
модератора
Удаление
сообщений
SQL
Заявки на удаление
сообщений
БД
БД
БД
Входящий
Rabbit MQ
SQL
Очередь на удаление
отмодерированных
комментариев
Копии всех обновлений
SQL
Исходящий
Rabbit MQ
Этот сервер очередей должен стоять
на стороне кластера фронтендов для
того, чтобы в случае пропадания
связи с резервным ДЦ информация
никуда не потерялась.
Приложение,
обновляющее SQL
и считающая кучу
статистики
74. Интеркоммуникация сервисов
Задача: необходимо уведомлять одни части системы о событиях,
которые происходят в других частях:
• размещение информации в пользовательских лентах (feeds) о
событиях, произошедних в сообществах;
• лайки;
• комментарии;
• рассылка писем;
75. Интеркоммуникация:
решение с очередью
Пользователи
Пользователи
Всегда быть готовым
к дублированию
задач в очереди
Постинг поста
Сервис постов
Синхронная
постановка в
очередь
Очередь
Репликация или Heart beat
Синхронная запись в
базу данных
Репликация
очереди
Постоянная
база данных
Если очередь
сломалась –
переставляем
задачи по
постоянной
базе
сообщений
Разборщик
очереди
76. Интеркоммуникация: решение с очередью
Это могут быть те же
сервера, что и
обрабатывают запросы от
фронтендами
Входящие Httpсервера сервиса Б
Сервис A
Внутренняя
очередь
сервиса А
Раздающий демон
сервиса А
Внутренняя
очередь
сервиса Б
Сервис Б
Сервис Б
Входящие Httpсервера сервиса Б
Сервис A
Обработка задач
сервиса А
Входящие Httpсервера сервиса Б
Забираем задачи
Push сообщений из
сервиса А во все
остальные сервисы
Сервис Б
Прием задач для
сервиса Б
Обработка задач
сервиса Б
78. Антишквал
Фронтенд
Первый запрос
Первый бекенд не ответил,
переходим ко второму
Сервис
Сервис
Ряд серверов-бекендов, выполняющих
однотипные задачи.
Запрос приходит на первый бекенд,
начинает выполняться, но не успевает за
время таймаута.
Фронтенд или толстый клиент
перебрасывает запрос на новый бекенд,
тот тоже не успевает.
Таким образом очень быстро вся сеть
бекендов будет положена.
79. Антишквал: умные запросы
Умные запросы от фронтенда:
Фронтенд
Фронтенд
Фронтенд
Третий запрос,
Timeout = 3с
Первый запрос,
Timeout = 1с
Сервис
Второй запрос,
Timeout = 2с
Сервис
Фронтенд
Четвертого запроса
просто нет.
• Первый запрос к первому бекенду идет с
таймаутом 1 секунду. Второй запрос идет с
таймаутом 2 секунды, третий - 3 секунды,
а четвертого уже нет. То есть ограничиваем
количество запросов;
• Бекенд может принимать решение о том,
что он перегружен (раз в секунду
спрашивать LA и кэшировать его). При
начале обработке запроса происходит
проверка и если LA слишком высокий отдаем фронту Gone Away (штатная
ситуация - перейди к другому бекенду).
Сервис
Сервис
82. Кеширование на бекенде;
Кеш
•
•
•
•
Единый кеш для всех бекендов;
Проблема инвалидации кеша;
Проблема старта с непрогретым кешем;
Целесообразность применения кеша;
Бекенд
Бекенд
Бекенд
86. Шардинг
Базовый принцип: те данные, которые в дальнейшем потребуются вместе, так же
должны храниться вместе.
Примеры:
1. Пользователи;
2. Посты в сообществах;
3. Блоги;
Принципы разбиения данных на шарды:
1. Центральный диспетчер, знающий, что где лежит;
2. Хэш-функция, по ключу вычисляющая шард;
3. Хэш-функция, по ключу вычисляющая виртуальный шард + таблица соответствий
виртуальных шардов реальным.
91. Репликация
Базы данных MongoDB
Push-сервер
Лог обновлений
MongoDB
Обновления слушаются с
одной из реплик
Реплики
MongoDB
AJAX-Соообщение об
обновлении
Репликация
Бекенд
Читаем с реплики
Бекенд
Чтение блога
Бекенд
Репликация
Реплики
MongoDB
Репликация
Публикация поста
Бекенд
Запись поста в блог
Мастер
MongoDB
Реплики
MongoDB
94. Функциональное разделение базы данных
Разные данные хранятся в разных таблицах
или
Разные данные хранятся в разных СУБД
или
Разные данные хранятся в разных типах СУБД
96. Денормализация данных
Денормализация — намеренное приведение структуры базы
данных в состояние, не соответствующее
критериям нормализации, обычно проводимое с целью
ускорения операций чтения из базы за счет добавления
избыточных данных.
101. Алгоритм, ШАГ ВТОРОЙ
Посчитаем объёмы хранимых данных и скорость их приращения. Выбираем
критический путь – хранение, запись или чтение данных?
101
109. Сайт знакомств, профили / #1
1. Пользователь заполняет анкету;
2. Получает логин пароль для доступа к своему личному кабинету;
3. Пользователи могут смотреть профили друг друга;
109
110. Сайт знакомств, профили / #2
1. Пользователей 200 миллионов;
2. Каждая анкета занимает 10 килобайт, то есть всего 2 000
гигабайт;
3. Хитов в день 5 миллиардов;
110
112. Сайт знакомств, профили / #4
1.
2.
3.
4.
Данные часто читаются, но редко меняются;
Все анкеты примерно одного размера;
У анкеты есть уникальный идентификатор;
Нет ярко выраженных лидеров;
112
119. Сайт знакомств, профили / результат
• Разбиваем весь массив пользователей на виртуальные шарды;
• Маппим виртуальные шарды на реальные шарды;
• Внутри каждого шарда реплицируем информацию для
отказоустойчивости
119
121. Задания на стажировку
• В двух абзацах и одной схеме описать различия в СУБД MySQL и
PostgreSQL;
• Предположить, какие особенности в оптимизации и архитектуре
накладывают из-за этого различия возникают;
• Результаты прислать на oleg.bunin@ontico.ru
121
124. Новости / #2
• Каждая новость примерно 10 килобайт;
• Мы вечно храним архив с даты основания СМИ – 2000 год;
• В день публикуется около 10 тысяч различных региональных и
федеральных новостей;
• Итого в год 3 миллиона 500 тысяч новостей, в год 35 гигабайт, за
20 лет – 700 гигабайт;
• Это крупнейшее СМИ, посещаемость – 10 миллионов человек в
сутки;
124
126. Новости / #4
• Количество чтений на несколько порядков превышает количество
записей;
• 99% запросов касаются последнего дня;
• 99,99% запросов касаются последней недели.
126
133. Новости / результат
• Кеширование для горячих новостей;
• Партиционирование новостей по дате – последние новости в
быстрой таблице;
• Избыточное хранение новостей – новость пишется сразу и в
горячую таблицу и в архивную, горячая раз в какое-то время
чистится;
133
135. Просмотр френдленты / #1
• У пользователя может быть сколько угодно друзей;
• Френдленту храним бесконечно долго;
135
136. Просмотр френдленты / #2
• В среднем у пользователя 100 друзей;
• Каждый пользователь в среднем пишет 3 поста в день;
• Каждый пост занимаем около 1 килобайта;
• Пользователей – 10 миллионов в сутки, но каждый пользователь
делает 100 хитов. Итого – миллиард запросов к френдленте в
сутки;
• В сутки генерируется 30 миллионов постов, 10 миллиардов
записей в год;
136
137. Просмотр френдленты / #3
• Допустимо, что пользователь увидит запись своего друга не
моментально, а с небольшой задержкой;
• Допустимо, что порядок записей не будет строго совпадать с
хронологическим;
137
138. Просмотр френдленты / #4
• 99% запросов приходятся на голову френдленты;
• У нас есть пользователи, которые в друзьях у миллионов
пользователей;
138
140. Просмотр френдленты / #5
Избыточность?
Каждому пользователю свой список записей в его френдленте? Это
же очень много – один триллион записей за год!
140
141. Просмотр френдленты / #5
Храним для каждого пользователя
ленту идентификаторов постов!
141
143. Просмотр френдленты / #5
Пользователь и его посты
лежат рядом
Сделайте составной идентификатор поста, пусть в него входит
идентификатор пользователя
143
144. Просмотр френдленты / #5
Достали список
идентификаторов постов
Как собрать ленту?
144
146. Просмотр френдленты / #5
Если вы круты, то можете попробовать
Параллельные вычисления
146
147. Просмотр френдленты / результаты
• Пользователи шардируются, рядом с пользователями лежат его
посты и его френдлента;
• В френдленте пользователя уже записаны идентификаторы
постов его друзей в порядке, близком к хронологическому;
• В идентификатор поста зашит ID пользователя, по которому мы
быстро определяем шард и забираем с него текст поста;
• За текстом поста у нас будет ходить JS-машина, работающая на
клиенте.
147
148. Запись френдленты / #5
А как посты попадают в
френдленту?
У нас ведь есть пользователи, которые в друзьях у миллионов?
148
155. Мониторинг
Вы должны с абсолютной точностью знать, что происходит в
системе.
• Мониторинг серверов;
• Мониторинг приложений;
• Мониторинг элементов приложений;
• Мониторинг показателей базы данных;
161. Буферизация в операционной системе
База данных
apache
nginx
Операционная система,
Сетевая подсистема
Электрический сигнал
Память
PHP
Операционная система,
дисковая подсистема
Диск
Сетевая карта
161
165. Задания на стажировку
• В двух абзацах и одной схеме описать различия в СУБД MySQL и
PostgreSQL;
• Предположить, какие особенности в оптимизации и архитектуре
накладывают из-за этого различия возникают;
• Результаты прислать на oleg.bunin@ontico.ru
165
168. Event-driven чат
Быстрый сервер
Node.JS или
phpDaemon
AJAX Long polling
Поток репликации
Основная база
MySQL
POST-запрос с сообщением
Быстрая база
MongoDB
Клиенты
Пишем постоянную версию
Основной сервер (PHPбекенд)
169. Лента новостей
Пользователь А
публикует запись
Сохраняем запись в
статичном постоянном
хранилище
Запись не
сохранилась
Нет
Этот процесс тоже можно
оптимизировать, группировать.
Сначала можно запросить
подробности по двум записям,
потом по четырем, потом по всем
оставшимся.
Постоянное
хранилище
Удачно?
Хранилище лент,
каждая лента =
список
идентификаторов
записей
Да
Удаляем (или не
коммитим) запись в
статичное хранилище.
Нет
Запрашиваем список
идентификаторов
записей из ленты B
Обрабатываем
идентификаторы и для
каждого из них
запрашиваем данные из
постоянного хранилища
Например,
RabbitMQ
Ставим в очередь З
задачу обновить ленты
подписчиков
пользователя А
Удачны обе
операции?
Пользователь B,
подписанный на
пользователя А, читает
свою ленту
Сервер
очередей
Да
Публикация произошла
успешно
Страница
построена
Пул процессов,
обслуживающих
очередь
Обновляем
соответствующие
списки
идентификаторов
170. Отдача
фотографии напрямую
с хоста
Database / 1
Backend / 1
По scp заливаем фотку (все варианты)
на один из серверов
MySQL
PHP + Limb
Backend / 2
Image Server / 1
nginx
Image Server / 2
nginx
User images
User images
PHP + Limb
Image Server / 3
nginx
После того, как nginx
полностью принял
фотографию, он
отправляет ее в
php-бекенд
User images
Frontend / 1
nginx
Backend / 3
Пишем в базу
данных метаинформацию
о фотографии
PHP + Limb
Демоны
Frontend / 2
nginx
memcached
Design images
Design images
Закачивание
фотографии
DNS-Балансинг
DNS-Балансинг
Пользователи
memcached
Хранение
бинарных
данных