SRE. Рецепты выживания в продакшене для инженера по надежности
Об управлении надежностью
«Управление надежностью похоже на искусство капитана на корабле: предсказываешь штормы, избегаешь подводных камней и сохраняешь хладнокровие в нестандартных ситуациях. Так корабль плывет безопасно и плавно.
Ненадежный корабль не завоюет доверие пользователей и не обеспечит конкурентоспособность компании. Управлять надежностью сервиса – обязанность каждого капитана сервиса и компании».
Александр Тармолов, руководитель отдела разработки международных веб-решений в Яндекс Картах
«Ошибки в коде и проблемы неизбежны. Очень неприятно и стрессово смотреть на то, как после релиза твой сервис постепенно (или моментально) падает. Но еще хуже, когда в этот момент у тебя нет плана действий и ты просто наблюдаешь, не в силах что-то сделать.
Но если к таким ситуациям правильно готовиться – можно заранее понять, что что-то идет не так, и не довести до падения. Либо снизить влияние на пользователей (можно даже так, что они особо ничего не заметят) и быстро все починить (а для этого нужны инструменты, планы действий для таких ситуаций).
Стресс все равно будет, но гораздо лучше рассказывать коллегам байки за бокалом пенного, как мы героически всех спасли, чем ужасы, как лежали часами и потеряли много лояльных пользователей».
Николай Животворев, руководитель клиентской разработки в Okko (в прошлом – Дзен, Яндекс. Эфир, главная Яндекса)
«Управление надежностью начинается не с конкретных процессов или систем, а с построения принципов работы команды разработки. Особенно это проявляется в Data-Driven направлениях, где дата-инженерам куда проще следить только за надежностью напрямую контролируемых ими ETL-процессов, чем за всей системой целиком, включая поставляемые другими отделами данные. Именно выстраивание принципов команды (как мы работаем, как мы считаем неприемлемым работать, как мы контролируем качество работы смежников, какое качество сервиса мы хотим дать своим пользователям) является основой для построения надежного и полезного для компании продукта».
Максим Пчелин, продакт-менеджер аналитической платформы Nebius (в прошлом – Яндекс, Mail.Ru)
«Информационный продукт появляется на свет как ребенок с иммунитетом, заложенным родителем. Но по мере роста и развития иммунитет нужно тренировать, делать прививки в виде учебных встрясок, интегрировать в себя «ДНК» реальных инцидентов и накапливать ресурсы для столкновения с реальным миром во всем его многообразии. И пусть иммунитет не дает 100% защиты от болезней, но “то, что нас не убивает, делает нас сильнее”, и в конечном счете эволюционную гонку выигрывает наиболее подготовленный организм».
Сергей Савенков, руководитель отдела front-end разработки управления развития розничных систем ООО «МерлионТех»
«Если вы не управляете надёжность своего сервиса – значит, нет у вас никакого сервиса.»
Андрей Столбовский, руководитель разработки в AWS (в прошлом – Яндекс, Вконтакте)
Что внутри
Здравствуй, читатель! Я Наташа, и я инженер. Двадцать лет работаю в IT, и мой путь начинался, как у многих соответствующих специалистов того времени, с веб-мастера, а интернет тогда подключался по телефонному проводу. Моя история опыта в индустрии крутится в основном вокруг бэкенда и инфраструктуры.
На первой серьезной работе я участвовала в создании интернет-магазинов, поэтому понятие надежности систем довольно быстро вошло в мою жизнь: если торговая онлайн-площадка не функционирует, то компания не может обслуживать заказы, а у владельца прекращается поток денег. Для таких бизнесов IT-система – это в прямом смысле сердце. С тех пор мир поменялся очень круто, и такое электронное «сердце» теперь есть, пожалуй, у всех.
В 2015 году я устроилась разработчиком в крупную компанию, и там стало очень быстро понятно: если у такой фирмы «лежит» ее главный сайт, то об этом сразу пишут в новостях. Это очень смешанные чувства: ответственность и гордость одновременно. В мире начал набирать популярность подход Site Reliability Engineering, в наш отдел добавили админов, которые сели за соседний стол… и надежность стала моим главным профессиональным интересом.
Что нужно знать о надежности:
– это не бесплатно
– это про готовность заниматься системой в любой момент
– это для педантичных
– это про постоянное извлечение уроков и изучение ошибок
Мир IT как будто развивается очень быстро, но фундаментально за 20 лет мало что изменилось. Новые языки программирования каждый год, облачные технологии, serverless, zero-code, ML, базы данных и еще много всего нового, но внутри все те же сервера с процессорами, каналы связи, дата-центры и экскаваторы, которые неловким движением перерубают кабели в земле.
В этой книге собраны мои правила и рецепты, накопленные за все время работы инженером по надежности. В случае актуальности я добавляла что-то про деньги. В конце концов, мы делаем IT-систему для бизнеса, а он всегда про них.
Рецепты в основном рассчитаны на крупные системы, но и для небольших здесь тоже есть что-то полезное. Никакой логики в порядке глав тут нет. В книге много сленга, и она рассчитана на инженеров с опытом.
Основано на реальных событиях. Приятного чтения!
1. Сервис без вмешательства не переживает отключение части свитчей в дата-центре – это плохой сервис
Пришли к нам как-то сетевые инженеры из дата-центра и говорят: «Нам нужно провести работы, для этого мы выключим пару свитчей, запланируйте у себя мероприятия». Обычно в таких ситуациях мы начинали какой-то трафик куда-то переключать, чтобы точно все хорошо прошло, а тут пообсуждали с коллегами и решили, что это неправильная ситуация и лучше мы посмотрим на последствия, а потом что-то улучшим. Всю систему оставили работать в обычном режиме, подготовились к «чему угодно» и стали наблюдать. Все прошло хорошо. С тех пор мы договорились, что в подобных случаях ничего сами трогать не будем, потому что система должна справиться сама.
Деньги:
Если система сама не сумела, то нужно оценить масштаб последствий для бизнеса, варианты ее улучшения и принять решение об инвестициях в один из них. Допустимо оставить как есть, если улучшения будут стоить неоправданно дорого.
2. Если какую-то процедуру делать страшно – делайте ее чаще
У каждого инженера по надежности или администратора системы есть набор нелюбимых манипуляций, которые делать страшно, но все равно иногда приходится. Я выработала для себя правило: если у меня есть такая процедура, то мне самой нужно ее просто регулярно повторять, чтобы она становилась привычной.
Почему это важно. У каждого из нас разная реакция на стресс: бей-беги-замри. Он запускается, когда что-то сломалось. А когда нужно во время этого сломанного провести нелюбимую манипуляцию, то стресс увеличивается.
История: как-то в моем хозяйстве имелась кластеризованная база данных. В ее работу вообще вмешиваться неуютно, но иногда (редко) надо было отключать некоторые из ее нод. Очень неприятная процедура. Но я сделала ее плановой: раз в месяц проверяла, что отключение правильно работает, а заодно и повышала свой уровень комфорта от этого занятия.
3. Если мониторинг не пишет о проблемах – проверьте, возможно, он не работает вообще
На серверах лежат файлы, а у тех есть права доступа. В этом смысле в мире не поменялось ничего. Мониторинг часто устроен так, что просто читает заданные файлы с логами.
Как-то мы переезжали с одних серверов на другие, и что-то пошло не так с правами доступа на файлы логов сервиса бэкенда. В результате на некоторых серверах бэкенд не мог писать свои логи. Нет логов – нет проблем. Мониторинг читал пустые файлы, не находил там никакой тревожной информации и всегда показывал «все в порядке». В это время на машинке оставался необновляемый код, а пользователь, попадающий запросами на эти сервера, видел вообще нечто очень странное. Нашли мы это случайно, к сожалению.
Отсюда следует: если мониторинг настроен по правилу «нет ошибок – нет проблем», то его стоит дополнить проверками, показывающими, что система действительно работает, как задумано.
4. Регулярно проверяйте все редко используемые аварийные средства доступа
В работе ответственного админа есть не только основные рабочие средства, но и запасные. Резервные интернет и ноутбук, еще разные способы, типа возможности залогиниться на сервер с телефона или загрузочной флешки для компьютера друга.
Если запасными средствами не пользоваться, то рано или поздно они перестанут работать. Такова их судьба. Поэтому важно регулярно проверять, что они до сих пор функционируют и могут быть использованы в критической ситуации.
Например, можно сделать себе напоминание – раз в две недели «проверить резервные средства» и там описать все, что нужно проверить: резервный интернет оплачен и работает, резервный ноутбук загружается, и с него можно зайти во все необходимые системы, и так далее.
5. Ходить на чужие разборы полезно
Во многих компаниях есть процесс публичного разбора крупных инцидентов (поломок). Это прекрасная практика, хотя и малоприятная для самих выступающих и участников. Задача разбора – сгенерировать с помощью большого числа инженеров меры предотвращения таких поломок в будущем, заодно помочь другим избежать подобного.
Если у вас в компании есть такое мероприятие – ходите туда и учитесь на кейсах своих коллег. Не надо ждать, когда случится инцидент именно у вас. Уникальных проблем поистине мало, а способов их предотвращения еще меньше. Изучайте, что случилось у других, анализируйте свою систему и выбирайте то, что разумно реализовать в ней заранее.
Если такого процесса не существует, то подумайте над тем, чтобы он появился.
6. Если результаты нагрузочного тестирования всегда одинаковые – это плохо
Если вы уже выкатываете релизы автоматически и в процессе выкатки есть стадия нагрузочного тестирования, то этот рецепт – для вас.
В нашем релизном процессе был шаг выкатки на тестовый стенд, на который выкатывается сборка и нагружается трафиком. Чтобы сильно не задерживать релизный процесс, мы выставили довольно высокое стартовое значение нагрузки по принципу «ну, столько наш бэкенд точно выдержит всегда». Затем система плавно увеличивала трафик. По мере его повышения стенд переставал отвечать на запросы, тестирование завершалось, а последнее успешное значение трафика принималось за результат нагрузочного тестирования. Если результат был допустим, то релиз выкатывался дальше в продакшн.
Долгое время наш результат тестирования был более-менее стабильным. Потом добавили немного логики, потом еще немного, потом еще… А он продолжал оставаться таким же, и релизы выкатывались в продакшн. Пока кто-то не пошел зачем-то посмотреть результаты тестирования своими глазами…
Что произошло на самом деле: по мере добавления новой функциональности и деградации производительности уровень допустимого трафика на стенд постепенно падал и упал ниже заданного стартового значения. В итоге тестирование заканчивалось сразу же, как только начиналось, потому что стенд обслуживал несколько запросов и сразу же отваливался, а в результаты просто записывалось то самое стартовое значение. За это время производительность бэкенда снизилась на 50%, но об этом никто не знал.
Как стоило бы поступить:
– начинать нагрузку трафиком с нулевого значения, но это сильно замедляет процесс релиза, и для кого-то это может быть принципиально
– создать параллельный процесс полного нагрузочного тестирования, чтобы не задерживать релизы
– считать тестирование успешным в случае, если финальное значение трафика отличается от стартового
– вычислять долю успешных и неуспешных ответов от стенда
7. Регулярно проверяйте всю редко используемую автоматику
Одним из основных принципов SRE является проактивное управление системами, что означает создание автоматических систем для защиты от инцидентов и поломок разного рода.
Вот несколько примеров таких автоматик:
– включение фильтрации трафика при срабатывании каких-то условий
– автоскейлинг ресурсов при росте нагрузки
– подключение кеширующих прокси
– отключение незначимых компонентов системы при пиковой нагрузке
– снижение скорости передачи данных
– увеличение времени ответа
– …
Список вариантов большой, но смысл понятен.
Что важно: речь идет об автоматике, включающейся при некоторых условиях. То есть речь идет о редких ситуациях. И это означает, что механизмы должны работать безотказно. Как огнетушитель в вашем деревянном загородном доме с дровяной печью: если случится так, что он пригодится, то лучше, если он будет исправен.
Всю такую автоматику необходимо регулярно проверять! Составьте себе расписание учений и протоколы проверки всех автоматик, на которые вы полагаетесь для обеспечения высокого качества своего сервиса в критических ситуациях.
В ходе этих регулярных проверок вы сможете обнаружить:
– изъяны или слабые места до того, как они проявятся в результате реальных инцидентов;
– изменения окружающей среды: по мере развития сервисов и инфраструктуры защитные механизмы могут потребовать корректировки или вообще перестать работать;
– несоответствия требованиям аудита;
– неполадки в работе системы мониторинга и оповещений;
– отсутствие необходимых доступов
– … и еще много всего.
Кроме того, участие в тестировании автоматики – это хороший способ онбординга новичков в команде.
Каждая проверка – это возможность узнать больше о системе и о том, как она ведет себя в различных условиях, что в итоге помогает усовершенствовать защитные механизмы.
Деньги:
Тут крайне важно соблюдать баланс между «давайте подготовимся заранее к чему угодно и будем оберегать наш хрустальный дворец» и «не делаем вообще ничего». Если вы не создаете систему жизнеобеспечения, не управляете ракетами и прочими критическими системами, то будет достаточно:
– проанализировать систему на предмет основных рисков
– оценить потери в результате реализации рисков
– спроектировать средства защиты
– оценить стоимость их реализации и поддержки
– применить здравый смысл и выбрать, куда потратить свои деньги
8. Рандомизируйте учения
В прошлой главе было много слов про важность проверки систем и про соответствующие протоколы. Так вот, назовем эти проверки учениями.
У любых учений есть два недостатка. Первый, главный: они далеки от реальной катастрофы. Второй: они проводятся по протоколу.
К сожалению, если на учениях выявилась какая-то проблема у какого-то сервиса, то ее устранение означает только то, что сервис научился переживать сценарий учений. Это вовсе не значит, что если начать отключать что-то в другом порядке, то все будет хорошо. И уж тем более – что авария будет проходить по сценарию учений.
Вносите разнообразие в учения. Регулярно меняйте протоколы и форматы.
Изменение последовательности действий во время учений повышает шансы того, что отдельные люди и команды действительно понимают лежащие в основе принципы и готовы реагировать на неожиданные ситуации.
Вот несколько способов внести разнообразие:
– использовать генератор случайных чисел, где это применимо
– применять вариации: например, проводить учебные проверки в разное время суток
– вместо одного сценария представлять варианты, когда различные компоненты выходят из строя в разном порядке или возникают несколько проблем одновременно
– менять членов команды ролями во время учений, это не только изменит динамику, но и покажет проблемы в навыках
– менять порядок шагов в сценарии учений, чтобы увидеть, как участники адаптируются, смогут ли они по-прежнему эффективно решать возникающие проблемы, и каким будет поведение всей системы
9. Проектируйте failover смолоду
Если у сервиса есть хоть какой-то шанс получить статус «должен работать примерно всегда», то лучше начинать думать о надежности сразу. Сами процессы стоит проектировать реентерабельными – рассчитанными на перезапуск, параллельный запуск и какой угодно другой запуск и работу. Лучше сразу предполагать, что любая часть проекта может выйти из строя, и резервировать ее, если без нее нельзя обойтись. Во-первых, система сразу будет более-менее устойчивой, а во-вторых – более масштабируемой.
Сделайте визуальную схему всей системы и спроектируйте меры повышения надежности.
Деньги:
Резервирование системы увеличивает ее стоимость не в два раза, а существенно больше, так как для управления резервными схемами требуются инструменты координации.
Как и в случае с рецептом про автоматику, здесь целесообразно оценить последствия отказа конкретных компонентов, посчитать стоимость их резервирования и систем координации. Только после этого принимать решение о создании запасного варианта.
10. Мониторинг трафика в диапазоне
Каждый раз, когда пользователь взаимодействует с приложением / веб-сайтом, отправляя данные или выполняя поиск, сервер получает запросы для обработки этих действий и предоставления информации. Это то, что мы в быту называем словом «трафик».
Мониторинг трафика важен по нескольким причинам:
– ранняя диагностика проблем
– контроль использования ресурсов
– управление производительностью
– потребности в локальном масштабировании
– планирование будущего роста
– контроль затрат
Это не полный список причин.
Трафик может количественно меняться двумя способами: резко и плавно. Также он зависит от сезона, дня недели, времени суток, событий в мире и т. п. Нет такого единственного абсолютного значения, отклонение от которого нужно считать проблемой, всегда есть диапазоны и колебания.
Для таких случаев используется комплексный мониторинг: по абсолютам и по тренду. У них разный принцип работы.
Мониторинг по абсолютному значению
Нужен мониторинг абсолютного значения и сверху, и снизу. Это может быть очень широкий диапазон, потому что верх определяют по максимуму, в дни высокого трафика, а низ – по минимуму, в дни низкого. Необходимо изучить свою динамику трафика за достаточно большой период и на основании нее выбрать абсолютные значения.
Важно понимать, что если случится внезапный рост трафика в дни, когда он обычно низкий, то из-за ширины диапазона этого можно не увидеть, ведь значения останутся в зоне нормы. Для этого нужен другой мониторинг.
Мониторинг по тренду
Этот вид мониторинга предполагает некоторое накопление данных, и есть множество алгоритмов его работы: сравнение текущего уровня трафика с типичным для этого дня недели, накопление пятиминутных значений и сравнение их между собой… Здесь каждый сам выбирает нужный ему алгоритм, исходя из доступных технических средств и ситуации.
Важно понимать: если трафик растет или, наоборот, падает достаточно медленно (в течение суток или недели, например), то мониторинг по тренду может не сработать – рост или падение будет слишком плавным. Здесь как раз поможет мониторинг по абсолютным значениям, который может сработать не так быстро, но лучше когда-нибудь, чем никогда.
К сожалению, обычно мониторят только рост трафика, потому что боятся за нагрузку и работоспособность системы, но его падение не менее важно: без трафика нет пользователей, а без них – нет денег. Его спад может указывать на проблему с доступом, в частности связанную с DNS, истекший срок действия SSL-сертификатов или неработающая функциональность интерфейса, которая не позволяет пользователям выполнять запросы и решать свои задачи, выпуск новой версии и еще куча разных причин. Но обычно падение трафика не говорит вообще ни о чем хорошем.
Поэтому рецепт такой: трендовый мониторинг делать для нахождения отклонений в типичном поведении, а пороговый – для крайних случаев, когда трендовый не способен определить отклонения. То есть мониторить следует не только рост трафика, но и падение.
11. Мониторинг среднего и min/max
В системах, где много серверов / узлов / нод (выберите любую единицу своей системы), невозможно мониторить каждую единицу. Поэтому для мониторинга значений создают агрегаты: перцентили, медианы и т. п. То есть некоторое «среднее по больнице». Это разумный подход, но есть нюанс: обычно имеются единичные отклонения, которые в агрегате будут незаметны.
Проблема может быть на одном хосте из сотни, но вы о ее существовании не узнаете. «Это же всего один хост», – скажут многие. Какая разница – он может быть не «одним», а «первым» в череде выхода из строя целой группы. Это совершенно разные ситуации.
Для такого случая полезно иметь мониторинг хотя бы на минимальное и на максимальное значения, либо использовать 95-ю, 99-ю перцентиль и ее другие виды.
Например, если вы мониторите среднее время ответа и используете его для управления масштабированием, то имейте в виду: половина запросов будет работать дольше этого среднего. Тут возникает очень важный вопрос: а насколько дольше?
В общем, вот что нужно сделать для улучшения ситуации:
– разобраться с перцентилями: что это такое, о чем они говорят