簡介:DNS 延遲的原因與緩解
隨著網頁越來越複雜,參照大量網域的資源,DNS 查詢可能會成為瀏覽體驗中的重大瓶頸。每當用戶端需要透過網路查詢 DNS 解析器時,引進的延遲時間可能極大,具體取決於解析器必須查詢的名稱伺服器數量和名稱伺服器數量 (超過 2 個,但很少發生)。例如,以下螢幕截圖顯示 Page Speed 網路效能評估工具回報的時間。每個長條代表該網頁參照的資源;黑色部分代表 DNS 查詢。在本頁中,網頁載入的前 11 秒內進行 13 次查詢。雖然有幾項查詢是同時完成,但螢幕截圖顯示需要 5 個序列查詢時間,其中總共是 11 秒的網頁載入時間。
DNS 延遲時間包含兩個部分:
- 用戶端 (使用者) 和 DNS 解析伺服器之間的延遲時間。 在大多數情況下,這主要是因為網路系統中的常用往返時間 (RTT) 限制:用戶端與伺服器機器之間的地理距離、網路壅塞、封包遺失和重新傳輸延遲時間 (平均每秒一秒)、超載伺服器、阻斷服務攻擊等。
- 解析伺服器和其他名稱伺服器之間的延遲時間。造成延遲的原因主要如下:
- 快取失敗。 如果無法透過解析器的快取提供回應,但需要以週期性方式查詢其他名稱伺服器,則系統會考慮新增的網路延遲,特別是在具公信力的伺服器中加入地理遠端時。
- 佈建不足。 如果 DNS 解析器超載,它們必須將 DNS 解析要求和回應排入佇列,且可能會開始捨棄並重新傳輸封包。
- 惡意流量。 即使 DNS 服務超額佈建,DoS 流量可能也會對伺服器造成不必要的負載。同樣地,Kaminsky 樣式的攻擊也可能會發生洪水解析器,而這類查詢保證需要略過快取,並需要傳出要求才能解決。
我們認為快取遺失係數是 DNS 延遲的主要原因,我們會在下方進一步討論。
快取失敗
即使解析器擁有足夠的本機資源,與遠端名稱伺服器通訊相關的基本延遲也不容易。換句話說,假設解析器已充分佈建,讓伺服器端遇到零快取快取的情形,在延遲方面則會快取失敗。如要處理缺失,解析器必須和至少一個伺服器連線 (通常是兩個以上的名稱伺服器)。根據 Googlebot 網路檢索器的觀察,我們在回應回應的名稱伺服器平均解析時間為 130 毫秒。 不過,由於 UDP 封包遺失和伺服器無法存取,因此完整的要求 4-6% 會逾時。如果我們將封包遺失、無效名稱伺服器、DNS 設定錯誤等因素納入考量,「實際」到端對端的平均解決時間為 300 到 400 毫秒,但是這會有顯著的差異和長尾。
雖然 DNS 伺服器的快取失敗率可能各不相同,但如果您不按照快取缺失情況,原因如下:
- 網際網路規模和成長。 簡單來說,隨著網際網路蓬勃發展,無論是加入新使用者和新網站,大部分內容都具爭議性。 雖然少數網站 (以及 DNS 名稱) 非常受歡迎,但多數網站只對少數使用者感興趣,且很少存取;因此,大多數要求都會造成快取失敗。
- 存留時間 (TTL) 值偏低。 DNS 存留時間值越低的趨勢,意味著解析度需要提高查詢頻率。
- 快取隔離。DNS 伺服器通常會部署在負載平衡器後方,隨機為不同的機器分配查詢。這會導致每個伺服器分別維護獨立的快取,而不是從共用集區重複使用快取解析度。
因應措施
在 Google 公用 DNS 中,我們已實作幾種方法來加快 DNS 查詢時間。以下列舉一些做法相當標準,其餘都是實驗性質:
- 妥善佈建伺服器以處理來自用戶端流量 (包括惡意流量) 的負載。
- 防範 DoS 和擴大攻擊。雖然這主要是安全性問題,且會影響到開啟的解析器 (而非開放式問題)。不過,預防 DoS 攻擊也有助於減輕 DNS 伺服器產生的額外流量,進而提升效能。 如要進一步瞭解我們採用哪些措施來盡量減少攻擊的機率,請參閱安全性優點頁面。
- 針對共用快取進行負載平衡,以改善服務叢集的匯總快取命中率。
- 為所有使用者提供鄰近服務。
妥善佈建服務叢集
快取 DNS 解析器必須執行比昂貴的名稱伺服器更高的費用,因為許多回應無法從記憶體提供,因此需要與其他名稱伺服器通訊,因此需要大量網路輸入/輸出。此外,開放式解析器也較容易快取快取中毒嘗試,增加快取失敗率 (這類攻擊專門針對無法從快取解析的假名命名要求),以及會增加流量負載的 DoS 攻擊。如果解析器未充分佈建,且無法跟上負載,這可能會對效能造成負面影響。 系統會捨棄封包且需要重新傳輸,名稱伺服器要求必須排入佇列等。這些因素都可能造成延遲。
因此,請務必為 DNS 解析器佈建大量磁碟區輸入/輸出功能。包括處理可能的分散式阻斷服務攻擊,唯一的解決方法是針對許多機器過度佈建。但同時,請在新增機器時降低快取命中率;這需要實作有效的負載平衡政策,詳情請見下方說明。
共用快取的負載平衡
如果透過新增機器,利用新增機器來擴充解析器基礎架構,實際上可能無法回火並降低快取命中率。在一般部署作業中,多部機器會位於負載平衡器後方,且會使用循環演算法等簡易演算法將流量平均分配至每部機器。因此,每部機器都會保留專屬的獨立快取,讓快取內容跨電腦隔離。如果每個傳入的查詢都會分配至隨機機器,視流量的性質而定,您可以根據比例提高有效快取流失率。例如,如果名稱重複的 TTL 較長,快取流失率可能會增加叢集中的機器數量。對於存留時間極低、查詢頻率非常低,或是導致無法快取回應 (0 存留時間與錯誤) 的名稱,則即使新增機器,快取失敗率也不會受到太大影響。
如要提高可快取名稱的命中率,請務必對負載平衡伺服器非常重要,以免快取零碎。Google 公用 DNS 提供兩種層級的快取。在一組鄰近使用者處的機器中,每部機器的小型小型快取包含最常用的名稱。如果此快取無法滿足查詢,系統會將要求傳送至另一個機器,並以名稱為快取分區。在這個第二層快取中,相同名稱的所有查詢都會傳送至同一部機器,其中名稱會快取或不存在。
為廣泛的地理區域發布提供叢集
在封閉式解析器中,這其實不是問題。 對於開放式解析器,伺服器位於使用者越接近位置,用戶端端的延遲時間就越短。此外,擁有充足的地理區域涵蓋範圍可以間接改善端對端延遲時間,因為名稱伺服器通常會針對 DNS 解析器的位置傳回最佳化結果。也就是說,如果內容供應器代管世界各地的鏡射網站,供應商的名稱伺服器會傳回最接近 DNS 解析器的 IP 位址。
Google 公用 DNS 位於全球的資料中心,並採用任一傳播轉送功能,將使用者傳送至位於地理位置最近的資料中心。
此外,Google 公用 DNS 支援 EDNS 用戶端子網路 (ECS),這項 DNS 通訊協定擴充功能可協助解析器將用戶端位置轉送到名稱伺服器,進而傳回針對實際用戶端 IP 位址最佳化的位置回應,而非解析器的 IP 位址。詳情請參閱這份常見問題。 Google Public DNS 會自動偵測支援 DNSDNS 用戶端子網路的名稱伺服器。