一、目標(biāo)
能橫向擴(kuò)展,架構(gòu)要簡(jiǎn)單,能做到負(fù)載均衡,避免單節(jié)點(diǎn)負(fù)載太輕的資源浪費(fèi)。
二、數(shù)據(jù)存儲(chǔ)的DB集群
數(shù)據(jù)存儲(chǔ)類型有多種。
(一)非交互性的個(gè)人數(shù)據(jù)
可通過(guò)簡(jiǎn)單的id分段。id為1~10000的玩家個(gè)人數(shù)據(jù)存儲(chǔ)在db1,id為10001~20000的玩家個(gè)人數(shù)據(jù)存儲(chǔ)在db2,以此類推。
(二)交互性數(shù)據(jù)
如好友關(guān)系等。
(1)如果好友關(guān)系可以為單向,那么可以將關(guān)系存到個(gè)人數(shù)據(jù)里。
(2)如果好友關(guān)系不能為單向,那么需要保證每條關(guān)系保持在要么沒(méi)有,要么兩人都認(rèn)同,記數(shù)據(jù)上一直,互相有關(guān)系。那么需要保證相關(guān)的關(guān)系操作的一致性。這樣可能只保存一份每?jī)蓚€(gè)人之間的關(guān)系,k-v存儲(chǔ)時(shí)需要方向查找,不知是否能實(shí)現(xiàn)。
(三)全局?jǐn)?shù)據(jù)
如全局排行榜之類的。這種放在單獨(dú)的庫(kù)里里,專門(mén)做全局?jǐn)?shù)據(jù)的存儲(chǔ)。當(dāng)?shù)揭欢ㄒ?guī)模時(shí),按全局?jǐn)?shù)據(jù)的類型再分庫(kù)。
家族、幫會(huì)等,也放單獨(dú)的庫(kù)里。如果需要擴(kuò)展,再按家族id、幫會(huì)id來(lái)分庫(kù)。
三、邏輯服務(wù)器集群對(duì)DB集群的訪問(wèn)
DB集群的路由規(guī)則配置到邏輯服務(wù)器的config里。當(dāng)需要熱擴(kuò)展DB時(shí),啟動(dòng)新DB后,給各logic服務(wù)器發(fā)送GM指定,reload路由規(guī)則的config。
DB集群路由規(guī)則的config,可以放在一個(gè)公共地方,各logic服務(wù)器接到GM指令后,去公共地方拉取新的config然會(huì)reload。
四、邏輯服務(wù)器集群
為了架構(gòu)的簡(jiǎn)單,可以每個(gè)邏輯服務(wù)器進(jìn)程上都有所有邏輯,擴(kuò)展時(shí),以擴(kuò)展邏輯服務(wù)器進(jìn)程數(shù)量來(lái)達(dá)到。
(一)各邏輯服務(wù)器上玩家分配
邏輯服務(wù)器集群之間的交互。如果邏輯服務(wù)器的使用,也像個(gè)人數(shù)據(jù)存儲(chǔ)的DB那樣id分段——只讓1~10000的玩家登陸logic1,10001~20000的玩家登陸logic2時(shí),這很簡(jiǎn)單,但各id斷的玩家活躍度不定的,做不到負(fù)載均衡啊。
所以是根據(jù)當(dāng)時(shí)的負(fù)載情況,來(lái)推薦玩家登陸閑的邏輯服務(wù)器的。這樣需要有個(gè)全局映射,知道哪個(gè)玩家登陸在哪個(gè)服務(wù)器上。可以將玩家當(dāng)前所在的服務(wù)器id記錄在該玩家的個(gè)人數(shù)據(jù)所在的db里。
(二)邏輯服務(wù)器間的通信
目前項(xiàng)目持久化使用redis,最快出東西,就先考慮redis的優(yōu)勢(shì)。
邏輯服務(wù)器間的通信,通過(guò)全局?jǐn)?shù)據(jù)存儲(chǔ)的redis來(lái)做pub/sub轉(zhuǎn)發(fā)吧。
redis的pub和sub的實(shí)時(shí)性不夠時(shí),將有實(shí)時(shí)性需求的玩家都轉(zhuǎn)到一個(gè)專門(mén)做強(qiáng)實(shí)時(shí)性的特殊邏輯服務(wù)器。
五、PS
公司的項(xiàng)目是Node.js+Redis,業(yè)余時(shí)間打算用Go寫(xiě)個(gè)服務(wù)器引擎。
這篇考慮發(fā)到精華區(qū),可以得到很多的批評(píng)建議。