DNS и путь запроса

Что это такое

DNS — это распределённая система имён, отображающая имя, например имя внутреннего сервиса, в IP-адрес. Устроена она как иерархия серверов, каждый из которых отвечает за одну часть имени, а поверх идёт обильное кэширование, которое удерживает трафик в разумных рамках. Как только имя разрешено, запрос проходит по цепочке шагов — поиск имени, установка соединения, согласование протокола, запрос, ответ, — и каждый шаг добавляет круговой обход, прежде чем двинутся полезные байты.

Почему это важно

Разрешение имён — самый часто забываемый источник задержки и самый часто забываемый источник отказов. Кэш DNS с долгим сроком жизни продолжает слать трафик на машину, которую вы давно вывели из эксплуатации, а медленный резолвер задерживает каждое новое соединение вашего сервиса. Результат кэшируется, поэтому проблема часто всплывает только при холодном старте или после развёртывания, — и выглядит оттого случайной. Подсчёт шагов превращает «сеть медленная» в число, привязанное к шагу.

Ключевые идеи

Имя читается справа

Имя устроено как путь по иерархии, который читают справа налево. Самая правая метка — домен верхнего уровня, дальше идёт домен организации, а затем поддомены. У каждого уровня есть авторитативные серверы, которые указывают на уровень ниже, и ни один сервер не знает все имена — именно поэтому система и может расти без центральной копии.

api.internal.example.com
  com            -> серверы реестра .com
  example.com    -> авторитативные серверы example
  internal.example.com -> внутренняя зона
  api.internal.example.com -> запись, которую вы запросили

Разрешение один раз проходит иерархию, затем кэширует

Резолвер спрашивает сверху вниз и кэширует каждый ответ на срок жизни записи. Первый поиск может занять несколько круговых обходов, а каждый поиск внутри этого срока не стоит ничего. Отсюда и то, что изменение записи видно не везде сразу: разные резолверы держат старый ответ, пока их копия не истечёт. Короткие сроки распространяют изменения быстро и повышают нагрузку запросов, долгие — наоборот.

первый поиск:  клиент -> резолвер -> корень -> com -> example -> ответ
поиск из кэша: клиент -> резолвер -> ответ          (без сети)

Путь запроса — это последовательность круговых обходов

Между набором имени и чтением ответа последовательно происходит несколько разных шагов. Имя должно разрешиться, транспортное соединение — установиться, любое рукопожатие безопасности — завершиться, а прикладной протокол затем отправляет запрос и ждёт первый байт. Каждый шаг обходится как минимум в один круговой обход через расстояние между клиентом и сервером.

разрешить имя           (0-n круговых обходов, 0 из кэша)
открыть соединение      (1 круговой обход)
рукопожатие безопасности (1-2 круговых обхода)
отправить запрос        (1 круговой обход до первого байта)

Расстояние задаёт нижнюю границу

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

Кэш есть на каждом слое

Браузер кэширует ответы, операционная система кэширует их, резолвер кэширует их тоже, а сервисная сетка может закэшировать ещё раз. Каждый кэш держит копию ровно столько, сколько объявлено в сроке жизни записи. При отладке практический вопрос звучит не «что говорит DNS», а «что считает слой, с которым говорит мой код, и когда он это узнал».

Практика

Проследите имя вручную

Спросите у резолвера имя и прочтите срок жизни ответа. Спросите у публичного резолвера то же самое имя и сравните, затем повторите сразу же и отметьте, какие поиски ушли в сеть.

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

Замерьте каждый шаг запроса

Возьмите один URL, который вызывает ваше приложение. Запишите время на разрешение имени, на соединение, до первого байта ответа и общее.

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

Частые ошибки

  • Убеждение, что изменение DNS вступает в силу немедленно — каждый резолвер, у которого есть ответ, держит его до истечения срока; исправить: понижайте срок задолго до запланированной миграции.
  • Разрешение имени на каждый запрос — каждое новое соединение платит за поиск, который убрал бы кэшированный результат; исправить: держите соединение открытым или разрешите имя один раз и переиспользуйте адрес.
  • Путаница кэшированного ответа с авторитативным — отладка против кэша даёт устаревший результат, который выглядит текущим; исправить: запрашивайте авторитативный сервер, когда ответ важен.
  • Игнорирование рукопожатия при подсчёте стоимости запроса — запрос, измеренный десятками миллисекунд, состоит в основном из установки; исправить: разделите фазы и атакуйте круговые обходы, а не нагрузку.
  • «Сеть медленная» как одна проблема — разрешение, соединение, рукопожатие и передача отказывают и замедляются по-разному; исправить: измеряйте фазы по отдельности, прежде чем что-то менять.

Что читать дальше