English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

гость
1 / ?
назад к урокам

Узлы, рёбра, направления

Запрос как ход на графе

Каждый компонент, с которым взаимодействует запрос, является вершиной: клиент, разрешающий сервер DNS, крайний узел CDN, обратный прокси, реплика сервера backend, база данных, кэш.

Каждое соединение между двумя узлами - это направленное ребро: запросы текут вперед, ответы текут назад. Ребро, идущее вперед, представляет собой открытый TCP-соединение плюс протокол, наложенный сверху.

Один запрос - это путь по этому графу. Общая работа системы, которую она выполняет для ответа на запрос, равна сумме работы на каждой вершине, плюс задержка каждого ребра.

Почему это важно? Когда вы нарисуете граф, свойства, которые не видны в коде, всплывают:

- Количество переходов: количество ребер в пути. Каждый переход добавляет задержку (круговая задержка сети + обработка узла). Меньше переходов = ниже базового уровня задержки.

- Входной градус: количество ребер, указывающих ВНУТРИ узла. Высокий входной градус означает, что узел получает запросы от многих источников и должен масштабироваться или защищаться.

- Выходной градус: количество ребер, указывающих ВНУТРИ узла. Высокий выходной градус означает, что узел зависит от многих downstream и имеет много путей к отказу.

- Точка разрыва: одиночная вершина, удаление которой разрывает граф. Обратный прокси без пирата - это точка разрыва; удаление его удаляет все доступ к его источникам.

Запрос как путь через направленный граф: клиент, прокси, backend, база данных

Нарисуйте (или опишите в тексте) граф запроса для: браузер клиента -> крайний узел CDN -> обратный прокси -> реплика сервера backend -> база данных. Подсчитайте переходы. Определите вершины разрыва. Прогnoзгните одну операционную последствие такого большого количества вершин разрыва подряд.

Где сосредотачивается трафик

Концентрация (Fan-In)

Степень входа узла = количество входящих к нему ребер. В графе запросов, степень входа = количество исходящих источников запросов.

Схема концентрации: много клиентов -> один CDN; много CDN-ребер -> несколько origin-прокси; много прокси -> меньше бэкенд-реплик; много бэкендов -> одна база данных.

Важно, что узел с наивысшей степенью входа видит наибольшую суммарную нагрузку. База данных в конце цепи может видеть запросы от каждого активного запроса в системе, даже если ни один пользователь не генерирует много.

Зависимость (Fan-Out)

Степень выхода узла = количество исходящих из него ребер. Высокая степень выхода означает много downstream-зависимостей.

Бэкенд, вызывающий базу данных, два кэша, три внешних API и очередь, имеет степень выхода 7. Его вероятность успеха примерно равна произведению каждой downstream-вероятности успеха (если все необходимы для успешного ответа).

0.999 ^ 7 ≈ 0.993: бэкенд с 7 downstream, каждый с вероятностью 99,9% надежности, может достичь только ~99,3% надежности самого себя, даже при отсутствии собственных ошибок.

Уменьшить степень выхода: кэширование результатов downstream, делая необязательными некритичные downstream (мягкая децентрализация), параллелизация того, что можно параллелизировать.

Асимметрия

Концентрация увеличивает нагрузку; зависимость умножает риск. Граф с правильной формой минимизирует оба параметра на узлах с наибольшим влиянием.

База данных (наивысшая концентрация): кэширование агрессивно, чтобы уменьшить нагрузку. Чтение реплик бэкенда для распределения концентрации между несколькими узлами.

Оркестратор (наивысшая зависимость): циркулярные разрывы для каждой зависимости, мягкая децентрализация, bulkheads.

Бэкенд-реплика вызывает 4 downstream-сервиса, каждый независимо с вероятностью успеха 99,95%. (1) Какова верхняя граница доступности бэкенда, если все 4 вызова необходимы для успешного ответа? (2) Если 2 из 4 downstream-сервисов сделаны опциональными путем мягкой децентрализации (замена их кэшированными фоллбэками при недоступности), какая граница становится?

Вставленный узел приобретает гибкость

Индирект = Добавление промежуточного узла

Без прокси-устройства, граф выглядит так: client -> backend. Клиент должен знать о адресе backend. Перемещение backend требует обновления клиента (через DNS или конфигурацию). Это тугое связывание.

С прокси-устройством, граф становится: client -> proxy -> backend. Клиент знает только о прокси. Перемещение backend требует обновления конфигурации прокси-устройства вверх, а не клиента.

Графовая операция: вставить узел вдоль существующего ребра. Новое ребро client -> proxy устойчиво; новое ребро proxy -> backend теперь в компетенции команды.

Геометрическое чтение: индирект добавляет слой, который декуплирует изменение вверху от изменение внизу. Каждый слой может независимо перенастраиваться.

Стоимость индиректа

Каждый слой добавляет:

- Один прыжок задержки (ребро от клиента к прокси)

- Еще одну вершину разрыва на пути (прокси-устройство)

- Еще одно место, где может произойти ошибочная конфигурация

Польза (перенастройка, масштабирование, защита, завершение TLS, распределение нагрузки) обычно перевешивает затраты для любого неочень сложного системы. Но есть предел: каждый слой индиректа добавляет еще один прыжок и еще одного кандидата на SPOF.

Фольклорное правило: любую проблему можно решить, добавив слой индиректа (кроме проблемы слишком большого количества слоев индиректа).

A team adds a CDN in front of an existing reverse proxy. The path goes from `client -> proxy -> backend` (2 hops) to `client -> CDN -> proxy -> backend` (3 hops). Name two benefits of the indirection (graph-theoretic terms welcome) & two costs.

Прочитайте архитектуру как граф

Синтез

Теперь вы можете читать архитектуру системы как граф: считать прыжки, идентифицировать вершины разрыва, измерять концентрацию fan-in, вычислять потолки доступности от fan-out и оценивать торговые предложения индиректа.

Примените все четыре.

Новый сервис имеет такую архитектуру: клиенты -> CDN -> обратный прокси (2 реплики) -> backend слой (8 реплик) -> { основной база данных, кластер кэша (3 узла), внешний API }.

Анализируйте: (1) какой максимальный прыжок на одном пути запроса, (2) какой уровень тир имеет наибольшую fan-in (и что это подразумевает для масштабирования), (3) какой потолок доступности backend, если DB 99.95%, кэш 99.95% и внешний API 99.9%, все обязательны, и (4) какой один узел, если убрать, бы больше отключил пользователей?

Дополнительные примечания

Дополнительные примечания

Эта геометрия-урок преобразует основной урок Proxies & Origins в анализ направленного графа.

Следующее дополнение в этом курсе, geometry_of_stateless_horizontal_scaling, берет математический анализ реплик из основного урока масштабирования и выводит кривую очереди, закон Литтла и колено геометрического 80% использования.

Хорошая работа.