| 本文根據美團基礎架構部技術專家舒超在2019 ArchSummit(全球架構師峯會)上的演講內容整理而成。html
命名服務主要解決微服務拆分後帶來的服務發現、路由隔離等需求,是服務治理的基石。美團命名服務(如下簡稱MNS)做爲服務治理體系OCTO的核心模塊,目前承載美團上萬項服務,日均調用達到萬億級別。爲了更好地支撐美團各項飛速發展的業務,MNS開始從1.0向2.0演進。本文將圍繞本次演進的初衷、實現方案以及落地的效果等方面進行展開,同時本文還介紹了命名服務做爲一個技術中臺組件,對業務的重要價值以及推進業務升級的一些成果。但願本文對你們可以有所啓發。git
從架構上看,MNS 1.0 主要分爲三層:首先是嵌入業務內部的SDK,用做業務自定義調用;而後是駐守在每一個機器上的SgAgent,以代理的方式將一些易變的、消耗性能的計算邏輯與業務進程分離開來,從而下降SDK對業務的侵入,減小策略變更對業務的干擾;遠端是集中式的組件,包括健康檢查模塊Scanner,鑑權緩存模塊MNSC,以及基於ZooKeeper(如下簡稱ZK)打造的一致性組件MNS-ZK,做爲通知和存儲模塊。在層級之間設立多級緩存,利用「邊緣計算」思想拆分邏輯,簡化數據,儘可能將路由分配等工做均攤到端上,從而下降中心組件負載。更多詳情你們可參考《美團大規模微服務通訊框架及治理體系OCTO核心組件開源》一文中的OCTO-NS部分。github
在體量方面,MNS 1.0已經接入了美團全部的在線應用,涉及上萬項服務、數十萬個節點,並覆蓋了美團全部的業務線,日均調用達萬億級別,目前咱們已將其開源。數據庫
總的來說,做爲公司級核心服務治理組件,MNS 1.0在架構上帶有明顯的CP屬性,在保持架構簡潔、流程清晰的同時,還支持了業務大量迭代的需求,較好地幫助公司業務實現了服務化、標準化的目標。編程
可是隨着美團業務的快速增加,公司的服務數、節點數、服務信息量、服務變更頻次等維度都在快速增加,有些服務甚至呈現出跨數量級的增加。在這樣的狀況下,命名服務也面臨着一些新的問題和挑戰:後端
從可用性、擴展性、性能等三個方面,MNS 1.0暴露出不少的問題,究其根源,原來的命名服務做爲一個CP系統,爲得到「數據一致性」而犧牲了部分狀況下的可用性。其實,對於命名服務而言,一致性並無這麼重要,最可能是調用方在必定時間內調多了或調漏了服務方而已,這個後果在不可靠網絡的大前提下,即便命名服務沒有出現問題,也可能常常會出現。藉助端的自我檢查調整機制,其影響能夠說微乎其微。而另外一方面,若是是一個機房或一個地域的調用方和服務方沒有問題,可是由於這個區域和命名服務主集羣斷開了連接,從而致使本域內不能互調,這個就顯得不太合理了。跨域
因此總結一下,咱們認爲,命名服務的本質是創建和加強服務自己的連通性,而不是主動去破壞連通性。命名服務本質上應該是一個AP系統。緩存
其實,業界對命名服務AP/CP模式都有相應實現和應用,不少企業使用CP模式,緣由可能有如下幾點:安全
另外,咱們瞭解到,一些公司使用特殊的方式弱化了這個問題,好比將CP系統進一步拆分到更小的域中(好比一個IDC),縮小分區的粒度,而全局有多個CP系統自治。固然,這個可能跟調用方服務方的跨度限制或者說調用配套部署有關係,但也有可能帶來更復雜的問題(好比CP系統之間的數據同步),這裏就不作詳細的討論了。微信
除去MNS 1.0自己的架構缺陷,咱們還須要面臨另外一個問題,當初在項目啓動時,雲原生尚處於起步階段,而現在,一些基於雲原生理念興起的網絡基礎設施,尤爲是Service Mesh在美團快速發展,也須要MNS進行改造去適配新的流量通道和管控組件,這也是這次MNS 2.0演進的目標之一。
綜上,咱們以AP化、Mesh化爲主要目標,正式開始了從MNS 1.0向MNS 2.0的演進。
MNS 2.0的總體架構自上而下主要分爲四層:
控制服務層:新增註冊中心控制服務,這也是MNS 2.0的核心。主要分爲如下三個模塊:
綜上所述,MNS 2.0總體架構在兼容1.0的前提下,重點變化是:新增了控制服務層並對底層存儲介質進行拆解。下面,咱們來看一下服務註冊發現功能在MNS 2.0中的實現流程:
接下來,咱們一塊兒來看下MNS2.0的主要演進成果。
2.1 流量洪峯&平行擴展
流量洪峯對於不一樣領域而言有不一樣的時段。對於O2O領域好比美團來講,就是天天中午的外賣高峯期,而後天天晚上也會有酒旅入住的高峯等等。固然,基於其它的業務場景,也會有不一樣的高峯來源。好比經過「借勢營銷」等運營手段,帶來的高峯量可能會遠超預期,進而對服務形成巨大的壓力。
MNS 1.0受制於MNS-ZK集羣數量上限和強一致性的要求,沒法作到快速、平行擴展。MNS 2.0的數據存儲層重心是保證數據安全讀寫和分佈式協調,在擴展能力層面不該該對其有太多的要求。MNS 2.0的平行擴展能力主要體如今控制服務層,其具體功能包括如下兩個方面:
集羣分片:控制服務提供全量註冊數據的分片能力,解決命名服務單獨進行大集羣部署時不能進行業務線隔離的風險。MNS-Control網關模塊分爲Master和Shard等兩類角色,協做提供大集羣分片能力。
網絡分區可用:MNS 1.0階段,網絡分區對可用性的影響巨大,分區後MNS-ZK直接拒絕服務。新架構將存儲遷移到KV系統後,在網絡專線抖動等極端狀況下,各區域依然能正常提供數據讀取功能。同時,咱們與公司存儲團隊共建C++ SDK的地域就近讀寫功能。一方面,提升跨域服務註冊發現的性能,另外一方面,實現了網絡分區後,各區域內命名服務可讀、可寫的目標,提升了系統的可用性,整個命名服務對網絡的敏感度下降。
目前,控制服務層在平行擴縮容時間和集羣原地恢復時間等方面,都達到了分鐘級,集羣也沒有節點上限,從而可以有效應對突發的流量,防止服務出現「雪崩」。
2.2 推送風暴&性能提高
另外一個典型的場景是推送「風暴」,在服務集中發佈、出現網絡抖動等狀況下,會致使命名服務出現"一橫一縱"兩種類型的放大效應:橫向是「關注放大」,相似於社交網絡中某大V消息須要分發給衆多的粉絲,服務越核心,放大的效果越明顯。縱向是「級聯放大」,命名服務的上下游會逐級進行拷貝發送,甚至一級上下游會針對一個消息有屢次的交互(Notify+Pull)。
「關注放大」和「級聯放大」自己都是沒法避免的,這是由系統屬性決定,而咱們能作的就是從兩方面去平滑其帶來的影響:
正面提高核心模塊性能,加強吞吐、下降延遲
2.高併發的吞吐能力:控制服務經過無鎖編程處理關鍵路徑的競爭問題,藉助應用側協程機制,提供高併發、低延遲的數據分發功能。
另外,包括前面提到的控制服務集羣的平行擴展能力,其實也是總體性能提高的一種方式。
側面疏通,區分冷熱數據,下降推送的數據量,提升效能
天然界中廣泛存在「80/20法則」,命名服務也不例外。服務註冊信息的結構體中元素,80%的改動主要是針對20%的成員,比較典型的就是服務狀態。所以,咱們將單個整塊的服務信息結構體,拆分爲多個較小的結構體分離存儲;當數據變更發生時,按需分發對應的新結構體,可以下降推送的數據量,有效減小網絡帶寬的佔用,避免代理組件重複計算引發的CPU開銷,數據結構變小後,內存開銷也獲得顯著下降。
那是否須要作到徹底的「按需更新」,僅推送數據結構中變更的元素呢?咱們認爲,徹底的「按需更新」須要很是精細的架構設計,並會引入額外的計算存儲開銷。好比,咱們須要將變更成員分開存儲以實現細粒度Watcher,或用專門服務識別變更元素而後進行推送。
同時,還要保證不一樣成員變更時,每次都要推送成功,不然就會出現不一致等問題。在組件計算邏輯所需的數據發生變化時,也會帶來更多的改動。在命名服務這樣的大型分佈式系統中,「複雜」、「易變」就意味着穩定性的降低和風險的上升。因此根據「80/20法則」,咱們進行尺度合理的冷熱數據分離,這是在方案有效性和風險性上進行權衡後的結果。
通過改造,MNS 2.0相比MNS 1.0的吞吐能力提高8倍以上,推送成功率從96%提高到99%+,1K大小服務列表服務發現的平均耗時,從10s下降到1s,TP999從90s降低到10s,總體優化效果很是明顯。
2.3 融入Service Mesh
在MNS 2.0中,咱們將代理服務SgAgent部分註冊發現功能合併到了Mesh數據面,其流程以下圖所示:
關於美團服務治理功能與Service Mesh結合的技術細節,這部分的內容,咱們今年會單獨作一個專題來進行分享,感興趣的同窗能夠關注「美團技術團隊」微信公衆號,敬請期待。
2.4 無損遷移
除了上面說到的MNS 2.0的這些重點演進成果以外,咱們還想談一下整個命名服務的遷移過程。像MNS這樣涉及多個組件、部署在公司幾十萬個機器節點上、支撐數萬業務系統的大規模分佈式系統,如何進行平滑的數據遷移而不中斷業務正常服務,甚至不讓業務感知到,是MNS 2.0設計的一個重點。圍繞業務服務無感知、具有快速回滾能力、新/老體系互備數據不丟失等要求,咱們設計了以下圖所示的遷移流程:
MNS 2.0總體以服務爲粒度進行遷移操做,設置標誌位說明服務所處的狀態,由接入代理層組件識別該標誌作出相應的處理。標誌位包括:
上述能夠總結爲:聚焦單個服務,階段性遷移服務發現流量,從而達到相似系統新功能發佈時「灰度上線」的能力。固然,這個策略還涉及一些細節在其中,好比,分開存儲在雙寫時須要重點去保證異常狀況下的最終一致性等等,鑑於篇幅緣由,這裏就不詳細展開討論了,並且業界針對這種狀況都有一些成熟的作法。
另外,咱們經過優化命名服務發佈系統的發版形式,實現自動化的流量灰度策略,下降了人力成本,同時構建了自動化的遷移工具、巡檢工具,高效地進行自動化的數據遷移工做,可以快速巡檢遷移後的鏈路風險,保障新MNS 2.0的穩定上線。
2.5 演進總結
在美團命名服務這樣的大型分佈式系統優化過程當中,具體到架構和功能設計層面,咱們也作了很多的權衡和取捨,前面咱們也提到,放棄了增量式的精準變更信息推送方式。在考慮性能的前提下,也沒有使用數據多維度營運能力更好的MySQL做爲主要存取介質等等。取捨的核心原則是:改造目標時強調業務收益,落地過程當中減小業務感知。
目前,MNS 2.0主要成果以下:
命名服務自己做爲基礎的技術中臺設施,在堅持「以客戶爲中心」,升級自身架構的同時,也從以下幾個方面對美團的多個業務進行賦能。
單元化(SET化)是業界比較流行的容災擴展方案,關於美團單元化的詳細內容,可參考OCTO團隊在本次ArchSummit中的另外一個專題分享《SET化技術與美團點評實踐解密》。這裏主要是從命名服務對單元化支撐的角度去解答這個問題。
如上圖所示,業務多種來源的外網流量在經過網關進入內網後,會藉助命名服務提供的能力(SDK/Agent),並按照業務自定義的核心數據維度和機器屬性,給流量打上單元化標籤,而後路由到標籤匹配的下一跳,從而實現了單元間流量隔離。一個單元內部,從服務節點到各類存儲組件,都依賴於命名服務提供的單元識別和路由能力來完成隔離,因此命名服務在單元化中主要起底層支撐的做用。目前單元化在美團的重點業務,好比外賣、配送已經建設的比較完備,經過必定的單元冗餘度,能在一個單元出現問題時,切換到另外一個可用的鏡像單元,顯著提升了業務總體可用性。
接下來,咱們再來看一下泳道場景。目前泳道在美團這邊主要用於業務作完代碼UT以後的線下集成測試階段,同時結合容器,實現一個即插即用的上下游調用環境去驗證邏輯。命名服務在其中起到的做用與單元化相似,根據泳道發佈平臺對機器的配置,自動編排上下游的調用關係。以下圖所示:
當下一跳存在泳道節點時,測試流量進入泳道。反之,測試流量回流到主幹。每一個節點重複上述過程。
命名服務另一個重要場景是服務的平滑發佈,咱們與發佈平臺配合,控制發佈流量的自動摘除與恢復,實現服務發佈操做的自動化與透明化。具體流程以下圖所示:
早期的發佈流程,存在異常調用的風險,上線過程當中存在一段服務實例不可用的「時間窗口」,此時流量再進入可能致使調用失敗,而後會報錯。爲保證發佈的穩定性,須要操做人員手動進行流量排空,流程上效率低、易出錯,浪費業務團隊的時間。針對這項業務痛點,命名服務向發佈系統提供針對服務實例的流量管控能力,實現進程重啓前自動摘除並清空來源請求,升級完畢後,提供自動流量恢復的平滑發佈功能。智能地解決發版過程當中的異常調用問題,提升公司的服務上線效率,下降了業務團隊的運維成本。
彈性伸縮是容器一個很大的賣點。可是在伸縮過程當中有不少問題須要考慮,好比擴縮容策略,包括調用親和度配置,路由均衡等等。命名服務和容器化合做,提供業務的上下游調用關係、分組設置信息、容器下線流量無損摘除等服務,同時保障伸縮服務註冊及時、高效。以下圖所示:
MNS服務數據對業務的賦能主要分爲兩個部分,一是將自身運行狀態以業務可理解的SLA暴露出來,方便業務評估命名服務健康情況。對於命名服務來講,SLA指標主要有推送成功率和推送耗時兩種(其實,推送耗時也能夠看作成功率的一個衡量維度,這裏暫時不作太詳細的區分)。
MNS 1.0精準量化運行情況的困難在於,一方面MNS的發佈/訂閱機制重度依賴ZK,受限於ZK的自身實現和鏈路上衆多不一樣組件的異構性,及時獲取完整鏈路的推送行爲數據很困難。另外一方面,因爲節點數衆多,全量採集服務發現數據,對公司的監控上報系統以及採集以後的計算也是很大的負擔。
在MNS 2.0中,咱們首先在架構上顯著弱化了ZK的地位,它基本上只做爲一致性通知組件。咱們自研的MNS-Control能夠充分DIY埋點場景,保證了主要推送行爲抓取的可控性。其次,咱們採用了分級採樣計算,在全面梳理了公司現有的服務節點數比例後,將典型的服務列表數劃分爲幾個檔次,好比1000個節點的服務爲一檔,100個又爲一檔,並建立相應的非業務哨兵服務,而後在不一樣機房選取適量的採樣機器按期註冊+拉取來評估總體的運行狀況。這樣既作到了上報量的精簡,又兼顧了上報數據的有效性。詳細操做流程,以下圖所示:
控制層週期性修改採樣服務中的服務數據,觸發服務發現的數據推送流程。
參與指標統計的機器節點,本地代理進程獲取到註冊信息推送後,上報送達時間到運維平臺並由其寫入存儲層。
控制層對數據庫中的數據進行聚合計算,最後上報監控系統展現指標數據。此外,經過與監控團隊合做,解決全量部署的Agent埋點監控問題。
命名服務存儲的服務信息有很高的業務價值,從中能夠知道服務的部署狀況、發佈頻次以及上下游拓撲信息等等。因此「賦能」的第二個部分在於,藉助這些信息,咱們能夠挖掘出業務服務部署運維上不合理的地方或風險點,不斷推進優化,歷來避免一些沒必要要的損失。目前已經在推進的項目包括:
在架構上,MNS 2.0依賴DB和其它一些數倉介質,進行多種維度的數據上卷和下鑽,並結合一些定製的風險策略邏輯去幫助業務發現和規避問題,目前這個事情也在進行中。
將來,美團命名服務主要會朝兩個方向發展:
美團OCTO服務治理團隊誠招C++/Java高級工程師、技術專家。咱們致力於研發公司級、業界領先的基礎架構組件,研發範圍涵蓋分佈式框架、命名服務、Service Mesh等技術領域。歡迎有興趣的同窗投送簡歷至tech@meituan.com(郵件備註:美團OCTO團隊)。
閱讀更多技術文章,請掃碼關注微信公衆號-美團技術團隊!