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

un

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

Три концепции, которые стоит знать

Добро пожаловать

Системы, распределенные, ломаются по шаблонам. Когда вы узнаете эти шаблоны, каждый постмортем превратится в упражнение на распознавание вместо загадки.

Три концепции охватывают большинство того, что важно в анализе сбоев в производстве:

Один точка отказа (SPOF): компонент, отказ которого приводит к отключению более крупной системы. Часто скрыты: DNS-сервер, на котором everyone depends; сертификат, с которым everything обновляется; единственный база данных master.

Каскадный отказ: отказ одного компонента вызывает отказ другого, который вызывает отказ еще одного. Медленная база данных вызывает таймауты в слое API, что вызывает повторы, что нагружает базу данных еще больше, что вызывает еще больше таймаутов. Взрыв распространяется.

Радиус взрыва: как много системы выходит из строя, когда один элемент ломается. Архитектурные решения либо ограничивают, либо не ограничивают радиус. SPOF имеет неограниченный радиус взрыва. Сервис с буферами имеет ограниченный радиус.

К концу этого урока вы сможете:

- Определить SPOFs в архитектуре путем осмотра

- Опознать шаблоны каскадных сбоев: громкий стадо, буря повторов, очередь смерти

- Прочитать реальный таймлайн и разделить триггер от латентного дефекта, который триггер раскрыл

- Написать безвиновные меры, направленные на системы вместо людей, охватывая профилактику / обнаружение / восстановление

- Мыслить о буферах & предохранительных устройствах как о средствах ограничения радиуса взрыва

Узнаем один точку отказа

Проверка архитектуры с несколькими слоями

Рассмотрим небольшую веб-архитектуру:

- DNS: api.example.com -> IP-адрес одного DNS-провайдера 203.0.113.10, размещенный одним DNS-провайдером

- CDN: один поставщик CDN перед api.example.com

- Вход: два обратных прокси-машинки позади балансировщика нагрузки

- Backend: шесть реплик API в двух зонах доступности (три в каждой)

- База данных: одна основная + одна реплика чтения, в той же зоне доступности

- Кэш: кластер Redis, три узла, развернутых на двух разных зонах доступности

Вопрос: какие компоненты являются SPOFs? Подсказка: SPOFs не всегда являются очевидными 'одним сервером'. Кластер из трех машин, все в одной зоне доступности, является SPOF для отказа зоны доступности.

Определите, по крайней мере, три SPOFs в этой архитектуре. Для каждого из них назовите, что ломается, когда оно ломается, и предложите конкретное изменение, которое бы устранило SPOF (без переписывания приложения).

Три классических паттерна каскадного отказа

Отказы передаются через зависимости

Паттерн 1: Громовая стая. Общий ресурс (кэш, блокировка, база данных) выходит из строя или перезапускается. Каждый клиент, который на нем зависел, одновременно повторяет попытку. Волновая потока затопляет что-то, что снова включается; повторы наливаются быстрее, чем восстановление может их обработать; восстановление никогда не завершается.

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

Паттерн 3: Смертельная очередь. Очередь обработки с отсутствием обратной связи получает быстрее, чем обрабатывает. Очередь бесконечно растет. Память истощается; потребитель падает; перезапускается; находит все еще более крупную очередь; снова падает.

Общий нить: малое первоначальное возмущение вызывает положительный обратный отсчет. Ответ системы усиливает отказ вместо сглаживания его.

Механизмы сглаживания

Экспоненциальное отсрочивание с джиттером. Клиенты, которые повторяют, ждут дольше каждый раз, с случайным смещением. Предотвращает синхронные волны повторов.

Реле обрыва циркуляции. Пользователь, обращающийся, отслеживает скорость отказа downstream. После порога пользователь перестает звонить на период охлаждения и сразу отказывается в своих запросах.

Бульбашка. Изолировать ресурсы в зависимости. Пул соединений A для базы данных, отдельный пул соединений B для кэша. Медленная база данных не может лишить всех соединений; вызовы кэша продолжаются.

Отвод нагрузки. Когда перегружены, отбрасывать запросы на границе вместо принятия и медленного отказа. 429 за 1 мс лучше, чем 500 за 30 секунд.

Нагрузка отвода. Медленно производить, когда потребители не могут поддерживать скорость. Очереди становятся ограниченными; отправители блокируются; первоначальный источник работы ощущает трение.

Каскадный отказ: инициатор -> усилитель -> разрушение, с механизмами сглаживания

Диагностика каскадного отказа

API-уровень команды выходит из строя во время обычной базы данных failover. Ход событий:

- 14:00:00 — оператор переводит в работу запасную базу данных. Ожидаемое время недоступности: ~10 секунд.

- 14:00:08 — основная база данных недоступна. Ошибки подключения к базе данных у API-уровня.

- 14:00:08 — API-уровень пытается повторить (по умолчанию: 5 попыток, без отсрочки, через 100мс).

- 14:00:11 — запасная база данных переведена в работу, принимает новые подключения.

- 14:00:11 — API-уровень открывает тысячи новых подключений к базе данных одновременно (каждый реплика × каждый текущий запрос × каждый повтор).

- 14:00:13 — новый основной сервера истощает пул подключений; новые подключения отклоняются.

- 14:00:13-14:05:00 — реплики API-уровня истощают пулы подключений, генерируют исключения, перезапускаются, повторяют цикл.

- 14:05:00 — оператор вручную останавливает трафик API-уровня; база данных стабилизируется.

- 14:10:00 — завершение постепенного восстановления трафика. Общее время отключения: ~10 минут (вместо ожидаемых ~10 секунд).

Определите паттерн каскада, действующий в данной ситуации, назвать механизмы торможения, которые могли бы предотвратить его (по крайней мере два), и объяснить, почему переключение с основного на запасной (предназначенное для перерыва в 10 секунд) вместо этого вызвало отключение на 10 минут.

DNS SERVFAIL: Два Умножающихся Недостатка

Реальный-Шейп Постмортем

Вот следует санитированная версия реального инцидента. Названия поставщиков изменены, IP-адреса анонимизированы; форма, хронология, и уроки являются реальными.

Обзор

Сайт example.com возвращал SERVFAIL из всех публичных DNS-резолверов в течение примерно 3-4 часов. Все остальные 46 зон на том же DNS-мастере не были затронуты. Причина: два взаимодействующих недостатка.

1. Поставщик A (второстепенный DNS-провайдер) добавил новый внутренний синхронизированный IP, который не был в allowlist allow-axfr-ips основного сервера.

2. Зона example.com имела годичный конфликт CNAME, нарушавший RFC (demo.example.com имел как CNAME, так и MX/TXT записи на одном и том же подуровне), что вызвало отказ от обработки зоны на свежем AXFR у поставщика A.

Хронология (UTC)

- ~15:00 — Поставщик A добавляет новый синхронизированный IP 198.51.100.42 в свою инфраструктуру

- 15:02 — first AXFR-out denied for 198.51.100.42 appears in primary DNS logs (no alerting on this signal)

- ~18:00 — SOA expire window reached; Vendor A drops example.com zone from cache

- ~18:30 — SERVFAIL detected externally

- ~19:45 — root cause identified

- 20:00 — 198.51.100.42 added to allow-axfr-ips; primary restarted

- 20:05 — NOTIFY sent; AXFR initiated; zone STILL SERVFAIL (CNAME conflict)

- 20:07 — check-zone reveals 1 error: CNAME conflict on demo.example.com

- 20:09 — CNAME replaced with A record; zone check clean (0 errors)

- 20:10 — NOTIFY sent; AXFR completes; Vendor A begins serving zone

- 20:11 — dig @8.8.8.8 example.com A returns correct IP — RESOLVED

Почему только example.com?

Все 47 зон используют одну и ту же DNS-первичную. IP-шный блок для AXFR затрагивал все зоны. Но только example.com имел конфликт CNAME, и только example.com нуждался в свежем AXFR в момент, когда запрет был введен. Другие зоны уже обновились до запрета или еще не должны были.

Скрытый дефект

Конфликт CNAME на demo.example.com существовал годами. Это работало потому что первичный сервер зону отдавал из своей базы данных (снисходительный по отношению к нарушениям RFC) и Vendor A отслеживал устаревшие данные из предыдущего нарушения. Когда Vendor A сбросил свой кэш и нуждался в свежих данных, нарушение проявилось.

Триггер

Vendor A внезапно добавил новый IP-синхронизации. Первичный список разрешений не включал его. AXFR был отклонен. Три часа спустя (SOA expire), Vendor A сбросил зону. Скрытый дефект проявился, когда система пыталась восстановиться.

Напишите безвинные действия по исправлению

Безвинно: Целевая система, а не люди

Безвинный пункт действий называет то, что система должна делать по-другому, а не то, что человек должен делать по-другому. 'Тренировать оператора' - виновато. 'Добавить автоматический контроль, который ловит это перед развертыванием' - безвинно.

Хорошие безвинные пункты действий группируются в три измерения:

- Профилактика: сделать плохое сложнее или невозможно

- Обнаружение: заметить это раньше, если это произойдет

- Восстановление: ограничить ущерб при его возникновении

Каждый пункт должен называть (1) конкретное изменение системы, (2) команду-владельца и (3) измерение, на которое он направлен.

Напишите три безвинных действия по исправлению, касающихся DNS-SERVFAIL постмортема выше. Распределите их между профилактикой / обнаружением / восстановлением (по одному на каждой измерителя). Каждый пункт должен называть конкретное изменение системы и владеющую команду. НЕ целяться на человека как на причину.

Компартименты, тонущие без корабля

Заимствовано из военно-морской техники

Корабли имеют водонепроницаемые переборки: вертикальные стены, которые делят корпус на отсеки. Один отсек может затопиться без того, чтобы потопить корабль; другой может выйти из строя без влияния на остальные.

Распределенные системы заимствуют ту же фразу и ту же идею.

Паттерн переборки: изолировать ресурсы в зависимости от зависимости. Сервис, который вызывает три downstream API, использует три отдельных пула соединений, три отдельных пула потоков, три отдельных бюджета повторных попыток. Дистанционная служба, которая медленно или неудачно, не может потреблять ресурсы, выделенные для других двух.

Без переборок: одна медленная зависимость истощает общий пул потоков; вызовы других зависимостей блокируются, ожидая потоков; вся служба становится неработоспособной.

С переборками: одна медленная зависимость истощает свой собственный пул; вызовы к ней быстро завершаются с ошибкой; вызовы к другим зависимостям продолжаются нормально; радиус взрыва ограничивается затрудняющейся зависимости.

Реле обрыва

Паттерн реле обрыва: состояние обертки вокруг удаленной зависимости, которая отслеживает частоту сбоев. Три состояния:

- Закрыто (нормально): вызовы проходят. Сбои подсчитываются.

- Открыто (выстрелено): после превышения порога сбоев (например, 50% сбоев за последние 30 секунд), реле открывается. Вызовы сразу же завершаются с ошибкой без попытки зависимости. Спасает вызывающего от потраченной работы; спасает зависимость от получения нагрузки, когда она нездорова.

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

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

Переборки ограничивают радиус взрыва. Реле обрыва предотвращает поддержание взрыва.

Ограничить радиус взрыва

Ваш API-сервис вызывает четыре downstream-сервиса: User Service, Recommendation Service, Notification Service и внешний Payment API. Команда слышала, что Recommendation Service иногда работал нестабильно, и хочет убедиться, что при его сбое остальная часть системы остается здоровой.

Сегодня сервис использует единую общую пул потоков в 200 потоков и единую общую пул HTTP-соединений. Все четыре downstream-сервиса конкурируют за эти ресурсы. Нет цепных разрывов.

Предложите дизайн переборки + реле обрыва для этого API-сервиса. Будьте конкретны: как вы разделяете поток / пулы соединений между четырьмя зависимостями, какие пороги реле обрыва уместны для нестабильной Recommendation Service, и что должно делать пользовательский API, когда Recommendation Service находится в открытом состоянии.

Создание отзыва на возможные сбои

Синтез

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

Примените все пять.

Вашей команде предстоит запуск нового сервиса search.example.com, который зависит от трех downstream-сервисов: основного сервиса поиска (index.example.com), аналитического сервиса (analytics.example.com) и сервиса рекомендаций (recs.example.com). Команда просит вас провести 'отзыв на возможные сбои' перед запуском.

Опишите отзыв на возможные сбои, который вы бы провели. Включите: как бы вы выявили SPOFs (одна методика), как бы вы предотвратили каскадный сбой между сервисом поиска и его тремя downstream-сервисами (два шаблона), одно конкретное действие для сервиса рекомендаций (который команда указала как менее надежный) и что мониторинга вам потребуется иметь в наличии к моменту запуска.

Где эта курс идет дальше

Где этот курс идет дальше

Вы теперь можете выявить SPOF, узнать каскадный сбой, продуктивно читать постмортем, писать безвинные действия, и ограничивать радиус разрушения с помощью дизайна.

Последнее занятие в этом курсе (cs_distsys_observability_and_capacity) учитывает, что нужно измерять, чтобы выявить проблему до того, как пользователи этого узнают. Проверки здоровья, версии конечных точек, четыре золотых сигнала на уровне прокси и как решения о резервном объеме связаны с наблюдаемыми данными.

Сопутствующее занятие: geometry_of_failure_modes_and_blast_radius определяет междуцентральность (который графический узел является узким местом) и минимальный разрыв (граница на радиус взрыва).

Хорошая работа. Вперед.