Страница поддержки любого хостинг-провайдера говорит какую-то версию одного и того же: «изменения DNS могут распространяться от 24 до 48 часов».
Это один из самых живучих кусков дезинформации в сетевых технологиях. Не потому, что время всегда неверно — иногда это действительно занимает так долго — а потому, что созданная им ментальная модель абсолютно неверна, и именно эта неверная модель заставляет людей часами отлаживать несуществующие проблемы, пропуская настоящие.
DNS не распространяется. Ничего не расходится наружу. Нет никакой волны обновлений, разбегающейся по интернету. Как только вы поймёте, что происходит на самом деле, время становится предсказуемым, управляемым и обычно намного быстрее 48 часов.
То, о чём никто не говорит: ваше изменение уже действует
Когда вы обновляете DNS-запись, авторитетный сервер — реальный источник истины для вашей зоны — получает новое значение практически мгновенно. В зависимости от провайдера, перезагрузка зоны может занять несколько секунд, или минуту — распространение на вторичные серверы через зональный трансфер. Но она уже действует. Прямо сейчас. Вы можете пойти и запросить её, и увидеть новое значение.
Так почему же остальной мир всё ещё видит старое?
Потому что никто не спрашивает авторитетный сервер. Все спрашивают резолверов, а резолверы помнят.
Когда резолвер запрашивал вашу запись десять минут назад, он сохранил ответ в памяти вместе с обратным отсчётом — TTL, время жизни, которое вы установили на записи. Пока этот отсчёт не дойдёт до нуля, резолвер будет выдавать уже имеющийся у него ответ, ни у кого не спрашивая. Он не ленится и не сломан. В этом и заключается весь дизайн DNS: агрессивно кэшировать, чтобы интернет не рухнул под тяжестью постоянных повторных запросов одного и того же.
Так что изменение не распространяется наружу. Старые ответы истекают — независимо, в разные моменты, в миллионах отдельных кэшей, каждый из которых начал свой обратный отсчёт в разное время.
Почему одни видят это, а другие нет
Вот та часть, которая заставляет «распространение» казаться реальным, и это просто арифметика.
Допустим, у вашей записи TTL один час, и вы меняете её в полдень.
- Резолвер, закэшировавший старое значение в 11:10, имеет десять минут в запасе. Он покажет новое значение в 12:10.
- Резолвер, закэшировавший его в 11:59, имеет пятьдесят девять минут в запасе. Он покажет новое значение в 12:59.
- Резолвер, который вообще никогда её не запрашивал, спросит авторитетный сервер в тот момент, когда кто-то его запросит, и мгновенно получит новое значение.
Три резолвера, три совершенно разных момента переключения, одна запись. Ничего никуда не распространилось. Каждый кэш просто истёк, когда закончился его собственный таймер.
Именно поэтому проверка вашей записи из разных сетей даёт противоречивые ответы, и именно поэтому ваш телефон на мобильных данных видит новый сайт, а ноутбук в офисном wifi — нет. Они общаются с разными резолверами с разным возрастом кэша. Запуск проверки распространения через резолверы в разных сетях показывает это напрямую — и полезный вывод не в том «насколько далеко продвинулось», а в самом расхождении. Смесь старых и новых ответов означает кэширование. Единообразно старые ответы везде, включая резолверы, у которых не должно было быть кэша, означают, что ваше изменение на самом деле не опубликовалось.
Максимальное ожидание — это ваш TTL. Не 24 часа, не 48. Если ваш TTL — 300 секунд, худший случай — пять минут. Вот и всё правило.
Тогда откуда берутся «48 часов»?
Это не совсем выдумка — это происходит из реальной вещи, которую затем применяют не к той ситуации.
Есть два разных вида изменений DNS, и они ведут себя совершенно по-разному:
Изменение записи внутри вашей зоны (A-запись, CNAME, MX). Это регулируется вашим TTL, который вы контролируете. Установите его в 300, и изменения занимают пять минут.
Изменение ваших серверов имён у регистратора. Это изменение делегирования, и оно живёт в зоне TLD, а не в вашей. Вы не контролируете этот TTL — это делает реестр. Для .com NS-записи в зоне TLD несут TTL 172800 секунд. Это ровно 48 часов.
Вот откуда взялся этот миф. Смена серверов имён действительно может занять до двух дней, потому что резолверы кэшируют само делегирование именно на этот срок. Где-то по пути время для редкой, медленной операции стало применяться к каждому DNS-изменению вообще, и страницы поддержки хостингов с тех пор это повторяют.
Если вы меняете A-запись, 48 часов — это чепуха. Если вы переносите серверы имён к новому провайдеру, это реально — и вы ничего не можете сделать, чтобы это ускорить, потому что TTL не ваш.
Хитрость, которую все делают чуть-чуть неправильно
Стандартный совет для планирования миграции: понизьте TTL перед изменением. Это верно, и почти все выполняют это неправильно.
Ошибка — понижать TTL за час до изменения. Вот почему это не работает:
Резолверы не просто кэшируют запись — они кэшируют запись с тем TTL, который был прикреплён в момент её получения. Если ваш TTL был 86400 (24 часа), и резолвер закэшировал вашу запись шесть часов назад, он держит эту запись с 18 часами, оставшимися на часах. Понижение TTL до 300 прямо сейчас не дотягивается до памяти этого резолвера и ничего не меняет. У него всё ещё 18 часов впереди, и он не узнает о вашем новом коротком TTL, пока запись не истечёт и он не спросит снова.
Вы должны понизить TTL как минимум за один полный старый TTL-период до изменения. Если ваш TTL — 24 часа, понижайте его за 24 часа заранее. Это даёт каждому кэшу время истечь и заново получить запись с новым, коротким TTL. Затем вносите своё изменение, и оно станет видимым за пять минут.
Полная последовательность:
- Понизьте TTL до 300. Подождите один полный старый TTL-период (24 часа, если он был 24 часа).
- Внесите ваше реальное изменение. Теперь оно видно везде в течение 5 минут.
- Как только вы подтвердили, что всё работает, поднимите TTL обратно до чего-то разумного.
Этот последний шаг важнее, чем кажется. Постоянно низкий TTL означает, что каждый резолвер постоянно перезапрашивает ваши серверы имён — больше нагрузки, больше задержки для ваших пользователей и намного больший радиус поражения, если у вашего DNS-провайдера случится сбой, потому что ни у кого нет закэшированного ответа, на который можно опереться.
Пять вещей, которые выглядят как распространение, но не являются им
Как только TTL истёк, а всё всё ещё неправильно, вы больше не имеете дело с обычным кэшированием. Вот обычные виновники:
У вашей операционной системы есть собственный кэш. Отдельный от резолвера, находящийся на вашей машине, со своими правилами. ipconfig /flushdns в Windows, sudo dscacheutil -flushcache в macOS, resolvectl flush-caches в большинстве современных Linux. Если ваша запись работает с телефона, но не с ноутбука, проверьте это, прежде чем винить что-то выше по цепочке.
У вашего браузера тоже есть собственный кэш. Chrome поддерживает DNS-кэш полностью независимо от ОС, видимый по адресу chrome://net-internals/#dns. Это частая причина того, что разработчики видят устаревшие результаты, пока все инструменты командной строки сообщают правильно.
Ваше приложение кэширует на уровне рантайма языка. Классический пример — JVM, которая исторически кэшировала DNS-запросы на всё время жизни процесса по умолчанию — то есть долго работающий Java-сервис мог держать мёртвый IP-адрес неделями, совершенно не завися от TTL. Любой долгоживущий процесс может держать разрешённый адрес со времени запуска.
Публичные резолверы — это не один кэш, их сотни. Это тонкий момент. Когда вы запрашиваете 8.8.8.8, вы разговариваете не с сервером. Вы разговариваете с anycast-адресом, который маршрутизируется к тому из множества экземпляров резолвера Google, который ближе всего к вам, и у каждого экземпляра свой собственный независимый кэш. Два человека, запрашивающие «один и тот же» резолвер из разных городов, попадают на разные машины с разным состоянием кэша. Даже два запроса из одного места могут попасть на разные экземпляры. Именно поэтому публичный резолвер может выглядеть как переключающийся туда-сюда между старыми и новыми ответами — он не «мигает», вас просто обслуживают разные машины.
Некоторые резолверы игнорируют ваш TTL. TTL — это запрос, а не контракт. Многие резолверы интернет-провайдеров устанавливают собственный минимальный порог, независимо от того, что вы задали — TTL в пять минут превращается в тридцать минут, потому что такова их политика. Существует также стандартизированный механизм (serve-stale), позволяющий резолверам выдавать истёкшие записи, когда они не могут достучаться до ваших авторитетных серверов, что реально полезно для устойчивости и запутывает во время миграции.
Как на самом деле это отладить
Вся диагностика сводится к одному сравнению. Спросите напрямую авторитетный сервер, затем спросите резолвер, и посмотрите, совпадают ли они.
- У авторитетного новое значение, у резолвера старое. Всё работает. Это кэш. Проверьте TTL, дождитесь. Ничего не сломано и нечего чинить.
- У авторитетного всё ещё старое значение. Ваше изменение никогда не опубликовалось. Проблема в панели управления вашего провайдера, а не в DNS — запись не сохранилась, сохранилась не в ту зону, или ваши серверы имён указывают не туда, куда вы думаете. Это реальный баг, и никакое ожидание его не исправит.
Запрос напрямую к авторитетному серверу — это вся хитрость целиком, и инструмент DNS-запроса, позволяющий указать, какой сервер спрашивать, — это всё, что вам нужно. Одна эта проверка говорит вам, ждёте ли вы физику или смотрите на ошибку — и занимает около пятнадцати секунд против полутора дней ожидания, которые рекомендует миф.
Переосмысление, которое стоит сохранить: DNS не медленный. Кэши терпеливы, и вы сами сказали им, как долго терпеть. Как только вы усвоите, что это число ваше и вы задали его заранее, большая часть загадки испаряется — и «подождите 48 часов» перестаёт быть советом, который вы принимаете.