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

华为云开发者联盟發表於2024-05-08

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

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

一、異地多活

1.1 什麼是異地多活

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

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

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

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

圖一:同城雙活架構圖

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

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

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

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

圖二:異地多活架構圖

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在異地多活場景下的實踐

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

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

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

enableKafkaProhibition: true  
kafkaTopics:  
 - topic-test 

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

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

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

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

三、資料庫禁寫外掛

3.1 訊息佇列禁止消費外掛介紹

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

資料庫禁寫外掛目前支援MySQL、MongoDB、PostgreSQL和OpenGauss資料庫。在微服務執行時,可以透過配置中心下發禁寫的資料庫型別和名稱。支援禁寫的具體寫操作和外掛使用方式請參考官網文件資料庫禁寫

3.2 資料庫禁寫外掛保護資料一致性應用

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

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

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

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

enableMySqlWriteProhibition: true  
mySqlDatabases:  
 - global

其中,enableMySqlWriteProhibition表示開啟對MySQL資料庫的禁寫能力,mySqlDatabases用於指明具體的禁寫資料庫名稱,本示例為global資料庫。

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

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

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

四、總結

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

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

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

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

相關文章