天天看點

雲解析小編科普:“SRTT” DNS伺服器選擇算法介紹

雲解析小編科普:“SRTT” DNS伺服器選擇算法介紹

大家都知道BIND在作為遞歸伺服器時在向權威DNS請求時會使用優選政策,不過這個優選政策目前沒有清晰的資料。小編查閱了一些公開的資料發現基本都是各種傳抄,沒有什麼清晰的說明。是以小編專門編寫此文來科普遞歸是如何進行優選的。本文以BIND9.8/BIND9.9/BIND9.11的代碼為基礎,并假定域名有多個品質不同的NS來進行計算。

BIND9.8及之前版本的SRTT政策

目前可以查詢到的一部分公開的資料都是基于BIND9.8版本的,小編仔細查閱了BIND9.8的源代碼後,判定這些公開資料的描述基本符合事實情況。小編針對BIND9.8的SRTT計算過程描述如下:

1、首先BIND在第一次計算SRTT時為所有的NS記錄一個初始化的值,指派方法是:

isc_random_get(&r);
e->srtt = (r & 0x1f) + 1;
e->expires = 0;           

注釋:這個值為随機1-32us,由于這個值非常小遠小于正常的SRTT,是以可以認為在初始化的時候,所有的NS都會得到一個很小的近乎為零的SRTT,是以所有的NS都有機會去被第一次優選。

2、在所有的NS中選擇SRTT最小的一個NS伺服器發起解析請求,如得到應答則記錄這次請求的RTT,并重新計算這個NS的SRTT,計算方法是:

new_srtt = (addr->entry->srtt / 10 * factor)+ (rtt / 10 * (10 - factor));           

注釋:這裡的factor定義如下:

#define DNS_ADB_RTTADJDEFAULT           7       /*%< default scale */
#define DNS_ADB_RTTADJREPLACE           0       /*%< replace with our rtt */
#define DNS_ADB_RTTADJAGE               10      /*%< age this rtt */           

是以,在正常收到應答的情況:

factor = DNS_ADB_RTTADJDEFAULT;           

是以在正常的請求中,factor的值為7,是以這個新的NS的SRTT計算方法如下,也就是說這次請求的RTT在新的SRTT值的計算中權重占30%:old_srtt 0.7 + curr_rtt 0.3

3、在這次請求中計算了請求的NS的同時,還需要對其他的NS進行衰減計算,計算方法如下:

if (factor == DNS_ADB_RTTADJAGE)
     new_srtt = addr->entry->srtt * 98 / 100;           

注釋:即所有的SRTT指派為原來的98%

4、如果本次NS請求以失敗告終,即送出請求并沒有得到應答的情況,這裡就要對這個NS進行懲罰,計算方法如下:

INSIST(no_response);
     rtt = query->addrinfo->srtt + 200000;
     if (rtt > 10000000)
     rtt = 10000000;           

注釋:直接給SRTT加上200ms,且SRTT最大值不能超過10s

5、1800s後,所有的SRTT清零,重複以上的計算

這個1800來自源碼的宏定義:

#define ADB_ENTRY_WINDOW        1800    /*%< seconds */           

BIND9.9及以後版本的SRTT政策

1、首先BIND在第一次計算SRTT時為所有的NS記錄一個初始化的值,用樣的指派方法,随機1-32us。

2、在所有的NS中選擇SRTT最小的一個NS伺服器發起解析請求,如得到應答則記錄這次請求的RTT,并重新計算這個NS的SRTT,同樣的計算方法old_srtt 0.7 + curr_rtt 0.3

3、其他NS的計算方法如下:

if (addr->entry->lastage != now) {
       new_srtt = addr->entry->srtt;
       new_srtt <<= 9;
       new_srtt -= addr->entry->srtt;
       new_srtt >>= 9;
       addr->entry->lastage = now;           

注釋:大概值為“SRTT = ((SRTT<<9)-SRTT)>>9”,即指派為原來的SRTT的511/512,大概99.8%,這是BIND9.9和之前版本在計算SRTT中的一個最重要的差别

5、如果本次NS請求以失敗告終,則懲罰方式如下:

INSIST(no_response);
rtt = query->addrinfo->srtt + 200000;
if (rtt > MAX_SINGLE_QUERY_TIMEOUT_US)
       rtt = MAX_SINGLE_QUERY_TIMEOUT_US;           

注釋:這裡MAX_SINGLE_QUERY_TIMEOUT_US為宏定義,定義為

#define MAX_SINGLE_QUERY_TIMEOUT 9U
#define MAX_SINGLE_QUERY_TIMEOUT_US (MAX_SINGLE_QUERY_TIMEOUT*US_PER_SEC)           

共9s,也就是SRTT的最大值降低了1s。值得說明的是,在BIND9.11中,這裡的懲罰邏輯又有了變化,計算方法如下:

INSIST(no_response);
isc_random_get(&value);
if (query->addrinfo->srtt > 800000)
       mask = 0x3fff;
else if (query->addrinfo->srtt > 400000)
       mask = 0x7fff;
else if (query->addrinfo->srtt > 200000)
       mask = 0xffff;
else if (query->addrinfo->srtt > 100000)
       mask = 0x1ffff;
else if (query->addrinfo->srtt > 50000)
       mask = 0x3ffff;
else if (query->addrinfo->srtt > 25000)
       mask = 0x7ffff;
else
       mask = 0xfffff;
……
rtt = query->addrinfo->srtt + (value & mask);           

注釋:這裡面根據目前SRTT值的不同,重新定義了一個随機數,而且是如果目前值的SRTT越小則懲罰的度量越大。

5、同樣的1800s後,所有的SRTT清零,重複以上的計算SRTT政策&DNS解析品質。是以BIND的SRTT整個過程如下:

雲解析小編科普:“SRTT” DNS伺服器選擇算法介紹

SRTT從設計上來說即兼顧了DNS異常依賴的優選以及容災措施,在所有NS的存活的情況下能夠保持絕大部分的遞歸請求可以優選最好的NS,同時在個别NS挂掉的情況下又能容災切換至其他的NS。同時,根據BIND版本演進中的衰減/懲罰機制變化來看, BIND在保障容災的前提下盡可能更加選擇優選(衰減政策從原來BIND9.8版本的98%變更至BIND9.9版本的99.8%),是以對于被優選NS的品質也提出了更高要求。在此小編假設一種場景,對于BIND9.11版本的遞歸來講如果一直優選的那個NS因為異常原因發生了丢包進而被遞歸懲罰,将使用更長的時間和次數來為這個NS進行衰減,進而有更長的時間/更多的遞歸次數不能被優選(比如一個原本20ms的NS因為一次丢包導緻SRTT增加至220ms,那麼需要2300次的衰減/或者等1800s過期才能使SRTT重新恢複至20ms),這對于遞歸的性能有本質上的影響。

是以,在衡量權威伺服器本身性能的同時,是否擁有高品質的網絡/是否擁有低丢包率的權威軟硬體服務,也是重要的考量名額。在這裡小編需要指出,阿裡雲在DNS這種網際網路基礎協定上持續進行基礎設施的投入,使得雲解析擁有全球高品質的BGP網絡和自研的高性能DNS,幾乎将雲解析權威的丢包率降低為零,進而實作了更高品質的遞歸解析性能。

繼續閱讀