JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

資源記錄、快取,與 TTL

一個名字會變成一個答案——但那個答案究竟長什麼樣子?整顆星球每秒查詢同樣的名字數十億次,又為什麼不會燒壞?這篇要介紹的是資源記錄,以及那個默默撐起整個 DNS 的小數字:TTL。

一個答案到底是用什麼做成的

在上一篇裡,你看著一個解析器把一個名字從根一路走到權威伺服器,再帶著答案回來。但「一個答案」是個有禮貌的簡化。權威伺服器真正交回來的不是一句話,而是一筆小小的、格式嚴格的資料列,叫做資源記錄,簡稱 RR。DNS 對這個世界所知道的每一項事實,都被存成這樣一列;而學會讀懂一列,幾乎就等於學會了 DNS。

一筆記錄每次都有相同的四個部分。有它描述的名字(example.com)、一個說明這是哪種事實的型別(一個位址?一台郵件伺服器?)、一個 TTL(一個我們稍後會回來談的秒數),以及資料本身,稱為 RDATA,也就是那個型別所攜帶的任何東西。把它想成舊式圖書館目錄裡的一張卡片:書名是名字,分類貼紙是型別,用鉛筆寫上的日期是 TTL,那一行文字則是資料。DNS 不過就是一個大得難以想像、又分散各地的抽屜,裡頭裝滿這樣的卡片。

NAME                  TTL     TYPE   RDATA  (the data)
--------------------  ------  -----  --------------------------
example.com.          3600    A      93.184.216.34
example.com.          3600    AAAA   2606:2800:220:1:248:1893::
example.com.          3600    MX     10 mail.example.com.
example.com.          86400   NS     ns1.example.com.
www.example.com.      300     CNAME  example.com.
example.com.          3600    TXT    "v=spf1 include:_spf..."

  ^ name it's about    ^ secs  ^ kind  ^ whatever the kind carries
同一個網域的六筆資源記錄。每次都是相同的四欄:名字、以秒為單位的 TTL、型別,以及該型別所定義的資料。

一個小小的記錄型別動物園

記錄型別有數十種,但少數幾種就包辦了幾乎所有的工作。A 記錄是最原始、也最常見的:它把一個名字對應到一個 IPv4 位址,也就是你認識過的IPv4 位址,像是 93.184.216.34。它的孿生兄弟 AAAA 記錄(讀作「quad-A」)替IPv6位址做同樣的事;位元數是四倍,所以是四個 A。當你的瀏覽器想建立一條連線,它真正要的事實幾乎總是一筆 A 或 AAAA 記錄,因為 TCP 與 IP 講的是位址,不是名字。

CNAME 記錄是一個別名:它說「這個名字只是那個名字的另一個稱呼,去那邊看吧」。所以 www.example.com 可能是一筆指向 example.com 的 CNAME,解析器便順著指標、去解析那個目標。它就像搬家信件上的轉寄貼紙。MX 記錄(郵件交換器)指名替某個網域收信的伺服器,前面附一個數字標示優先順序,好讓信件能退而求其次找備援。NS 記錄指名某個區域的權威伺服器,而這些正是讓前兩篇裡的委派得以運作的記錄;母區域把它的 NS 記錄交給你,就是把你往下交給子區域。

最後,TXT 記錄是個雜物抽屜:它存放任意文字,而整個網際網路在它上面拴了一整套套系統。電子郵件的防偽機制(SPF、DKIM、DMARC)就活在 TXT 記錄裡;某個網站向某項服務出示、用來說「對,這個網域確實是我的」的那一小段證明也是。TXT 之所以強大,恰恰是因為 DNS 從沒規定那段文字代表什麼意思,於是人們不斷替它發明新意義。

TTL:一筆有保存期限的記錄

現在回到中間那一欄的數字。TTL,也就是存活時間,是任何人在必須丟掉這筆記錄、重新去問之前,被允許保留它副本的秒數。一筆 TTL 為 3600 的 A 記錄說的是「這個位址在一小時內有效」。它就是牛奶上用鉛筆寫的賞味期限:在那之前都可以信任它,過了就該去看看有沒有新的一盒。權威伺服器——那個真正擁有這筆記錄的伺服器——是唯一設定 TTL 的一方,它正在決定這世界上其他人被允許記住它答案多久。

為什麼一個數字這麼重要?因為沒有它,DNS 根本無法以這種規模存在。有數十億台裝置,它們一遍又一遍查詢同樣那些熱門的名字。如果每一次查詢都得從根一路行軍到權威伺服器,根與最繁忙的權威伺服器頃刻間就會被壓垮,而每一次頁面載入都得付出你上一篇追蹤過的那趟多跳的完整旅程。TTL 是那張允許答案被重複使用的通行證,而重複使用,正是把一份不可能的工作量變成一份輕鬆工作量的關鍵。

快取:你早已握在手裡的答案

這就是 TTL 所解鎖的機制。當你的本地解析器(你電腦對話的那個遞迴解析器)完成一次查詢,它不會只是把答案交給你就忘掉。它會在記憶體裡留一份副本,存在一個叫做快取的儲存區,並蓋上它抵達那一刻的時間戳。這就是DNS 快取。下一次任何用這個解析器的人問同一個名字,它就能在不到一毫秒內從快取回答,完全不必走那整套層級結構。一個熱門名字的第一次查詢很慢;接下來的一千次幾乎免費。

  1. 一筆 TTL 為 3600 的記錄抵達解析器。解析器把它存起來,並記下時鐘:這筆記錄將在 3600 秒後過期。
  2. 接下來一小時內任何問這個名字的人都會立刻拿到快取的副本,而且解析器還會替它回報的 TTL 倒數,所以一筆已快取 600 秒的記錄,會以剩餘 TTL 為 3000 的形式交出。
  3. 當倒數歸零,這筆記錄就過期了。解析器把它丟棄,並在下一次請求時,重新做一趟完整的遞迴行軍去取一份新的副本。

快取是分層的,就像網路其他地方那些一層套一層的信封。你的瀏覽器有一個小小的快取,你的作業系統有一個,你家的路由器常常也有一個,而你的 ISP 那台大型遞迴解析器則有一個被許多客戶共用的巨大快取。一個查詢會停在第一個已經知道答案的那一層。這就是為什麼你剛造訪過的名字,一打字就立刻解析出來;也是為什麼一個全新的名字,第一次會有一個看得見的停頓。

選一個 TTL 是貨真價實的取捨

TTL 不是設定一次就忘掉的細節;它是一個有著兩種相反代價的旋鈕。一個長 TTL(比方說一天,86400 秒)意味著答案會被重複使用很久,於是你的權威伺服器很少被問到,查詢又快又便宜。代價是,如果你更動一筆記錄,舊答案會在世界各地的快取裡逗留,直到它們過期。一個短 TTL(比方說 300 秒,五分鐘)意味著變更傳得快,但每個快取都不停地重新去問,加重你伺服器的負擔、也增加延遲。沒有放諸四海皆準的數值,只有對你正在做的事而言正確的數值。

兩個誠實的提醒。第一,TTL 是權威伺服器給的一個提示,不是它能強制執行的法律:一個行為不良或過於積極的快取,可能把記錄保留得比要求的更久,而你無法伸手進世界各地的快取去逼它們提早遺忘。所以 TTL 是你該預期的上限、是用來規劃的,絕不是保證。第二,快取加上 TTL,也正是 DNS 在變更後感覺「慢半拍」的原因;記錄在你存檔的那一刻就已經在源頭是正確的,但世界其他地方只能隨著舊副本逾時而慢慢跟上。那個延遲不是錯誤,它正是讓 DNS 能擴展的那份重複使用本身。

反過來查,以及是誰讓它持續運轉

目前為止幾乎所有事都是名字到位址。但有時你手上有一個位址、想要那個名字,例如一台郵件伺服器要查是誰在連它。那就是反向 DNS,而它巧妙之處在於反向 DNS重複使用了同一棵樹。位址 93.184.216.34 被反著寫成一個特殊區域底下的名字,34.216.184.93.in-addr.arpa,而那個名字上一種叫 PTR(指標)的記錄型別會給出主機名。把那幾段位元組反過來寫,正是讓一般那套由上而下的層級與委派也能用在位址上的關鍵;不需要第二套系統。

最後兩塊把這一階綁在一起。記錄不會憑空出現;是某個人(或他們的代管工具)把它們放進一個區域裡,而使用一個名字的權利本身,是透過網域註冊商租來的——你付錢給那家公司去註冊 example.com,並告訴註冊局哪些 NS 記錄指向你的權威伺服器。而抵達那些記錄所要經過的網路,本身也必須又快又有韌性,這就是任播登場的地方:最繁忙的解析器與根伺服器同時從許多地點宣告同一個 IP 位址,於是你的查詢會被導向最近的那份副本,就像一連串共用同一支電話號碼的在地倉庫。任播加上快取,正是為什麼在地球上幾乎任何地方查一個名字都感覺像瞬間完成。