1.15k likes | 1.42k Views
Основы построения масштабируемых высоконагруженных веб-проектов Семинар (8 часов). Алексей Рыбак Badoo Development (badoo.com). Задачка на разминку.
E N D
Основы построения масштабируемых высоконагруженныхвеб-проектов Семинар (8 часов) Алексей Рыбак Badoo Development (badoo.com)
Задачка на разминку Пусть в нашем распоряжении имеется некоторый веб-сервер. Выполняя запросы, часть времени он проводит в ожидании ответов от удаленного сервера базы данных, остальное время занимает работа процессора. Считая, что ресурсы базы данных и пропускная способность сети – неограниченны: при каких условиях сервер может отдавать 1000 запросов в секунду?
Наш план • Введение • Базовые компоненты и архитектуры • Управление и поддержка больших проектов • Избранное по заявкам, обсуждение проблем, любые ваши вопросы
Кто зачем пришёл (1/2) • Не очень хорошо знаком с архитектурой и принципами масштабирования много-серверных систем, хочу узнать основы • В нашем проекте уже несколько серверов, хочу узнать, как расти дальше • Мне всё более-менее понятно, хочу систематизировать знания и получить консультации по ряду вопросов
Кто зачем пришел (2/2) • программист • администратор • руководитель группы/отдела • всё вышеперечисленное • ничего из выше перечисленного
Ещё пару вводных слов • Стек технологий – LNMP • Многиепроблемы носят фундаментальный характер • Постараемся «перезагрузить» мозг • Будет много живого общения • Не стесняйтесь прерывать и задавать вопросы • Будет много флипчарт-сессий
Почему “перезагрузить” мозг? Какпрограммирует «продвинутый новичок»? • Осознаёт предметную область (бизнес-анализ, пользовательские сценарии) • Создаёт «модель» и «над-язык» (данные, сущности, операции над ними) • Пишет код, внося изменения в над-язык (реже – пересматривая модель) • В п.2 мы кое-что забыли • Модель не имеет системного каркаса • Нужна верификация модели с системной точки зрения – системное проектирование
Проектирование (1/2) • Многоуровневый анализ • Логический уровень: модель данных • Software-уровень: ОС, ФС, веб-сервера, базы данных и другие базовые компоненты • Hardware-уровень: диски, память, сеть, CPU … • У всех компонент – и программных, и железных - есть свои важные особенности, которые играют колоссальную роль
Проектирование (2/2) • Любой архитектор обязан иметь навыки системного администрирования • Правильное «объединение» всех компонент • О масштабировании нужно заботиться заранее • Всё это - не преждевременная оптимизация
Сети массового обслуживания • Массовый поток требований случайного характера • Телефонные станции, супермаркеты, автомагистрали, call-центры, ремонтные предприятия…и конечно интернет-проекты! • Первая работа - А.К.Эрланг, «The Theory of Probabilities and Telephone conversations», 1909 • Не пугайтесь, не будем углубляться в математику, главное – «чувствовать» модели
Базовая модель канал обслуживания очередь обслуженные заявки требования переполнение: отказы • Характеристики: • число требований в ед.t • пропускная способность (число обслуженных требований) • среднее время обслуживания, распределение (моменты) • число отказов в ед. t Важное свойство: нелинейная (стремительная) «деградация»
N-канальная СМО с ожиданием каналы (N) очередь обслуженные заявки требования Ищите подобные модели в своих проектах. Это - архитектура вашего бизнеса. Остальное – в-общем, вторично.
Цели изучения СМО Повышениеэффективности: • Пропускная способность • Время ожидания • Совокупная стоимость
Попробуем рассчитать на «пальцах» проект • Суточная аудитория - 10 млн человек • Оператор – процесс веб-сервера • Требование – запрос от браузера • Расчёт крайне грубый • Время на один запрос – 0.1 сек • 75% загрузка: 24 час X 45 мин X 60 сек = 64800 сек • Всего запросов на оператора 64800*10 = 0.648 млн • Каждый пользователь делает 30 кликов • Всего запросов 30*10млн = 300 млн • На один сервер – 10 процессов • Число серверов 300 / (10*0.648) = 46.2
Этот расчёт – неверный • Не учитываем «случайность» распределения • Не учитываем структуру запросов (1 хит != 1 запрос) • Не учитываем суточное распределение • Для UGC 10 млн на практике – это сотни, а то и тысячи серверов • В жизни системы куда сложнее, поэтому иной раз проще не считать, а сразу проводить измерения
Базовые софтверные компоненты проекта • Веб-сервер • Сервер приложений (может быть интегрирован в веб-сервер) • СУБД • Кеш-сервер • Цель: «прокачать» как можно больше хитов за как можно меньшие деньги
Масштабирование линейное заработали нелинейное эффективность линейное, но с плохой производительностью потратили Говорят, что scaling и performance – разные вещи. Это не совсем так. Это всё про деньги. Scaling – класс кривой, Performance – её характер (например, угол наклона)
1. Базовые компоненты и архитектуры
Скорость доступа к данным типичные цифры Memory #00 #01 < 1e-6 s cache cache <1e-9 s CPU FS cache “HARD” DISK Network >1e-4 s >1e-5 s
Диск – слабое звено • Если что-то лежит на диске, не меняется и часто читается – оно мгновенно в FS cache и доступ к нему такой же быстрый как к памяти • Считать по сети из памяти удаленной машины чаще быстрее, чем с локального диска • Читать/писать последовательно и много –значительно выгоднее • Пакетная запись на диск: накопили в памяти и сбросили. Можно вовсе асинхронно (возможны потери). • Будущее – за SSD
Linux: параллелизм • Процессы (processes) • Трэды (threads) • Для осуществления «параллельной» работы необходимы переключения между режимами ядра и задачи - переключение контекста (context switch) • Ключевой момент для большинства классов серверов – модель обработки сетевых соединений
Модели обработки сетевых соединений • Process per connection • CGI: fork per connection • Pooling: Apache (v.1, mpm_prefork – min, max, spare), PostgreSQL+pgpool, PHP-FPM … • Thread per connection • Pooling: Apache (mpm_worker – min, max, spare), MySQL(thread_cache) • FSM (finite state machine) • «современные» ядра:kqueue, epoll • общий интерфейс libevent, libev • FSM + process pooling: nginx • FSM + thread pooling: memcached v>1.4
Обработка сетевых соединений веб-сервером • process-per-connection(apache 1, 2 mpm_prefork) • медленные клиенты = куча процессов • thread-per-connection(apache 2 mpm_worker) • медленные клиенты = куча потоков • Keep-Alive – 90% неактивных клиентов • накладные расходы – context switches, RAM • “lightweight“ (nginx, lighttpd, …) • nginx (не нгинкс, не нжинекс и даже не нгинекс, а эн-жин-ыкс (engine-x)!)
flipchart case #1 • Отдача статики веб-сервером
Почему nginx? • 1 master + N workers (10**3 – 10**4 conn) • N:CPU, вероятность блокирующих операций • FSM + поддержка эффективных методов работы с соединениями • большое внимание к скорости и качеству кода • минимум копирования данных • Keep-Alive: 100Kbytes active / 250 bytes inactive • очень удобная конфигурация • даже есть встроенный кастрированный perl • sysoev.ru, apache-talk@lexa.ru
Типичная конфигурациявеб-сервера • Что делает сервер? • Выполняет код • Обслуживает клиента • Разве повар принимает заказ? • Разные задачи, разделить • Двухуровневая схема (frontend/backend) • nginx + Apache + mod_php, mod_perl, mod_python • nginx + FCGI (например, php-fpm)
[front/back]end: концепт «тяжеловесный» сервер (HWS) «легковесный» сервер (LWS) Apache mod_php, mod_perl, mod_python FastCGI nginx «быстрые» и «медленные» клиенты «статика», SSI, perl «динамикa»
[front/back]end:масштабирование • F и В – «логический» • уровень • F и B гомогенны • (обслуживание, замена) • F и B могут быть • разными «физическими» • серверами или • одним сервером • (единый однородный • «слой» серверов, • на каждом LWS и HWS) N/Nb B F N/Nf B SLB F B F B
Масштабирование линейное заработали эффективность потратили
Масштабирование веб-кластера • Гомогенность: при большом числе серверов можно не разделять front-и back-endы • Независимость компонент • Минимум общих ресурсов (share-nothing => share accurately) • Некоторые распространённые ловушки: • общие данные на nfs (сессии, код) => локальные копии кода, сессии в memcached • локальный кеш => общий кеш • что-то пишем в базу realtime => сделать тяжелые операции асинхронными
nginx: load balancing upstream backend { server backend1.example.comweight=5; server backend2.example.com:8080; server unix:/tmp/backend3; } server { location / { proxy_pass http://backend; } }
nginx: fastcgi upstream backend { server www1.lan:8080weight=2; server www2.lan:8080; } server { location / { fastcgi_index index.phtml; fastcgi_param [param] [value] ... fastcgi_pass backend; } }
Отдача защищенной статики • через скрипт – плохо («тяжелый» процесс на каждого клиента) • X-Accel-Redirect («тяжелый» процесс быстро проверяет, можно ли отдавать, и даёт «указание» веб-серверу) • модули (URL-сертификаты) • http://sysoev.ru/nginx/docs/http/ngx_http_secure_link_module.html • http://wiki.nginx.org/NginxHttpAccessKeyModule
Кеширование • «память»-10-9-10-6,«сеть»-10-4,«диск»-10-3 и выше • страницы(+картинки и т.д.), HTML-блоки, «объекты» • эффективность: соотношения hit/miss/set, «кеш-память на одного юзера» • HTML-блоки: не всегда эффективно • А был ли мальчик? (if-modified-since) • Кеширование веб-сервером (прокси-кэш) • Объектный кеш: сериализованные данные • «Некогерентный»(несогласованный) кеш
Несогласованность локального кеша + LC data frontend backend + data LC backend Global Cache Global Cache Global Cache
memcached • danga.com/memcached/ (LiveJournal) • «глобальный» кеш-сервер • оптимизированная работа с памятью (slab alloc, object versions)и сетевыми соединениями (libevent) • Крупнейшие мировые проекты: LJ, slashdot, digg, facebook (десятки терабайт) • идеален для сессий, объектного кеша • multi-get, stats (get, set, hit, miss + slab info) • легко масштабировать • i = crc32(key)%N и вариации • время жизни, LRU и пролонгация • неидеально написан, особенно после facebook
Кластеризация сессий • http-conn: кидаем клиента на один сервер в рамках сессии (производительность, неравномерная нагрузка) • NFS: никакая масштабируемость, SPOF, “nfs stale handle”, скорость • Database:SPOF, скорость (лучше: heap, cluster) • Memory: высокая скорость, почти линейная маcштабируемость. Memcached, Zend Session clustering
flipchart session • Есть ли вопросы? • Case#2: база знаний (википедия) • Case#3: медиа-хранилище (фото-видео-хостинг, файлопомойка)
Компоненты (cont.) Что ещё входит в базовые компоненты: • Application servers: обычно интергированы в веб-сервер (исключение - FCGI). Пару слов про PHP-FPM и особенности PHP • СУБД (MySQL)
Приложения • Приложения на скриптовых языках • «Собирают» динамические страницы • Много блокирующего IO • Часто создают существенную нагрузку на CPU • В качестве примера рассмотрим PHP
Особенности PHP • Acceleration (APC, xcache, ZPS, eAccelerator) • memory & CPU usage (zval: C(1M), Perl(10M), PHP(20M)) • modules rock! • FCGI (fpm)
FPM • PHP-FPM: PHP FastCGI process manager • Менеджер FastCGI-процессов для PHP • Архитектура сервера напоминает nginx (master + N workers)
PHP-FPM: эксплуатация • Плавно обновляться, не теряя соединения • Видеть все ошибки • Автоматически реагировать на подозрительное поведение воркеров (выход, тормоза, массовые падения) • New: динамическое количество воркеров (apache-like)
PHP-PFM: основные возможности • Плавный перезапуск/обновление кода • Мастер ловит stderr воркеров • Автоматический трейсинг и завершение работы медленных воркеров • Аварийный перезапуск при массовом падении воркеров
PHP-PFM: доп. возможности • Error header снимает проклятие пустой белой страницы (200 OK на ошибку) • fastcgi_finish_request() – отдать output клиенту, но продолжить работу (сессии, статистика и т.д.) • Accelerated upload (поддержка request_body_file - nginx 0.5.9+)
FPM на путик PHP • Mamba, Badoo (2004-2006): набор разрозненных патчей • Андрей Нигматулин. 2007: один патч поверх PHP(5.3.0-0.5.12, http://php-fpm.org) • 2009: проект отнимает массу времени, «берёт руководство» Michael Shadle, коммитит dreamcat4http://launchpad.net/php-fpm • Конец 2009 … Антон Довгаль, Jerome Loyet - FPM наконец в PHP! Отдельный SAPI, 5.3.*. • Groups: highload-php-(en|ru)@googlegroups.com
Базы данных • Самый «капризный» компонент • Пофантазируем о том, как бы мы разрабатывали СУБД • Поймем «модель» обслуживания • Поговорим о масштабировании
в первом приближении: установить соединение, выделить ресурсы скорость, память на стороне сервера… получить запрос проверить кэш запросов разобрать SQL-выражение bind vars, stored proc… получить данные index lookup, buffer cache, disk read отсортировать данные in-memory, filesort, key buffer отдать результат очистить ресурсы, закрыть соединение Вы - БД и выполняете SELECT
MySQL: кратко о самом важном • Движки - MyISAM, InnoDB, Memory(Heap); Pluggable • Блокировка: MyISAM на уровне таблиц, InnoDB на уровне строк • «Ручные»блокировки: select lock, select for update • Индексы: B-TREE, HASH (no BITMAP) • point->rangescan->fullscan; • fully matching prefix; innoDB PK: clustering, data(“using index”), • myisam keycache, innodb buffer pool • dirty buffers, transaction logs: innodb_flush_trx_log_at_commit • many indexes – heavy updates • sorting: in-memory (sort buffers), filesort • USE EXPLAIN! Using temporary, using filesort • innodb_flush_method = O_DIRECT • лучше использовать маленькие таблицы вместо одной большой