SRE · Подготовка к собеседованию
Вопросы на собеседовании SRE: короткие ответы
Короткий ответ из каждого урока линии — тот же текст, что в уроке, только без подписи «Короткий ответ:», — и вопросы из его раздела «Дальше спросят». Ответы на эти вопросы, механизм и замеры, на которых всё это стоит, — в уроке по ссылке.
01
Сигналы и PID 1
У процесса с номером 1 в своём пространстве имён умолчательные действия сигналов не выполняются, поэтому
SIGTERMбез обработчика для него не делает ничего — оркестратор ждёт весь льготный срок и добиваетSIGKILL, а в отчёте остаётся код 137, то есть 128 + 9. Зомби при этом — не процесс, а запись о его смерти: она держится ради кода выхода и занимает слот в таблице процессов, а убирает еёwait, а не время.Дальше спросят
02
cgroups и OOM
Лимит памяти ставится группе процессов, и когда потребление упирается в него, ядро сначала пытается освободить память внутри группы, а если не выходит — убивает одного из её процессов сигналом
SIGKILL. Поэтому в логе приложения пусто, а снаружи видно 137 — это128 + 9. Потребление при этом за лимит не улетает: в измеренном прогоне пик группы дошёл ровно до лимита и остановился.Дальше спросят
03
Лимит дескрипторов
EMFILE— это лимит на число дескрипторов конкретного процесса, и считаются в нём не файлы, а все открытые объекты — сокеты, каналы,epoll, плюс три, которые процесс получил при рождении. Лимитов два: мягкий ядро проверяет при открытии очередного дескриптора, а жёсткий ограничивает то, насколько высоко процесс может поднять себе мягкий, — и поднять мягкий он может сам, без перезапуска.Дальше спросят
04
Page cache и fsync
writeдоводит данные только до кеша ядра и возвращается; долговечность обещаетfsync, и стоит она на два порядка дороже. Поэтому падение процесса не теряет записанного — кеш принадлежит ядру, — а при потере питания всё несброшенное может быть потеряно.Дальше спросят
05
Очередь accept
Между
connectклиента иacceptсервера стоит очередь ядра, и соединение в ней уже установлено — договорённость провело ядро, а не приложение. Поэтому занятый сервер выглядит для клиента работающим, а при переполнении очереди клиент получает не отказ, а таймаут: пакет молча отбрасывается, и TCP его повторяет.Дальше спросят
06
Таймауты и дедлайны
Таймаут ограничивает ожидание вызывающего и ничего не сообщает исполнителю, поэтому работа продолжается после ухода клиента; дедлайн — это точка во времени, которая едет вместе с запросом, и по ней исполнитель может отказаться, не начиная. Измерено на цепочке из трёх сервисов: без бюджета работу довели до конца все три сервиса; с бюджетом первый закончил работу, второй отказался до начала, а третий вообще не был вызван.
Дальше спросят
07
Ретраи и джиттер
Повтор запроса усиливает нагрузку в момент отказа, а одинаковое расписание повторов синхронизирует её в пик после восстановления. Поэтому нужны две разные вещи: экспоненциальная выдержка — чтобы повторов было меньше, когда неудачи повторяются, — и джиттер, чтобы клиенты вернулись не одновременно. В модели этого урока джиттер снизил пик в сто раз, но отодвинул момент, когда обслужены все, с 3100 мс до 13 290.
Дальше спросят
08
Graceful shutdown
Graceful shutdown — это два действия по порядку: перестать принимать новые соединения и доработать уже принятые; и работает он только потому, что
SIGTERMперехватывается. Измерено на одном и том же сервере под одинаковой нагрузкой: без обработчика оборвано 20 запросов из 20, с дренажем — ноль, а цена дренажа — 164 мс против 2, то есть остаток уже начатой работы.Дальше спросят
09
Очередь и хвост
Время в системе — это обслуживание плюс ожидание, и с ростом загрузки растёт ожидание, а не обслуживание. Поэтому зависимость непропорциональна: в модели рост загрузки с 0,80 до 0,95 — это плюс 19 %, а время выросло в 4,1 раза при неизменных 10 мс работы на запрос.
Дальше спросят
10
SLO и бюджет
SLO — это цель по метрике плюс окно, а бюджет ошибок — то, сколько плохого эта цель разрешает в этом окне; считается он в тех же единицах, в которых считается сама метрика. 99,9 % за 30 дней при 1000 запросов в секунду и доступности, считаемой по запросам, — это 2 592 000 неуспешных запросов, что при полной недоступности равно 43,2 минуты; те же 99,9 % за сутки — 1,4 минуты.
Дальше спросят
11
Health-checks
Проб три, и различаются они последствием — liveness перезапускает, readiness выводит из ротации, startup откладывает liveness на время запуска. Поэтому вопрос liveness звучит не «жив ли процесс», а «поможет ли перезапуск этого процесса»: внутрь пробы попадает только то, что чинится перезапуском, а зависимости — в readiness.
Дальше спросят
12
Выкатка и откат
Ущерб от плохой выкатки зависит от того, сколько трафика и как долго обслуживает дефектная версия, и от тяжести дефекта, а не от названия стратегии. При постоянных потоке и долях число испорченных запросов — это поток × доля трафика на новой версии × доля запросов, которые ломает дефект, × суммарное время воздействия, а время до тревоги, решение и откат в этом времени складываются. Поэтому канарейке нужен детектор, способный заметить проблему на маленькой выборке: в модели урока та же канарейка задела 645 запросов при детекторе, ждущем 200 ошибок, и 29 при детекторе по доле ошибок — разница в 22 раза.
Дальше спросят
13
Разрешение имени
Приложение обычно зовёт не DNS, а системную функцию разрешения имён (
getaddrinfoв Linux), и та идёт по источникам в порядке изnsswitch.conf— часто сначала файл/etc/hosts, потом сервер имён. Поэтому ответ может прийти вообще без сети, а длительность этого шага задают настройки резолвера: в замере урока ненайденное имя стоило 12,0 секунды. Ограничит ли её таймаут клиента, зависит от API: таймаут сокета, поставленный после резолва, как уsocket.create_connectionв Python, блокирующий резолв не покрывает, а дедлайн на весь вызов покрывает —net.DialTimeoutв Go включает разрешение имени в свой бюджет.Дальше спросят
14
TLS-рукопожатие
Рукопожатие стоит не работой процессора, а кругами — полётами до сервера и обратно, — и платится оно один раз за соединение, а не за запрос. Сколько именно кругов, зависит от версии: TLS 1.3 — один, TLS 1.2 — два. Измерено на звене с известным кругом: 43,6 мс против 84,7 мс при полном рукопожатии. Поэтому «первый запрос медленный» лечится переиспользованием соединения, а не отключением шифрования.
Дальше спросят
15
TIME_WAIT и порты
TIME_WAIT— нормальный конец соединения, а не утечка. Закрывшая сторона ещё некоторое время держит свою пару адрес-порт, чтобы задержавшиеся сегменты старого соединения не были приняты новым соединением с теми же адресами и портами. Проблемой это становится у клиента, который открывает соединение на каждый запрос: у него кончаются не память и не дескрипторы, а номера портов. Измерено: при диапазоне в 50 номеров ровно 50 соединений иEADDRNOTAVAILна пятьдесят первом.Дальше спросят
16
Балансировка
Круговой перебор раздаёт поровну число запросов, а не работу, поэтому он проигрывает, как только запросы неоднородны. Опрос двух случайных серверов забирает заметную часть выигрыша полного опроса, но его цена не растёт с размером парка. Модель: p99 ожидания 582,4 мс у кругового перебора, 123,6 у опроса двух и 42,9 у опроса всех.
Дальше спросят
17
Консистентное хеширование
Деление по модулю привязывает владельца ключа к числу узлов, поэтому любое изменение состава пересчитывает всё; кольцо привязывает владельца к позиции ключа, поэтому меняются только ключи рядом с изменением. Посчитано на 100 000 ключей: добавление девятого узла к восьми переносит 88,9 % ключей при модуле и 11,5 % на кольце с одной точкой на узел.
Дальше спросят
18
Идемпотентность
Доставку ровно один раз гарантировать нельзя, а эффект — можно. Клиент порождает ключ на операцию, сервер под этим ключом занимает место до работы и хранит ответ, и любой повтор получает тот же ответ вместо второго эффекта. Измерено: четыре повтора без ключа — четыре эффекта, с ключом — один.
Дальше спросят