在很長一段時間內(nèi),分布式系統(tǒng)都采用無狀態(tài)服務(wù)作為分布式系統(tǒng)擴展的最佳實踐。它可以通過簡單的循環(huán)負(fù)載均衡來提供擴展能力徘键。它的缺點則在于數(shù)據(jù)中心之間復(fù)雜的一致性問題懈万。
這里有一篇關(guān)于有狀態(tài)服務(wù)(PPT)的分享恳不。這篇分享介紹了基于Azure的Orleans開發(fā)Halo4的經(jīng)驗桃焕。Orleans基于有狀態(tài)分布式的Actor模型,節(jié)點之間實現(xiàn)了高可用的Gossip協(xié)議,一個兩層的一致性哈希加上分布式哈希表÷χ埽基于這些方案提供節(jié)點動態(tài)負(fù)載均衡筐付,動態(tài)擴縮容,熱點平衡轉(zhuǎn)移等等。
下面簡單說一下如何使用有狀態(tài)服務(wù):
無狀態(tài)服務(wù)帶來額外開銷
無狀態(tài)服務(wù)可以通過添加節(jié)點來實現(xiàn)線性可擴展能力的提升说庭。問題在于,我們開發(fā)的應(yīng)用場景是有狀態(tài)的郑趁,這意味著我們需要通過sharding或者NoSQL來實現(xiàn)擴容口渔。這又喪失了關(guān)系型數(shù)據(jù)庫關(guān)于強一致性的保證。
對于單個用戶穿撮,經(jīng)常需要把這個用戶的所有請求路由到同一臺服務(wù)器上缺脉,這樣可以通過本地數(shù)據(jù)緩存的措施來減少IO開銷。
集群信息:
- 靜態(tài)配置 配置一份包含所有集群信息的靜態(tài)文件分發(fā)到所有機器上悦穿,缺點在于不夠靈活攻礼,線上發(fā)生故障需要手動調(diào)整配置,不支持動態(tài)擴容縮容栗柒。
- Gossip協(xié)議 穩(wěn)定狀態(tài)下礁扮,系統(tǒng)中所有節(jié)點對于節(jié)點的健康狀態(tài)能夠達(dá)成共識,在發(fā)生網(wǎng)絡(luò)分區(qū)或者節(jié)點加入/離開時瞬沦,可能會出現(xiàn)短暫的不一致情況太伊。
- 共識算法 保證所有節(jié)點的一致性,缺點在于可能會是整個系統(tǒng)速度的瓶頸逛钻。
路由策略:
- 隨機路由 一般是根據(jù)機器的處理能力進(jìn)行按處理能力的路由僚焦。
- 一致性哈希 問題在于可能會出現(xiàn)熱點問題,需要精心選擇哈希鍵曙痘。
3.分布式哈希表(DHT) 動態(tài)哈希表保存服務(wù)狀態(tài)芳悲。
三個例子:
Facebook的Scuba
一個高速的基于內(nèi)存的分布式數(shù)據(jù)庫,使用了靜態(tài)成員信息配置边坤,寫時采用隨機分發(fā)策略名扛,讀取操作有中間件進(jìn)行聚合返回,不保證可用茧痒。
Uber的Ringpop
Ringpop是一個實現(xiàn)了程序?qū)蛹壏制膎ode.js庫肮韧,采用了Swim Gossip協(xié)議維護集群信息,這個協(xié)議基于AP所以不保證強一致性旺订,一致性哈希負(fù)責(zé)處理請求路由弄企,所以有可能出現(xiàn)熱點問題。
微軟的Orleans
Orleans是一個基于分布式系統(tǒng)的Actor模型耸峭,Actor是計算的核心單元桩蓉,彼此之間使用異步消息通信,它持有一系列狀態(tài)機所以本身是有狀態(tài)的劳闹,Gossip協(xié)議負(fù)責(zé)集群信息院究,路由策略是一致性哈希與分布式哈希表的結(jié)合:當(dāng)向集群發(fā)送對Actor的請求時洽瞬,Orleans運行時將計算對Actor ID的一致哈希。哈希映射到具有該ID的分布式哈希表的計算機业汰;Actor的分布式哈希表知道哪個機器包含指定ID的Actor伙窃。
有狀態(tài)模型帶來的挑戰(zhàn):
需要關(guān)注服務(wù)器內(nèi)存狀況,緩存建設(shè)問題样漆,第一次鏈接問題等等为障。