無法做單元化,異地雙活也可以玩得很溜
?一、基本概念
1、機房
中心機房
當前單機房情況下的機房,除了雙活的業務外,長尾業務以及沒做多活的業務都在該機房。
- 單元機房
新機房,即雙活新增的機房,用以承接主鏈路雙活能力流量的機房。
2、路由
sharding_id即route_code,雙活根據路由規則會轉換為route_code(四輪出行為地域)。每個route_code會對應中心機房或者單元機房。網關、soa、redis、db等都會根據route_code路由到正確的機房。
二、多活的幾種模式
1、同城雙活
在同個城市進行雙活部署(兩個IDC)。
2、異地雙活
在兩個城市進行雙活部署(每個城市一個IDC)。
3、異地多活
在多個城市進行多IDC部署。
4、優劣勢
三、單元化
大家可以考慮一個問題,一個公司,或者某個業務在tps達到幾十萬或者幾百萬在整個系統設計、架構乃至機房瓶頸就會顯得極為突出。但是放眼整個國家或者全球來看,全部的tps何止百萬、千萬,歸根結底還是因為不同的流量,在最開始就根據公司、業務、機房、地區路由到了不同的機房,而由于公司、業務之間天然是隔離的,因此每個公司的每個業務只需要處理自己的這部分tps就行。如:淘寶流量只會在阿里的應用、機房,滴滴的流量只會在滴滴的應用、機房。但是假如某個公司的某個業務的tps有一億,假如無法做到水平無限擴容,必然是沒有公司能夠抗住這么大的并發的,不光是架構,即使物理機房也不允許這么大的集群(電力、場地都會有限制)。而單元化提供了理論上無限水平擴容的架構能力。
單元化可以理解為異地多活的最終形態。單元化在流量入口將流量拆分到不同的IDC,每個IDC分別承接自己的流量,且IDC之前的流量不會互相調用。單元化和區域無關,理論上做到單元化后,新增的流量完全可以新增IDC解決,而新增的IDC不會受到區域的限制,因為IDC之前不會有流量互相調用。
判斷是否做到單元化,我理解只要一個標準,即是否流量能夠自閉環。舉個例子,如果你的A機房在上海部署,B機房很遠的海外的任意一個地方,對業務也毫無影響(AB機房地域距離很長,如果無法做到自閉環,則相互調用的RT會變長,必然影響業務),那么你就可以認為是單元化成功了。
單元化流量如下:
單元化做雙活只需要在底層的數據層面進行同步即可。如下所示:
四、雙活的流量路由規則
1、路由方式
1)隨機路由
將流量按照比例隨機路由到各自IDC,只需按照比例路由到每個IDC,而無任何規則。故障情況下,可以將該故障機房的流量切換到另外的IDC。
2)用戶id路由
根據用戶id將流量按照一定比例路由到各自IDC,每個用戶的操作都會路由到指定的IDC。故障情況下,可以將該故障機房的流量按照用戶切換到另外的IDC。
3)地域路由
按照用戶所屬城市將流量按照一定比例路由到各自的IDC,每個地方的用戶操作都會路由到指定的IDC。故障情況下,可以將該故障機房的流量地域切換到另外的IDC。
2、四輪出行的選擇
經過多番討論,哈啰四輪出行最終選擇了按照地域路由。
主要理由如下:隨機路由在各類多活設計中都不算一個好的方案,主要原因是隨機路由由于其無規律性,在多活項目中,無法做到單元化。選擇地域路由而非用戶維度路由,主要是由于四輪業務和電商業務存在一些區別,在電商業務中的基本操作都是基于C端用戶,每個C端用戶只操作自己的訂單數據,因此訂單數據按照用戶id天然是隔離的,單元化也比較好做,但是此方案也是犧牲了B端的商家的體驗,商家操作多用戶訂單數據必然會存在跨機房的可能性,從而影響商家體驗。
作為四輪來說,買家和賣家分別為乘客和司機,是天然的雙訂單模型(司機訂單和乘客訂單),因此如果用用戶id路由,則在同時操作司機訂單和乘客的接口(如司機接單)中,必然會存在大量的跨機房路由(司機和乘客因為用戶id不同分到不同的機房)。而如果按照地域來分,則由于出行訂單跨城或者跨省的概率極低,因此該跨機房率會大大降低,且可以根據實際跨機房單量比例去人為降低跨機房數量。但是該方案也有一定缺陷,因為地域訂單會在不同的時間和場景下,如:節假日、下雨天等會存在比較大的流量波動,導致同城、同省流量波動較大,從而導致機房壓力大小不一致。
五、雙活方案
1、中間方案
雙活中間件提供的能力主要分為四類,存儲、消息、soa和雪花算法。
2、存儲
存儲提供的能力大部分為底層的數據雙向同步。
redis的跨機房讀寫和跨機房加鎖均是因為雙訂單模型無法做到單元化,提供的雙活能力。
redis雙寫則為無雙向同步能力時的臨時能力。
db糾偏則是db層面指定路由,也是為了兜底,當soa路由出異常,在db層做最后的兜底(可訪問跨機房數據)。
db禁寫保護則是當業務開啟禁寫保護,非本機房的訂單無法在本訂單操作,也是db兜底保護的一種。
3、消息
消息則分為發送和消費。
對于發送來說,單元到中心的復制和中心到單元的復制,則都是一個機房消息復制到另外機房,也是無法單元化的一種解決方案。當然該方案也可以兼容雙活應用發送消息和非雙活應用消費者的問題。
消費本機房:只能消費本機房產生的消息,異地機房的復制消息無法消費。
都不消費:代表本機房和異地機房都不消費。
消費本機房和異地機房消息,則代表消息消費本機房和異地機房消息(消費雙份消息)。
4、soa
soa接口需要根據特定的條件將rpc請求路由到正常的機房。
服務提供方路由則表示該路由規則由服務提供方指定。
服務消費方路由則表示該路由規則由服務消費方指定。
5、雪花算法
雙活由于zk集群是兩個機房的,需要在雪花算法上打上機房標識,保證全局唯一。
6、業務改造
業務改造大部分是基于中間件方案的改造。而其中的部分方案是基于業務自己述求進行的一些雙活改造點。
1)單元化改造
部分業務邏輯之前在單機房情況下無法做到單元化,需要對部分可單元化的業務進行改造。
2)db緩存一致性
基于訂單可靠性保證,對訂單數據通過binlog消息保障兩機房數據一致性。
3)機房過濾改造
基于機房信息,處理非本機房邏輯,或者過濾非本機房邏輯(目前無法單元化的臨時方案)。
4)單號改造
發單的時候需要將路由規則打到訂單號上,在修改訂單其他屬性時根據訂單號進行路由(保障單元化)。?