1. Виды кластеров
1.1. HP
1.1.1. High Performance
1.2. HA
1.2.1. High Availability
1.3. HL
1.3.1. High Load
2. Enterprise vs WebSphere
2.1. Бесплатный софт
2.1.1. Огромное количество машин, накладные расходы
2.2. Открытый софт
2.2.1. manageable
2.2.2. нет полностью готовых решений
2.2.2.1. всё собирается как из конструктора
2.3. Относительно дешёвое железо
3. Основные проблемы и вызовы
3.1. Большая нагрузка (тысячи и миллионы хитов)
3.2. Высокие ставки
3.2.1. Потребность в быстрой разработке
3.2.1.1. Высококонкурентное окружение
3.2.2. Высокие риски
3.2.2.1. резкий рост нагрузок
3.2.2.2. Высокая надёжность
3.2.2.3. DDoS
3.2.3. Большая ответственность на разработчике
3.3. Зоопарк технологий и сервисов
3.4. Большая команда
3.5. Хороший проект
3.5.1. Технический менеджмент
3.5.2. Системное администрирование
3.5.3. Поддержка
3.5.4. Разработка
3.6. Ловушки
3.6.1. не масштабируемая архитуктура
3.6.1.1. высокая степень связности
3.6.1.1.1. данные
3.6.1.1.2. компоненты
3.6.2. "полурешения"
3.6.2.1. накапливаемые риски
3.6.3. "горе от ума"
3.6.3.1. теоретики vs практики
4. Уровни зрелости высоконагруженного проекта
4.1. Рост проекта
4.1.1. Один сервер
4.1.2. Несколько серверов
4.1.3. Много серверов (сотни, тысячи)
4.1.4. Много ДЦ
4.2. Переход между уровнями -- обычно кризис
4.3. Ключевое значение -- масштабируемая архитектура
4.4. Грамотное многоуровневое проектирование
4.4.1. Масштабируемость и производительность должна учитываться на всех уровнях
4.4.1.1. Софт
4.4.1.2. Библиотеки
4.4.1.3. СУБД
4.4.1.4. ФС
4.4.1.5. hardware: диски, память, сеть, CPU
5. Как будем повышать пропускную способность?
5.1. P = C / t
5.1.1. Пропускная способность в единицу времени = кол-во одновременно обрабатываемых запросов / время обработки одного запроса
5.2. Уменьшение времени отклика
5.2.1. Оптимизация
5.2.1.1. premature optimization
5.2.1.1.1. 80% опт. алгоритма
5.2.1.1.2. 15% опт. кода
5.2.1.1.3. 5% отп. машинного кода
5.2.1.2. замеряйте прежде чем менять!
5.2.2. Кэширование
5.2.3. Тюнинг ОС / СУБД / инфраструктурного ПО
5.2.3.1. Тюнинг ОС
5.2.3.2. Тюнинг СУБД
5.2.3.2.1. Сложно
5.2.3.3. Тюнинг ФС
5.2.3.3.1. xfs
5.3. Увеличение количества одновременно обрабатываемых запросов
5.3.1. Масштабирование
5.3.1.1. График: затраты / профит
5.3.1.2. Почти никогда не бывает полностью линейным
5.3.1.2.1. Overhead
5.3.1.3. web-серверов
5.3.1.4. баз-данных
5.3.1.5. Способы масштабирования
5.3.1.5.1. scale up (вертикальное)
5.3.1.5.2. scale out (горизонтальное)
5.3.1.6. Уменьшаем связность
5.3.1.6.1. компонентная архитектура (связность в пространстве / монолитность)
5.3.1.6.2. асинхронная обработка (связность во времени)
6. Масштибирование web-серверов
6.1. Ловушки / проблемы
6.1.1. share nothing
6.1.1.1. примеры: общие данные на NFS: сессии, код
6.1.1.2. минимум доступа к разделяемым ресурсам
6.1.1.3. share accuretely
6.1.2. общий кэш
6.1.2.1. больше cache hits
6.2. Frontend / акселлератор
6.2.1. Двухуровневая система: frontend / backend
6.2.1.1. принципиально разные задачи у frontend и backend
6.2.1.1.1. Разве повар вместо официанта принимает заказ?
6.2.2. Преимущества
6.2.2.1. Медленные клиенты (spoon feeding)
6.2.2.2. Большое количество соединений (> 100000)
6.2.2.3. Раздача статики
6.2.2.4. Кэширование динамики
6.2.2.5. Шифрование
6.2.2.6. Сжатие трафика
6.2.2.7. Аутентификация
6.2.2.8. Интеллектуальная обработка / доп. логика
6.2.2.8.1. nginx-perl
6.2.3. Примеры
6.2.3.1. nginx
6.2.3.2. haproxy
6.2.3.3. lighttpd
6.3. Способы распределения нагрузки
6.3.1. DNS-LB
6.3.1.1. TTL
6.3.2. IP AnyCast
6.3.2.1. BGP
6.3.3. IP-LB (Layer-4)
6.3.3.1. Linux IPVS
6.3.3.2. FreeBSD CARP
6.3.3.3. M$ NLB
6.3.4. http-проксирование / reverse proxy (Layer-7)
6.3.5. http-переадресация
6.3.6. технологии CDN
7. Масштабирование баз данных
7.1. scale up (более мощное железо)
7.1.1. Больше CPU
7.1.1.1. Ограниченная масштабируемость большинства СУБД
7.1.1.1.1. Особенно mysql
7.1.2. Больше памяти
7.1.2.1. Больше кэшей
7.1.3. Нелинейный эффект от вложения денег
7.2. Репликация
7.2.1. Виды
7.2.1.1. Синхронная / асинхронная
7.2.1.2. master-master / master-slave
7.2.2. Проблемы
7.2.2.1. Выигрыш нелинейный
7.2.2.2. Большой overhead на синхронизацию
7.2.2.2.1. иерархия серверов
7.2.2.3. Неконсистентные данные
7.2.2.3.1. Репликация в один тред
7.2.2.4. Запись не масштабируется!
7.2.2.4.1. master / master
7.2.3. Как роутить чтение между серверами
7.2.3.1. proxy
7.2.3.1.1. mysqlproxy
7.2.3.1.2. pgproxy
7.2.3.1.3. "sql proxy" от slonik_v_domene
7.3. Вертикальное масштабирование
7.3.1. Выделение ролей для серверов (разные таблицы на разных серверах)
7.3.1.1. Проблемы
7.3.1.1.1. Всё равно упираемся в пределы физической машины
7.3.1.1.2. До свиданья джойны...
7.3.2. Partitioning (разные куски таблицы / разные таблицы на разных дисках)
7.3.2.1. Можно физически хранить на разных storage...
7.3.2.2. Минусы
7.3.2.2.1. Узким местом всё равно становится CPU / масштабируемость СУБД
7.4. Горизонтальное масштабирование
7.4.1. Плюсы
7.4.1.1. Неограниченное масштабирование
7.4.2. Как разделять данные
7.4.2.1. Статически
7.4.2.1.1. По "первой букве"
7.4.2.1.2. Хэш-функции
7.4.2.1.3. По дате
7.4.2.1.4. По диапазону ID PK
7.4.2.1.5. Проблемы -- слишком жёсткие правила, неудобно добавлять серверы
7.4.2.2. Динамически
7.4.2.2.1. добавление новых машин, замена, перенос, балансировка – без изменения кода
7.4.2.2.2. Минус: SPOF, высокая нагрузка
7.4.2.2.3. Роутинг
7.4.3. Решения
7.4.3.1. Вручную, внутри приложения
7.4.3.1.1. Нужно писать прослойку для работы с данными
7.4.3.2. proxy
7.4.3.2.1. PL/Proxy
7.4.3.2.2. mysqlproxy
7.4.4. Минусы
7.4.4.1. Нельзя JOINs
7.4.4.2. Усложняется доступ к данным
8. Алгоритмы
8.1. Очереди
8.1.1. Всё что можно сделать потом -- делаем потом
8.1.2. Примеры
8.1.2.1. Почта: двойная асинхронность
8.1.2.2. Комментарии к постам в блоге
8.1.2.2.1. Счётчик комментариев
8.1.3. Реализации
8.1.3.1. PgQ
8.1.3.2. Gearman
8.1.3.3. RabbitMQ
8.1.4. Плюсы
8.1.4.1. Сглаживает пики нагрузки
8.1.4.1.1. Меньше требования к мощностям
8.1.4.2. Уменьшает время отклика
8.1.5. Минусы
8.1.5.1. Нет транзакций
8.1.5.2. Данные неконсистентны
8.1.5.2.1. Применяем внимательно и точечно
8.2. Асинхронный ввод-вывод
8.2.1. Perl-библиотеки
8.2.1.1. AnyEvent
8.2.1.2. Coro
8.2.1.3. POE
8.2.1.4. IOl::Lambda
8.2.2. Механизмы ОС
8.2.2.1. неблокирующиеся сокеты
8.2.2.2. epoll
8.2.2.3. kqueue
8.2.2.4. WaitForMultipleObjects
8.3. Распределённая обработка данных
8.3.1. Алгоритмы
8.3.1.1. MapReduce
8.3.2. Реализации
8.3.2.1. Hadoop
8.3.2.1.1. HDFS
8.3.2.1.2. HBase
8.3.2.1.3. Cassandra
9. Хранение данных
9.1. CAP-теорема (теорема Брюера)
9.1.1. Принципы
9.1.1.1. Consisency
9.1.1.2. Availability
9.1.1.3. Partition tolerance
9.1.2. Рабочие комбинации
9.1.2.1. CA
9.1.2.1.1. ACID-СУБД
9.1.2.1.2. LDAP
9.1.2.2. CP
9.1.2.3. AP
9.1.2.3.1. DNS
9.1.2.3.2. eventually consystent
9.1.2.3.3. weak consistent
9.1.2.4. BASE
9.1.2.4.1. Basically Available
9.1.2.4.2. Soft-state
9.1.2.4.3. Eventually consistent
9.2. Транзакционная целостность
9.2.1. ACID
9.2.1.1. Atomicity
9.2.1.1.1. что никакая транзакция не будет зафиксирована в системе частично
9.2.1.2. Consistency
9.2.1.2.1. Согласованность данных
9.2.1.3. Isolation
9.2.1.3.1. другие процессы не должны видеть данные в промежуточном состоянии
9.2.1.4. Durability
9.2.1.4.1. успешные транзакции обязаны быть сохранены
10. Альтернативы реляционным СУБД / NoSQL
10.1. Ключ-значение key / value
10.1.1. Основные особенности
10.1.1.1. Хорошее горизонтальное масштабирование
10.1.1.2. Partitioning
10.1.1.3. Простые API
10.1.1.4. Отказ от транзакционной целостности
10.1.1.5. Нетабличная структура
10.1.2. Примеры
10.1.2.1. memcached
10.1.2.2. BerkleyDB
10.1.2.3. MemcacheDB
10.1.2.4. Redis
10.1.2.5. MongoDB
10.1.2.6. tarantool
10.1.2.7. CouchDB
10.1.2.8. Membase
10.1.3. Протоколы
10.1.3.1. UnQL
10.1.3.1.1. Unstructured Query Language
10.2. Полнотекстовый поиск
10.2.1. sphynx
10.2.2. apache solr
10.3. Объектные БД
10.3.1. Caché
10.4. Column-based СУБД
10.4.1. Плюсы
10.4.1.1. Каждую колонку можно отсортировать по своему
10.4.1.2. Не нужны индексы
10.4.1.3. Эффективное сжатие данных
10.4.1.4. Уже посчитанная статистика
10.4.2. примеры
10.4.2.1. Infobright
10.4.2.2. InfiniDB
10.4.2.3. MonetDB
10.5. Гибридные механизмы
10.5.1. HandlerSocket