Оглавление
- Введение в System Design и работа с требованиями
- Моделирование систем (UML)
- CAP-теорема: Фундаментальные ограничения
- Балансировка нагрузки и CDN
- Кэширование: Стратегии и Инвалидация
- Масштабирование баз данных
- Порождение идентификаторов в распределенных системах
- Паттерны асинхронного взаимодействия (Bus)
- Распределенные паттерны: Event Sourcing и Saga
- Consistent Hashing (Согласованное хэширование)
1. Введение в System Design и работа с требованиями
System Design — процесс проектирования архитектуры, модулей и интерфейсов системы для удовлетворения заданных требований.
Работа с требованиями
- Функциональные требования (ФТ): Что система должна делать.
- Необходимо выявлять истинную проблему бизнеса, а не просто реализовывать “как” просит заказчик.
- Ubiquitous Language (Единый язык): Создание словаря терминов, понятного и бизнесу, и разработке.
- Event Storming: Методика анализа процессов через события (event), команды (command) и действующих лиц (actors).
- Нефункциональные требования (НФТ): Как система должна работать (атрибуты качества).
- Производительность, масштабируемость, надежность, наблюдаемость.
- Уровни обслуживания (SRE-подход):
- SLI (Indicator): Метрика (например, время ответа).
- SLO (Objective): Внутренняя цель (99.9% запросов < 200мс).
- SLA (Agreement): Юридическое обязательство перед клиентом.
Физические ограничения
- Сетевые и дисковые операции на порядки медленнее операций в памяти.
- Пример: Чтение из L1 кэша (~0.5 нс) против сетевого запроса в другой дата-центр (~150 мс).
2. Моделирование систем (UML)
Для однозначного описания архитектуры используются визуальные модели:
- Sequence Diagrams (Диаграммы последовательности): Взаимодействие объектов во времени.
- Class Diagrams (Диаграммы классов): Статическая структура и отношения (композиция, агрегация).
- State Diagrams (Диаграммы состояний): Жизненный цикл объекта и переходы.
3. CAP-теорема: Фундаментальные ограничения
В распределенной системе невозможно одновременно обеспечить более двух свойств из трех:
- Consistency (Согласованность): Все узлы видят одинаковые данные одновременно.
- Availability (Доступность): Каждый запрос получает ответ (успешный или нет).
- Partition Tolerance (Устойчивость к разделению): Система работает при разрыве связи между узлами.
Ключевой выбор: Поскольку сетевые сбои (P) неизбежны, мы выбираем между:
- CP (Consistency + Partition Tolerance): Жертвуем доступностью ради точности (Zookeeper, MongoDB).
- AP (Availability + Partition Tolerance): Жертвует согласованностью ради доступности (Cassandra, DynamoDB). Обеспечивают Eventual Consistency.
4. Балансировка нагрузки и CDN
Виды масштабирования
- Вертикальное (Scale Up): Наращивание ресурсов одного сервера (имеет предел).
- Горизонтальное (Scale Out): Добавление новых серверов.
Подходы к балансировке
- На клиенте: Клиент получает список адресов через Service Discovery.
- На сервере (Load Balancer): Прокси-узел (Nginx, HAProxy) распределяет трафик.
- Алгоритмы: Round Robin, Weighted RR, Least Connections, Sticky Sessions.
- CDN (Content Delivery Network): Сеть PoP-узлов (Points of Presence) для доставки статики из ближайшей к пользователю географической точки.
5. Кэширование: Стратегии и Инвалидация
Ключевые метрики
- Cache Hit / Miss: Попадание или промах мимо кэша.
- Hit Ratio: Отношение попаданий к общему числу запросов.
Стратегии чтения и записи
- Read Through: Если данных нет в кэше, приложение само идет в БД, обновляет кэш и возвращает ответ.
- Write Through: Данные пишутся одновременно в кэш и в БД.
- Write Back (Отложенная запись): Данные пишутся только в кэш, а в БД попадают асинхронно (риск потери данных при сбое).
Инвалидация (вытеснение)
- TTL (Time To Live): Удаление по времени.
- LRU (Least Recently Used): Удаление давно не использовавшихся данных.
- Cache Stampede: Проблема, когда при истечении кэша множество клиентов одновременно бьют в БД.
6. Масштабирование баз данных
Репликация
Копирование данных между узлами для отказоустойчивости.
- Master-Slave: Мастер принимает запись, Slave — только чтение.
- Синхронная: Мастер ждет подтверждения от Slave (высокая консистентность, медленная запись).
- Асинхронная: Мастер подтверждает запись сразу (возможна потеря данных при сбое мастера).
Партиционирование (Секционирование)
Разбиение таблицы на части внутри одного сервера.
- Цель: Ускорение запросов и удобство обслуживания (удаление старых партиций).
Шардирование
Горизонтальное разделение данных между разными серверами.
- Вертикальное: Разные колонки на разных серверах.
- Горизонтальное: Разные строки на разных серверах по ключу шардирования.
- Минусы: Нет JOIN-ов между шардами, сложность транзакций.
7. Порождение идентификаторов в распределенных системах
В распределенных (шардированных) системах AUTO_INCREMENT не работает.
- UUID (v4/v7): Децентрализовано, но v4 не упорядочен (плохо для индексов).
- Snowflake ID (Twitter): 64-битный ID (Timestamp + Machine ID + Sequence). Глобально упорядочен.
- Sequence + Shard ID: Использование локального сиквенса шарда с добавлением ID самого шарда.
8. Паттерны асинхронного взаимодействия (Bus)
Используются для построения слабосвязанных систем и достижения Eventual Consistency.
- Event Bus (Шина событий): Уведомление “что-то произошло” (
OrderCreated). Подписчик сам идет за деталями. - Command Bus (Шина команд): Приказ “сделай это” (
CreateOrder). Содержит все данные для выполнения. - Data Bus (Шина данных): Передача полного состояния объекта для репликации или кэширования.
9. Распределенные паттерны: Event Sourcing и Saga
Event Sourcing
Хранение не состояния, а неизменяемого лога событий.
- Плюсы: Полный аудит, возможность восстановить состояние на любой момент времени (Time Travel).
- Минусы: Сложность чтения текущего состояния (требуются снапшоты).
Saga
Управление транзакциями между микросервисами через последовательность локальных транзакций.
- Хореография: Сервисы обмениваются событиями без центрального узла.
- Оркестрация: Центральный сервис управляет шагами и вызывает компенсирующие транзакции (откат) при сбоях.
10. Consistent Hashing (Согласованное хэширование)
Решает проблему решардинга.
- При обычном
hash(id) % Nдобавление нового узла заставляет перемещать почти все данные. - Согласованное хэширование размещает узлы и данные на виртуальном кольце. При добавлении/удалении узла перемещается в среднем лишь
1/Nчасть данных.
Примечание: “Часы проектирования экономят недели разработки”. Проектируйте системы с учетом возможности их горизонтального масштабирования и неизбежности сбоев (Failure is inevitable).