理解 DNS 快取

hanyouqing發表於2021-12-25

理解 DNS 快取

學渣出品,技術/英文學習記錄,難免會有理解/翻譯瑕疵甚至錯誤,歡迎指正。
建議閱讀原文: Understanding DNS cache

當我第一次學習 DNS 解析 時,我被這個漫長和複雜的過程驚到了。想象一下你每天要訪問多少網站,再想一下你每天要訪問多少次。現在想象一下你每次訪問時,在另一端的 ISP DNS 伺服器必須重複整個遞迴過程,並查詢遞迴鏈中的所有域名伺服器。

以此為背景,想象一下你的手機。當你想跟你一個定期聯絡的朋友通個電話時,你很容易在最近通話中找到他們的名字並撥打。但是,如果這些資訊並沒有準備好,你就得打 114 來去獲取他們的號碼,然後手動撥出。看起來是不是很繁瑣?

實際上將域名轉化為 IP 地址 需要大量步驟,並且要消耗大量時間。幸運的是,DNS 的設計者考慮到了如何加速 DNS,並實現了快取。DNS 快取使得 DNS Server 或者 客戶端本地儲存 DNS 記錄並在以後複用,減少了對新 DNS 請求的查詢需求。

域名系統為每一條  DNS 記錄實現了存活時間(TTL)。TTL 指定了一條 DNS 記錄在 DNS 伺服器和客戶端可以被快取的秒數。當快取中存在該 DNS 記錄時,也會儲存其存活時長。伺服器會持續更新快取中的 TTL ,以秒為單位倒數計時。當它變為 0 時,該記錄會從快取中被刪除或者清除。此時,如果快取過期以後再次收到該記錄的請求,DNS 伺服器就必須啟動解析流程。

要理解快取,讓我們來看下上一篇文章中的例子,解析 www.google.com 。 當你在瀏覽器裡輸入 www.google.com 時,瀏覽器向作業系統詢問 IP 地址。作業系統有 stub resolver 或者 DNS client (參考:什麼是 DNS Server, resolver 以及 stub resolver),一個作業系統響應所有 DNS 查詢的解析器。DNS 解析器會傳送 DNS 請求(並開啟遞迴查詢標記)給特定的遞迴解析器(域名伺服器)並根據其 TTL 值儲存其 DNS 記錄到快取。

Stub Resolver 收到一個應用程式的請求,它會先檢視自己的快取,如果快取中有該記錄,它會將快取中的資訊直接返回給應用程式。如果快取中沒有,則傳送 DNS 請求(並開啟遞迴標記)遞迴解析器(ISPDNS 伺服器)。

Recursive Resolver 收到請求,它會先檢視快取中有 www.google.com 的哪些資訊。如果快取中有 A 記錄,則把記錄傳送給 Stub Server。如果沒有 A 記錄,但是有權威域名伺服器的 NS 記錄,它將會請求這些權威域名伺服器(繞過根伺服器和 com gTLD 伺服器)。

如果沒有權威域名伺服器,它會請求 com gTLD 伺服器。

graph TD;
google.com-->Browser;
Browser-->OS;
OS-->Stub-Resolver;
Stub-Resolver-->Cached;
Cached-->Browser;
Stub-Resolver-->Not-Cached;
Not-Cached-->ISP-DNS;
ISP-DNS-->Cached-A-Record;
Cached-A-Record-->Stub-Resolver;
ISP-DNS-->Not-Cached-A-Record;
Not-Cached-A-Record-->Cached-Auth-NS-Server;
Cached-Auth-NS-Server-->Query-Auth-NS-Server;
Query-Auth-NS-Server-->ISP-DNS;
Not-Cached-A-Record-->Not-Cached-Auth-NS-Server;
Not-Cached-Auth-NS-Server-->COM-GTLD-Server;
COM-GTLD-Server-->ISP-DNS;
注:圖表為譯者根據自己理解新增(歡迎指正)

如果沒有權威名稱伺服器,就會請求 .com gTLD 伺服器(因為他們 TTL 非常高,他們一般是存在於快取中,並且他們適用於任意 .com 域名)。只有當他們不存在於快取時, Recursive Resolver 才會向根伺服器請求 gTLDs, 這種情況非常少見(通常是指行了 purge 操作)。

為了避免傳播過期 DNS 記錄,DNS 伺服器將會通過矯正一個請求的 TTL ,而不是這條記錄原始 TTL 值。例如,假設 一條 www.google.com 記錄的 TTL4 個小時,並且它在上午 8 點被 Recursive Resolver 儲存於快取中。如果有一個新使用者,在這個解析器,在上午 9 點請求相同的域名,resolver 將會傳送一個 3 個小時的 TTL 記錄。

現在我們已經覆蓋了 DNSOSDNS 伺服器的快取,然後就剩下最後一層快取:應用程式。所有應用都可以選擇快取 DNS 資料,即使他們不能遵循 DNS 標準。應用依賴作業系統函式 getaddrinfo() 來解析域名(所有作業系統都是用相同的函式名)。該函式返回域名的 IP 地址列表 - 但是他不返回 DNS 記錄,所以應用程式沒有 TTL 可用。

所以,不同的應用程式快取資料時間不同。IE10+ 將在其快取中儲存最多 256 個域名,固定時間為 30 分鐘256 個域名看起來好像很多,實際上不是的 - 網路上大量網頁都會飲用 50 個域名以上,多虧第三方標記和重定向。另一方面,Chrome 將快取 DNS 資訊一分鐘,並且儲存 1000 條記錄。你可以通過訪問 chrome://net-internals#dns 檢視和清理 ChromeDNS 快取。

NS 快取陷阱

人們會經常掉入一個的 DNS 快取陷阱是權威名稱伺服器記錄。就像我們之前提到的,權威名稱伺服器在請求響應中作為 NS 記錄被指定。NS 記錄有 TTL。但並不提供名稱伺服器的 IP 地址。IP 資訊在額外的 A 或者 AAAA 記錄響應裡。

因此,一個 Recursive Resolver 同時依賴於 NSA 記錄來抵達名稱伺服器。理想情況下,兩種記錄型別的 TTL 應該相同,但是偶爾有人錯誤配置 DNS zones,他們會在 DNS 請求傳入新的 A 或者 AAAA 記錄。新記錄覆蓋老記錄,導致產生差異。

當所有的記錄都在快取裡,Recursive Resolver 將會請求其中一臺域名伺服器的 IP 地址。如果 Recursive Resolver 快取中只有 NS 記錄,沒有 A 或者 AAAA 記錄,它就必須解析 名稱伺服器域名,比如 ns1.google.com, 獲取其 IP 地址。這樣並不好,因為它增加了解析域的時間。並且,如果它有域名伺服器的 A 或者 AAAA 記錄但是沒有 NS 記錄,它會強制發起一個 域名 www.google.comDNS 查詢。

設定 TTL: 平衡行為

那麼,TTL 時間長一些還是短一些會更好的呢?合適的的情況下,使用一個更長的 TTL,因為它會使 resolvers 快取更久並且 OSS -- 意味著對終端使用者而言意味著更好的效能,以及它會減少到你名稱伺服器的流量,因為請求會更少。無論如何,它也會減少你的變更 DNS,使你更容易因為遭受 DNS 劫持攻擊,並在你的資料中心不可訪問時無法設定離線錯誤頁面。

換句話說,TTL 越短人們就越會花時間在下載頁面或資源,並增加你名稱伺服器的壓力。並且使你更快的變更 DNS 配置。


DNS 解析是一個多階段的由網際網路大量伺服器參與的過程。協議內建的快取機制通過快取並複用資訊加速了未來 DNS 請求的過程。DNS 伺服器 和/或 客戶端在 TTL 上遵循該 DNS 規範,但是像瀏覽器這樣的應用程式不遵循該規範 - 因此他們的快取可以儲存任意時間。

相關文章