Sermant在異地多活場景下的實踐

本文分享自華爲雲社區《Sermant在異地多活場景下的實踐》,作者:華爲雲開源。

Sermant社區在1.3.0和1.4.0版本相繼推出了消息隊列禁止消費插件數據庫禁寫插件,分別用於解決異地多活場景下的故障切流和保護數據一致性問題。本文將對Sermant在異地多活場景下的實踐進行剖析。

一、異地多活

1.1 什麼是異地多活

對於一個軟件系統,我們希望當系統出現故障時仍然可以正常對外提供服務,軟件系統的這種特性稱之爲高可用, 異地多活架構便是用來解決高可用問題的。

最早的系統架構一般爲單機架構,當數據庫出現故障時,可能會導致業務長時間中斷。爲了解決這一問題,數據庫發展爲由主庫和從庫組成,主庫負責讀和寫操作,從庫只提供讀操作,主數據庫的數據會實時同步至從數據庫保持數據的一致性和完整性。當主庫出現問題時,從庫切換爲主庫繼續工作。不過,這些服務都部署在同一機房甚至是同一個機櫃,當機房出現故障後,系統仍然不能正常對外提供服務。

此時,同城雙活成爲很好的解決方案,在一個城市部署兩個機房,兩個機房部署相同的軟件環境,並且均提供服務。當其中一個機房出現故障時,可以將流量切換至另一個機房繼續執行,以保證系統的高可用。如圖一所示,機房1數據庫爲主數據庫,兩個機房所有的寫操作均操作機房1的主數據庫,讀操作則可以讀取本機房的數據庫。兩個機房部署的物理距離較近,同時兩個機房可以使用專線進行網絡連接,因此不同機房服務調用的網絡延遲較低,機房2的服務寫入機房1的數據庫時延在可接受範圍內。

圖一:同城雙活架構圖

同城雙活架構很好地解決了軟件系統的高可用問題,但是城市如果出現了自然災害,比如地震、水災等,這些部署在同一城市的所有機房仍然會受到損害從而停止提供服務。並且因爲這些災害的破壞性較強,系統修復的週期也會相對漫長,會嚴重影響公司業務的正常運行。在這種情況下,很明顯需要這些機房部署在不同的地域,同時這些地域的地理距離需要足夠遙遠,這樣就能抵抗自然災害的風險,這就是異地多活架構的由來和價值所在。

針對上圖,機房1和機房2如果部署在兩個城市,就變成了異地雙活,爲了更好的抵禦風險,可以在多個地域部署機房,這樣異地雙活就升級爲了異地多活。

異地多活的架構圖如圖二所示,客戶端的流量通過路由層分發至不同的地域機房執行。和同城雙活架構不同的一點在於不同地域的機房物理距離遙遠,部署網絡專線的成本巨大且不現實,不同機房之間訪問的網絡時延是不可忽視的,因此需要操作本機房內的數據庫,不能跨機房操作。在異地多活架構下,每個機房的數據庫均爲主庫,不同機房的數據會同步至中心機房,並由中心機房再同步至其他機房。因爲所有機房的數據庫都可以寫入,當不同機房修改同一條數據時,就不可避免的引入了數據衝突的問題。爲了解決數據衝突,可以在路由層根據分片策略使一些流量固定轉發到某一機房,流量分片的策略可以基於業務類型或地理位置。通過流量分片,保證同一用戶的相關請求,會路由至同一個機房內完成所有業務操作,並且機房內的流量保證只在本機房內流轉,降低網絡延遲。

圖二:異地多活架構圖

1.2 異地多活典型場景

異地多活架構通過在不同地域部署機房對外提供服務來抵禦自然災害帶來的風險,是實現系統高可用的有效手段。但是,異地多活架構也使系統變得更加複雜,在故障切流、數據一致性等方面引入了新的需求:

  • 雲服務場景下,當某可用區發生故障時,需要故障區的消費者停止拉取消息進行消費,同時將已分配的消息隊列重平衡給正常可用區的消費者處理,從而避免引發業務異常。
  • 異地多活通過對流量分片處理,可以很好地解決數據一致性問題。但是對於全局數據,比如商品數量,在寫入數據時,只允許操作中心機房的全局數據庫。一般需要將操作全局數據的流量路由至中心機房,其他機房只允許讀該數據庫。當流量路由錯誤時,仍可能會寫入非中心機房的數據庫,導致數據衝突問題。此時需要對全局數據庫添加防護,在非中心機房禁止寫操作的執行。

針對以上兩個典型問題,Sermant分別開發了消息隊列禁止消費插件和數據庫禁寫插件來處理,下文將詳細介紹。

二、消息隊列禁止消費插件

2.1 消息隊列禁止消費插件介紹

消息隊列禁止消費插件允許微服務在運行態根據實際需求動態調整消費者對消息隊列中間件的消費行爲,確保在非正常環境或狀態下,業務處理流程中的消息得到妥善管理,避免不必要的業務影響。例如,在異地多活架構系統中,如果發生區域性故障需要對流量做切流處理時,可在發生故障的可用區開啓消息隊列禁止消費功能,讓正常可用區的消費者來處理業務,避免故障區域消費流量從而導致業務異常,保障系統的高可用。待故障處理完成後,可重新開啓消費。

消息隊列禁止消費插件目前支持Kafka和RocketMQ兩種消息中間件。在Kafka方面,該插件實現了Topic級別的禁止和恢復消費功能。對於RocketMQ, 控制消費的粒度爲消費者實例級別。Sermant支持通過配置中心下發需要禁止消費的消息隊列類型和具體Topic。

關於消費隊列禁止消費插件更多的介紹、配置說明和場景演示等請參考官網文檔消息隊列禁止消費

2.2 消息隊列禁止消費插件故障切流場景應用

應用場景:某軟件系統使用Kafka作爲消息隊列,生產者往topic-test主題生產消息,該topic消息包含四個partition。可用區A和可用區B各有兩個消費者加入test消費者組並消費topic-test的消息,每個消費者各分配一個partition,其中可用區A和可用區B分佈在不同地域,即異地多活的兩個機房。如下圖所示。

該場景下,消費者服務通過掛載Sermant的消息隊列禁止消費插件運行後,可以實時控制消費者消費的主題,從而確保在非正常環境或狀態下,業務處理流程中的消息得到妥善管理。

當可用區A發生故障後,可用區A的消費者應該停止消費。在可用區A下發全局配置禁止消費者A和消費者B消費topic-test主題,並釋放已分配的消息隊列。

消息隊列禁止消費插件的配置如下所示,enableKafkaProhibition表示開啓Kafka隊列禁消費能力,kafkaTopics指明需要禁止消費的訂閱主題Topic。下發配置的方式請參考官網文檔消息隊列禁止消費

enableKafkaProhibition: true  
kafkaTopics:  
 - topic-test

配置下發後,可用區A的消費者停止消費,可用區B消費者重新分配topic-test主題的partition,如下圖所示。

待可用區A恢復正常後,可以重新通過動態配置中心下發配置,開啓消費者A和B對topic-test主題的消費。開啓消費配置下發後Kafka將觸發重平衡,可用區A和B的消費者重新分配partition。

消息隊列禁止消費插件實現了異地多活場景下消息隊列的故障切流能力,保障了系統的可用性。

三、數據庫禁寫插件

3.1 消息隊列禁止消費插件介紹

服務在掛載數據庫禁寫插件啓動後,可以動態開啓或關閉對指定數據庫的禁止寫入能力。在異地多活場景下,用戶希望停止對個別或全部數據庫的寫入操作,僅允許讀取數據,以保證數據庫系統的數據完整性、一致性和安全性。比如,某業務數據庫全局數據寫入僅允許操作中心機房,通過開啓數據庫禁寫插件,使路由異常流量寫入非中心機房數據庫失敗;多地多寫場景下,對流量手動切流前,被切流的機房先禁止寫入數據庫,等待其他機房數據同步完成後,再進行切流。以上場景中數據庫禁寫插件的使用保障了數據庫數據的一致性。

數據庫禁寫插件目前支持MySQL、MongoDB、PostgreSQL和OpenGauss數據庫。在微服務運行時,可以通過配置中心下發禁寫的數據庫類型和名稱。支持禁寫的具體寫操作和插件使用方式請參考官網文檔數據庫禁寫

3.2 數據庫禁寫插件保護數據一致性應用

應用場景:異地多活架構下,某業務微服務用於修改商品庫存等全局數據,同時全局數據保存在名爲global的MySQL數據庫中。對於該全局數據,寫操作僅允許操作中心機房的global數據庫,其他機房的global數據庫只能讀取數據。爲了保證數據一致性,當修改全局數據時,該流量在路由層被路由至中心機房執行,其他讀操作可路由至任意機房,如下圖所示。

當路由層對寫全局數據的流量發生路由錯誤從而在非中心機房執行時,如果中心機房和非中心機房同時修改同一商品的數量,就可能導致數據衝突問題,爲了防止這種情況的發生,業務微服務可以掛載Sermant的數據庫禁寫插件,禁止在非中心機房寫入global數據庫。

在非中心機房禁止寫入global數據庫,需要通過動態配置中心下發如下配置:

enableMySqlWriteProhibition: true  
mySqlDatabases:  
 - global

其中,enableMySqlWriteProhibition表示開啓對MySQL數據庫的禁寫能力,mySqlDatabases用於指明具體的禁寫數據庫名稱,本示例爲global數據庫。

下發配置後,當路由異常的流量在非中心機房寫入global數據庫時,數據庫禁寫插件對業務微服務拋出java.sql.SQLException異常,並禁止寫入該數據庫。業務系統需要處理該異常,比如加入重試操作重新路由該流量至中心機房執行,以保證系統的正常運行,執行邏輯如下圖所示。

數據庫禁寫插件在異地多活場景下禁止對指定數據庫的寫入能力可以防止異常流量的寫操作,保證不同機房數據庫的數據一致性。

四、總結

在異地多活場景下,Sermant的消息隊列禁止消費插件可以實現可用區故障時消息隊列的切流問題,讓正常可用區的消費者消費數據;數據庫禁寫插件則用於禁止寫入指定的數據庫,並且不影響讀數據庫,防止發生數據衝突問題。

Sermant在異地多活場景實現了豐富的服務治理能力,未來,Sermant還將持續發力,逐步構建更加完善的服務治理能力體系。

 

Sermant作爲專注於服務治理領域的字節碼增強框架,致力於提供高性能、可擴展、易接入、功能豐富的服務治理體驗,並會在每個版本中做好性能、功能、體驗的看護,廣泛歡迎大家的加入。

  • Sermant 官網:https://sermant.io
  • GitHub 倉庫地址:https://github.com/huaweicloud/Sermant

點擊關注,第一時間瞭解華爲雲新鮮技術~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章