Оригинальная статья: https://sre.google/resources/practices-and-processes/twenty-years-of-sre-lessons-learned/
Adrienne Walcer, Kavita Guliani, Mikel Ward, Sunny Hsiao, и Vrai Stacey
Ali Biber, Guy Nadler, Luisa Fearnside, Thomas Holdschick, и Trevor Mattson-Hamilton
За двадцать лет может произойти многое, особенно когда вы активно развиваетесь.
Двадцать лет назад у Google было пара небольших дата-центров, каждый из которых содержал несколько тысяч серверов, соединенных в кольцо парой 2.4Гбит/с магистралей. Мы управляли нашим частным облаком (хотя мы не называли это так в то время) с помощью Python-скриптов, таких как "Assigner" и "Autoreplacer" и "Babysitter", которые работали с конфигурационными файлами, полными индивидуальных имен серверов. У нас была небольшая база данных машин (MDB), которая помогала поддерживать информацию о каждом сервере организованной и устойчивой. Для сокращения ручного труда, необходимого для управления нашим маленьким флотом серверов, наша небольшая команда инженеров использовала скрипты и конфигурационные файлы.
Время шло, пользователи Google приходили из-за поиска и оставались из-за бесплатного гигабайта от Gmail, и наш флот и сеть росли. Сегодня, с точки зрения вычислительной мощности, мы выросли в 1000; в сети - более чем в 10,000 раз больше, и мы тратим гораздо меньше усилий на сервер, чем раньше, при этом наслаждаясь гораздо лучшей надежностью. Наши инструменты эволюционировали от коллекции Python-скриптов до интегрированных экосистем сервисов -- единой платформы, которая предлагает надежность по умолчанию. И наше понимание вопросов отказоустойчивости распределенных систем также эволюционировало, поскольку мы сталкивались с новыми классами сбоев. Мы создали "Wheel of Misfortune", мы написали руководства по лучшим практикам сервисов, мы опубликовали "Google's Greatest Hits", и сегодня мы с ужасом рады представить:
Давайте начнем с 2016 года, когда YouTube предлагал ваши любимые видео, такие как "Carpool Karaoke с Adele" и всегда заразительный "Pen-Pineapple-Apple-Pen". Тогда произошел пятнадцатиминутный глобальный сбой из-за ошибки в распределенной системе кэширования памяти YouTube. Вот три урока, которые мы извлекли из этого инцидента.
1 Степень риска действий принимаемых по устранению инцидента не должна быть выше степени влияния инцидента
Есть мем, где один человек выкладывает картинку паука, увиденного в их доме, и капитан говорит: "ПОРА ПЕРЕЕХАТЬ В НОВЫЙ ДОМ!". Шутка в том, что на инцидент (увидеть страшного паука) будет отреагировано резким действием (покинуть текущий дом и переехать в новый). Мы, здесь в SRE, имели некоторый интересный опыт в выборе мер реагирования с рисками большими, чем сбой, с которыми они должны были бы помочь. Во время упомянутого сбоя на YouTube, рискованный процесс сброса нагрузки (load-shedding, временный отказ от обработки части запросов, прим. пер.) не исправил сбой... он вместо этого создал каскадный отказ.
Мы усвоили на собственном опыте, что во время инцидента мы должны мониторить и оценивать серьезность ситуации и выбирать тот путь смягчения последствий, рискованность которого соответствует этой серьезности. В лучшем случае рискованные меры решат сбой. В самом худшем случае рискованная мера не срабатывает как надо, и сбой затягивается из-за того, что изначально задумывалось как решение проблемы. К тому же, если ситуация полностью вышла из-под контроля, можно сознательно решить отступить от стандартных процедур (Речь о том, что если нет подходящей процедуры, а имеющиеся излишне серьезны, лучше придумать что-то еще, чем рисковать каскадом сбоев. Прим. пер.).
Чрезвычайная эвакуация из-за пожара в высотном здании города -- ужасная возможность впервые использовать лестницу. Аналогично, сбой -- ужасная возможность впервые попробовать рискованный процесс load-shedding. Чтобы сохранять спокойствие в ситуации высокого риска и стресса, важно заранее практиковать механизмы восстановления и убедиться, что:
- они сделают то, что вам нужно, чтобы они сделали
- вы знаете, как их делать
Тестирование механизмов восстановления имеет интересный побочный эффект снижения риска выполнения некоторых из этих действий. С тех пор, как этот беспорядочный сбой произошел, мы удвоили усилия по тестированию.
дополнение от @eabykov:
- Понизьте порог срабатывания алерта и зафиксируйте время реакции мониторинга
- Инструкции должны быть написаны простым и понятным языком, вплоть до "нажмите на зеленую кнопку"
Как-то раз мы хотели внести изменение в конфигурацию кэширования. Мы были довольно уверены, что это не приведет ни к чему плохому. Но довольно уверен -- это не 100% уверенность. Оказывается, кэширование было более важной функцией для YouTube, чем нам казалось, и изменение конфигурации имело некоторые непреднамеренные последствия, которые полностью парализовали сервис на 13 минут. Если бы мы провели канареечное тестирование этих глобальных изменений с прогрессивной стратегией развертывания, этот сбой мог бы не стать глобальным. Больше о канареечных релизах здесь и здесь.
В тот же промежуток времени, младший брат YouTube, Google Calendar, также пережил сбой, из которого мы извлекли следующие два урока.
4 Должна быть "большая красная кнопка" которая просто и быстро отменит изменения, которые привели к инциденту
"Большая Красная Кнопка" -- это уникальная, но в высокой степени практичная функция безопасности: она должна запускать простое, легко инициируемое действие, которое отменяет все вызвавшее нежелательное состояние. "Большие Красные Кнопки" бывают разных форм и размеров -- и важно определить, какими могут быть эти большие красные кнопки, прежде чем вы совершите потенциально рискованное действие. Мы однажды едва избежали крупного сбоя, потому что инженер, запустивший потенциально сбойное изменение, отключил свой настольный компьютер, прежде чем изменение могло распространиться. Так что при планировании ваших крупных релизов подумайте: Какая у меня большая красная кнопка? Убедитесь, что у каждой зависимости сервиса есть "большая красная кнопка", готовая для использования в чрезвычайной ситуации. Смотрите "Generic Mitigations" для дополнительной информации!
5 Проводить интеграционные тесты, наблюдая за тем, как наши изменения встариваются в общую архитектуру и взаимодействуют с другими компонентами
Ах.... unit tests. Они проверяют, может ли отдельный компонент выполнять то, что нам от него нужно. Модульные тесты воспроизводят намеренно ограниченный сценарий и очень полезны, но это означает и то, что они не воспроизводят среду выполнения. Поэтому мы большие сторонники интеграционных тестов! Мы используем интеграционные тесты даже для проверки холодного старта. Будут ли вещи работать так, как мы хотим? Будут ли компоненты работать вместе так, как мы хотим? Будут ли эти компоненты успешно создавать систему, которую мы хотим? Этот урок был получен во время сбоя Calendar, когда все то обилие тестов, что у нас было, никак не помогло оценить влияние изменений.
Из инцидента, который произошел в феврале 2017 года, мы извлекли следующие два урока:
Сначала недоступность OAuth привела к тому, что миллионы пользователей были разлогинены на устройствах и сервисах и 32000 устройств OnHub и Google WiFi провели сброс к заводским настройкам. Заявки на ручное восстановление учетных записей увеличились в 10 раз из-за неудачных попыток входа. Google потребовалось около 12 часов, чтобы полностью восстановиться после сбоя.
Да, это было плохое время. Знаете, из-за чего стало еще хуже? Команды ожидали, что смогут использовать Google Hangouts и Google Meet для управления инцидентом. Но когда 350 миллионов пользователей пытаются залогиниться на своих устройствах... опираться на эти сервисы Google, как выяснилось, было не лучшим решением. Убедитесь, что у вас есть резервные каналы связи, которые не зависят от вашей основной системы, и что вы их протестировали.
Затем тот же инцидент в 2017 году привел нас к лучшему пониманию graceful degradation:
Многие воспринимают доступность сервиса как что-то однозначное: он либо работает, либо нет. Однако способность обеспечить базовую функциональность даже при сниженной производительности позволяет предложить пользователям более стабильный и предсказуемый опыт использования. Именно поэтому мы тщательно разработали режимы работы с ограниченными возможностями, чтобы в критических ситуациях пользователи могли и не заметить проблемы (возможно, это даже происходит сейчас!). Важно, чтобы сервисы могли адаптироваться к сложившимся условиям, сохраняя при этом работоспособность.
- Следующий урок -- рекомендация убедиться, что ваша система последней линии защиты работает как ожидается в экстремальных сценариях, таких как стихийные бедствия или кибератаки.*
Помимо модульного тестирования и интеграционного тестирования, есть и другие очень важные виды тестирования: тестирование на устойчивость к катастрофам и тестирование на восстановление. Тестирование на устойчивость проверяет, могла бы ваша служба или система выжить в случае ошибок, задержек или нарушений, а тестирование на восстановление проверяет, может ли сервис вернуться к нормальной работе после полной остановки. Оба должны стать критичной частью ваших методов, как разъяснено в статье "Weathering the Unexpected". Полезно также может быть собрать вашу команду и проработать, как некоторые из этих сценариев могли бы теоретически разыграться -- в стиле настольной игры. Это также может быть веселой возможностью исследовать те ужасающие "Что если". Например, "Что если часть вашей сетевой связи внезапно отключится?".
В марте 2023 года серия сбоев сетевых устройств в нескольких дата-центрах привела к ощутимой потере пакетов. Этот шестидневный инцидент затронул порядка 70% сервисов, в зависимости от их местоположения, нагрузки и конфигурации в момент сбоя сети.
В подобных ситуациях можно сократить время на восстановление (MTTR), автоматизировав процессы, которые обычно выполняются вручную. Если есть точно известно, что происходит конкретный сбой, то почему нельзя что-то запустить автоматически? Иногда лучше использовать автоматику как средство первой очереди и оставить поиск первопричины на время после инцидента.
В марте 2022 года, из-за сбоя в системе платежей, пользователи не могли совершать покупки, что вынудило перенести игровое событие в Pokémon GO. Сбой был вызван удалением поля в базе данных, которое, как предполагалось, больше не использовалось. Но медленное обновление части системы привело к тому, что в реальной работе это поле всё еще требовалось.
Задержки между обновлениями в сложных системах могут серьезно затруднить оценку безопасности изменений. Частые развертывания, подкрепленные надлежащим тестированием, помогают избегать подобных сюрпризов.
11 Альтернативное решение для критически важных систем, которое их заменит в случае если в основной системе инцидент (Одна глобальная версия оборудования означает одну общую точку отказа)
Наличие одной определенной модели устройства для важных функций упрощает обслуживание. Но что если эта модель вдруг даст сбой?
В марте 2020 года неожиданное изменение сетевого трафика выявило скрытый баг "нулевого дня" в сетевом оборудовании. Поскольку вся сеть работала на той же модели и версии, произошел региональный сбой. Спасло ситуацию только наличие нескольких запасных магистралей, благодаря которым срочный трафик смогли перенаправить по работающему маршруту.
Скрытые неполадки могут долго оставаться невидимыми, пока какое-то малейшее изменение их не обнаружит. Разнообразие в инфраструктуре, хоть и требует дополнительных затрат, способно предотвратить полный сбой.
Итак, вот они! Одиннадцать уроков, приобретенных за два десятилетия инженерии надежности сайтов в Google. Почему одиннадцать? Ну, видите ли, Google Site Reliability, со всем нашим богатым опытом, все еще на пике.