基于twisted實現的智能dns系統:smartdns

jopen 10年前發布 | 18K 次閱讀 smartdns

smartdns 是 python 語言編寫,基于 twisted 框架實現的dns server,能夠支持針對不同的dns請求根據配置返回不同的解析結果。smartdns獲取dns請求的源IP或者客戶端IP(支持edns協議的請 求可以獲取客戶端IP),根據本地的靜態IP庫獲取請求IP的特性,包括所在的國家、省份、城市、ISP等,然后根據我們的調度配置返回解析結果。

smartdns的使用場景:

  1. 服務的多機房流量調度,比如電信流量調度到電信機房、聯通流量調度到聯通機房;

    </li>

  2. 用戶訪問控制,將用戶調度到離用戶最近或者鏈路質量最好的節點上。

    </li> </ol>

    舉個簡單的例子,我們的一個站點test.test.com同時部署在電信和聯通兩個機房,該站點在電信機房的ip為1.1.1.1、在聯通機房的 ip為 2.2.2.2,就可以通過smartdns做到該站點域名解析時判斷源IP為電信的IP時返回1.1.1.1、判斷源IP為聯通的IP時返回 2.2.2.2,從而達到不同運營商機房流量調度的目的。

    支持的功能

    支持A、SOA、NS記錄的查詢,支持DNS forward功能

    性能

    在虛擬機2.4G CPU上能夠處理1000QPS查詢請求,打開debug日志后可以到800QPS。3-5臺dns server組成的集群已經能夠滿足大部分站點的需求。

    目前我們正在實現和小流量測試go語言實現的smartdns,能夠達到3wQPS以上,后續測試穩定后會開源出來,大家敬請期待:)

    原理

    smartdns響應dns請求的處理流程如下:

    基于twisted實現的智能dns系統:smartdns

    IPPool類的初始化和該類中FindIP方法進行解析處理是smartdns中最關鍵的兩個要素,這兩個要素在下面詳細介紹。其他的特性比如繼 承twisted中dns相關類并重寫處理dns請求的方法、升級twisted代碼支持解析和處理edns請求等大家可以通過代碼了解。edns知識可 以猛戳這里:DNS support edns-client-subnet

    IPPool初始化

    基于twisted實現的智能dns系統:smartdns

    ip.csv內容格式如下:200000001, 200000010,中國,陜西,西安,電信

    其中各個字段含義分別為 IP段起始,IP段截止,IP段所屬國家,IP段所屬省份,IP段所屬城市,IP段所屬ISP

    a.yaml配置文件格式:

    test.test.com:
      ttl: 3600
      default: 5.5.5.5 2.2.2.2
      中國,廣東,,聯通: 1.1.1.1 3.3.3.1
      中國,廣東,,電信: 1.1.1.2 3.3.3.2

    配置中地域信息的key包括四個字段,分別帶有不同的權重:

    • 國家:    8

      </li>

    • 省份: 4

      </li>

    • 城市: 2

      </li>

    • 運營商:  1

      </li> </ul>

      初始化階段,會生成一個名為iphash的dict,具體數據結構如下圖:

      基于twisted實現的智能dns系統:smartdns

      其中,iphash的key為ip.csv每一條記錄的起始IP,value為一個list,list長度為6,list前5個字段分別為以該 key為起始IP記錄的IP段截止、IP段所屬國家、IP段所屬省份、IP段所屬城市、IP段所屬ISP,第六個字段是一個hash,key為 a.yaml里面配置的域名,value為長度為2的list,iphash[IP段起始][6][域名1][0]為域名1在該IP段的最優解 析,iphash[IP段起始][6][域名1][1]為該最優解析的總權值,該總權值暫時只做參考。

      iphash初始化過程中最關鍵的是iphash[IP段起始][6][域名1]的最優解析的計算,最簡單直接的方式是直接遍歷域名1的所有調度配 置,挑選出滿足條件且總權值最高的解析,即為最優解析。這種方式記錄整個iphash的時間復雜度為O(xyz),x為ip.csv記錄數,y為域名總數 量,z為各個域名的調度配置數。為了優化啟動速度,優化了尋找最優解析的方法:事先將每個域名調度配置生成一顆樹,這棵樹是用dict模擬出來的,這樣需 要最優解的時候就不需要遍歷所有調度配置,而是最多檢索15次即可找到最優,即時間復雜度為O(15xy),具體實現參考IPPool的 LoadRecord和JoinIP兩個方法。

      有了初始化后的iphash數據結構之后,每次請求處理的時候,只需要定位請求IP處在哪個IP段,找到IP段起始IP,然后從iphash中取出最優解析,取出最優解析的過程是O(1)的。具體流程如下:

      基于twisted實現的智能dns系統:smartdns

      代碼

      github: https://github.com/xiaomi-sa/smartdns

      安裝

      依賴:

      python 2.6或者2.7 Twisted 12.2.0 zope.interface 4.0.1

      安裝:

      git clone smartdns到本地路徑,進入script目錄,執行install_smartdns.sh即可將smartdns安裝在本地,同時python環境和相關的依賴都是使用virtualenv來進行管理,不會對系統環境造成影響。

      啟動:

      進入smartdns的bin路徑下,執行sh run_dns.sh即可啟動smartdns

      測試

      本地測試 dig test.test.com @127.0.0.1

      或者將搭建的smartdns加到測試域名的ns中進行測試。

      支持

      mail: fangshaosen@xiaomi.com

      github: jerryfang8

      EDNS相關請參考:DNS support edns-client-subnet

      </div>
      https://github.com/xiaomi-sa/smartdns

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!