本文做者:AIOps智能運維程序員
乾貨概覽redis
在計算機程序或者服務的層次上,咱們來試着分析前面提到的幾個問題。數據庫
問題緩存
1.我是誰?安全
服務叫什麼,服務包含了哪些實例,服務規模、部署狀況、實例運行情況如何?架構
2.我從哪裏來?運維
服務的上游有哪些,不一樣的上游流量如何分配?ssh
3.我往哪裏去?分佈式
服務的下游有哪些,不一樣的下游流量如何分配?函數
面對這樣的問題,咱們的答案是什麼呢?
在百度的運維實踐中,咱們只需「BNS」就能夠得到想要的答案。
BNS(Baidu Naming Service,百度名字服務)是百度雲智能運維團隊研發的一套分佈式的名字服務系統,是百度雲Noah智能運維產品中的一個重要基礎服務系統。它爲每個服務賦予一個獨一無二的名字,根據這個名字,咱們就能夠獲取到這個服務的相關信息 ,這些信息包括:服務在機器上部署信息(機器IP,部署路徑,服務配置,端口信息),服務的實例運行情況等其餘重要信息。簡單來說,它提供了一個服務名到資源信息的一個映射關係。
在BNS系統中,服務單元表示一個服務的實例集合,通常以三段式的結構表示,好比:server.noah.all,server表示服務名,noah表示產品線,all表示機房名稱,服務單元的名字在系統中是惟一的。
使用場景
在程序員的平常工做,經常面臨如下的場景:
場景
場景一:我是一名OP工程師,負責幾十個系統模塊的運維,我經常須要登陸部署服務的機器排查問題,可是隻知道服務名,記不住那麼多部署信息,怎麼辦?
場景二:我是一名RD工程師,我負責的服務須要擴容,個人服務是不少下游服務的依賴,服務的擴容怎麼通知給下游模塊?
場景三:個人服務部署實例有一個出現故障了,我想對下游服務屏蔽該故障實例,怎麼辦?
下面以一個簡單的例子來講明,假設一個模塊名是Server,它的上游是Proxy服務,下游是Redis服務,當出現變動或者故障時,如何讓上游感知到呢?
當新增上線實例、下線摘除實例或者實例發生故障時,BNS系統經過部署在機器上的客戶端實時感知到實例的狀態變化,同時新增和刪除實例的變動狀況會當即同步到分佈式的緩存系統中,這樣用戶經過一個BNS名字就能夠感知到下游的實例變化。
對應上面幾個場景,BNS提供瞭如下的解決方案:
場景一:用戶想登陸Proxy模塊的第一個實例,能夠經過ssh 1.proxy.noah.all.serv 方式登陸。
咱們基於BNS開發了nsswitch的擴展,而且修改了/etc/nsswtich的配置文件:
hosts files dns bns
在主機須要解析1.proxy.noah.all.serv 的時候,通常會直接或者間接的調用glibc提供的gethostbyname_r函數,而glibc在實現gethostbyname_r時,會按照nsswitch裏配置的順序files->dns->bns順序進行處理,這樣就實現了經過BNS登陸機器。
場景二:Server模塊擴容,但願上游及時感知到下游模塊的變動。
用戶在BNS上進行Server模塊的擴容,模塊實例變化信息會當即同步到BNS系統中的分佈式緩存,在全網任意一臺機器上,經過查詢就能實時獲取到實例變化的詳情。
場景三:Redis模塊3.redis.noah.all實例故障了,但願對上游屏蔽該實例。
經過部署在機器上的客戶端感知到實例的狀態變化(好比實例狀態由0變成-1,即正常變成非正常),並將數據同步到系統中的分佈式緩存,上游模塊能夠經過查詢redis.noah.all的實例狀態結果,主動過濾非正常的實例,也能夠在BNS系統中發起屏蔽故障實例的操做,在查詢過程當中會自動過濾該故障實例。
在下一節中將具體介紹BNS系統的總體架構。
基本架構
BNS系統主要包含幾個部分:流量接入層,Web Server,存儲層,代理客戶端。
做爲一個底層的基礎服務,BNS系統天天的訪問量近千億次,這對系統的可用性提出了很高的要求,於是系統須要在各個層面有完善的容災能力和流量管控能力。
1流量接入層
系統經過HTTP接口對外提供變動服務,用戶經過Web頁面或者接口進行服務或實例信息註冊。爲了保證平臺穩定和安全的運行,須要對非法和異常請求進行拒絕,在流量接入層(Proxy)端提供瞭如下兩個功能:
流量鑑權:每個服務組、服務單元、實例的註冊都須要進行權限驗證,用戶只有申請了合法的Token才能容許訪問,另外系統還提供了白名單等其餘的鑑權方式。
配額限流:針對產品線、用戶、IP提供必定的配額,當請求的數量超過配額,就會拒絕響應的請求,並提示用戶Quota超限。
2Web Server
Web Server提供用戶進行各種BNS變動的接口,承擔了BNS系統的大部分寫入流量,採用分佈式多地域的部署方式,能夠避免單實例、單機房的故障對可用性形成的影響。
3存儲層
這裏主要包含數據庫和Cache層兩個部分。
數據庫:採用MySQL存儲,採用主從集羣部署、讀寫分離的方式。
Cache層:是BNS系統自研的一個緩存模塊,緩存了全量的BNS系統數據,採用多地域部署的方式,它主要功能是下降數據庫的查詢壓力。
4客戶端
BNS系統主要包含兩個客戶端:查詢客戶端和健康檢查客戶端,咱們分別用Naming Agent和Check Agent來代指兩個。
客戶端部署在全部的機器上,並提供命令行工具和豐富的SDK以及各種插件,方便用戶在各個場景使用。
Naming Agent:提供BNS的查詢功能,用戶能夠根據一個名字(服務組、服務單元、實例)就能獲得詳細的服務信息。Naming Agent與Cache層的數據交互,採用推拉結合的方式,Naming Agent主動拉取數據和Cache模塊推送變動數據,同時Naming Agent客戶端會將查詢過的數據置於本地緩存中,以此下降Cache層的查詢壓力。
Check Agent:提供BNS實例的健康檢查功能,用戶經過在Web頁面對每個實例配置健康檢查的方式,機器上的Check Agent會主動探測全部實例的運行情況,並將健康檢查的結果上報給Cache層,同時更新數據庫內容。
總結
BNS系統知足服務間交互中常見的的資源定位、IP白名單維護等需求,也能夠用於機器列表查詢,使用場景包括機器列表查詢、服務定位、白名單維護、數據庫智能受權等,解決了程序「我是誰?我從哪裏來?該往哪裏去?」的問題。
今天咱們一塊兒聊了百度雲Noah智能運維產品中的BNS系統,目前系統還在持續迭代和優化中,若您想進一步瞭解BNS問題,歡迎你們積極留言。