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