分區分服與大規模跨服功能


© 內容版權所有,轉載或複製需附源站地址 www.tanjp.com 謝謝合作。

變更記錄

2020-04-24, tanjp, 編寫第一版 整體的架構設想。

名詞說明

分區分服,是指遊戲服務端的部署上劃分不同的遊戲入口,直接的感受就是玩家需要選擇一個服務器進行登錄後再創建角色進行遊戲。具體的劃分按運營的需求,可按地區劃分不同的服,如A區[1服~10服],B區[11服~20服],等等。


大規模跨服,是指不同地區服務器上的玩家可以一起玩耍,如A區1服玩家A與B區20服玩家,可以加好友,加入同一個公會,可以聊天,就一個問題討論,可以組隊去PVE,或者去跟另一組進行PVP,等等。

一、總體架構設計圖


遊戲服務端架構 - 分區分服與大規模跨服功能

二、數據存儲

2.1 數據存儲分類

  1. 角色數據,就是一個玩家自身的屬性變化,如揹包,經驗等級,等等。(一般採用整塊回寫)
  2. 社交數據,就是把多個玩家的數據通過某種形式的整合,如公會,好友,聊天,組隊,等等。(實時回寫或定時回寫)
  3. 狀態數據,不被用戶感知,但是在程序實現過程中的邏輯狀態,如在線狀態,XXX標記,緩存狀態,能否被刪除,等等。(一般存在於內存,可根據需要是否落地,或者緩衝在Redis,可全局訪問)
  4. 環境數據,在架構全局中起到分配或者負載均衡作用,又或者啟動了哪些進程?數據與進程之間的關係如何?(可以是配置信息,動態部署數據)

NOTE: 數據落地保證冪等性,避免重複寫入導致數據錯誤。

2.2 存儲方案

1) 角色數據存儲,採用 MongoDB 存儲。

每個角色服對應一個數據庫,角色數據一旦創建就永遠存在於該數據庫,合服也無需進行數據遷移。一般來說,一個服一般是導入2~3萬左右角色數量,不同的功能劃分存儲在不同的 document 即可。RoleDBS 為角色存儲服務,專職負責數據庫的讀寫,根據讀寫的壓力,可適當調整單DBS負載數 S。

具體結構如下圖:

遊戲服務端架構 - 分區分服與大規模跨服功能

2) 社交數據存儲,採用 MongoDB 存儲。

社交數據是所有服共用的一份數據,而且數據量根據不同的功能有所不同,甚至差異很大。譬如公會,假設全服公會數量最多有10萬個,每個公會里有許多條角色信息,並且每個工會都有一個公會玩法數據(假設較大10M),如此一來最大可能公會數據就有1000G數據,就需要進行數據劃分。假設劃分為100個數據庫,每個最大為10G,當然還有一個所有公會概要信息數據庫,最多也就是10萬條數據。

具體結構如下圖:

遊戲服務端架構 - 分區分服與大規模跨服功能

3) 狀態數據存儲,採用多個 Redis 按一致性HASH的方式存儲。

這裡的狀態數據,可能有些必須要存儲於內存。有些需要落地到硬盤,以便服務器重啟後數據依舊可用。譬如,玩家的在線狀態,只需要存在內存,一旦玩家下線了就可以刪除或者修改為下線。而玩家的簡要信息可能會被各個系統訪問,如各種等級,頭像框,戰鬥力等等,而且服務器重啟也要能訪問。因此,存儲於 Redis 的數據分為兩類,一類狀態數據需要落地,另一類狀態數據只需存在於內存

另外,考慮到用戶量可能會相當大,假如百萬用戶在線(雖然只有極少數遊戲或者公司能達到),日活估計得千萬,也就是說狀態緩存得千萬用戶級別。所以需要把狀態劃分多個存儲於 Redis 上,假如是千萬緩存用戶量,每個用戶緩存的數據量為 10KB,千萬用戶就是要 100GB 的緩存 ,每個 Redis 實例不超過 10GB的話,就需要 10個 Redis 實例。所以需要按用戶ID 映射到不同的 Redis 實例上,實現均衡分佈。

具體結構如下圖:

遊戲服務端架構 - 分區分服與大規模跨服功能

4) 環境數據存儲,採用 Zookeeper 集群存儲。

多進程分佈式的架構,往往會有幾十個甚至幾百上千個進程在同時運行而組成整套系統。所以,必須要統一的配置管理,由訂閱發佈機制來實現所有進程的配置更新。還有當幾百個進程同時在協作時,很難避免有個別進程由於各種原因導致不可用,這時就需要用新的服務節點替換故障的節點,這就涉及服務治理和服務發現。這一塊,還有挺多學問,還需日後繼續深入深究。


三、玩家交互

3.1 與玩家交互的四種方式

  1. 賬號登錄驗證,選服推薦,白名單機制,入口管理,等等。主要採用 Web HTTP的方式進行交互,主要保障高併發和高可用,由於這些功能都比較簡單,通過 Nginx 多節點負載均衡的方式,就能達到很好的效果。
  2. 賬號登錄成功並選服後,客戶端直連角色邏輯服,然後就是開始頻繁的交互,進入正常的遊戲邏輯。
  3. 當玩家參與了一個跨服玩法時,需要與其他區服的玩家進行一場強交互的玩法時,就需要把所有相關玩家都連接到另外一個玩法房間,此時客戶端與服務端之間保持量兩條網絡連接,分別負責不同的功能職責。
  4. 遊戲內往往有一些內嵌的網頁小活動,這種交互也是通過 HTTP 請求與 Nginx 交互,並轉發到服務端內部。

3.2 跨服玩法的特點分類

  1. 多人在較為短的時間強交互(頻繁的操作和響應),這種採用跨服房間的方式實現,多個客戶端同時連到該房間,進行強交互的玩法,並且在最後結算的時候才發放相關的獎勵。
  2. 多人在很長的時間裡進行弱交互(操作和響應不頻繁),這種採用類似公會系統的實現方式,在服務端內部通過RPC調用內部服務來完成功能玩法的實現,最為關鍵就是處理好數據一致性問題。
  3. 介於強交互與弱交互之間的玩法,得根據需求的複雜性來決定到底如何實現。

四、進程職責

  1. DBS進程(存儲服)負責最大限度發掘數據庫存取性能,除了Nginx,所有其他進程讀寫數據都是通過DBS來完成。DBS是獨立無狀態的集群,只為各個進程提供準確讀寫數據庫的服務。
  2. route進程(路由服)只作為轉發進程,只負責高性能的數據轉發服務。route是無狀態集群,每個進程都連上所有路由,任何一個路由都能轉發數據,但需在業務層按策略實現負載均衡。
  3. role進程(角色服)為指定區服的客戶端提供服務,同時連接到route進程,調用其他社交系統的接口。可按運營策略進行動態擴展。
  4. room進程(房間服)為不同區服的客戶端提供一個一起玩耍的跨服玩法服務,同時連接到route進程調用其他社交系統的接口。可根據具體玩法的負載情況,實現動態分配和擴展。
  5. social類進程(社交服),連接到route進程,為各服所有玩家提供社交系統接口,根據系統負載情況,可預先設定進程數量以滿足需求,也可實現服務治理與服務發現。
  6. 主要存儲數據庫採用 MongoDB, 採用 Redis 存儲全局狀態管理,採用 Zookeeper 來實現配置管理和服務發現。
  7. 充值流水等核心數據採用 Mysql 存儲。實時的錯誤信息或關鍵信息的上報和監控,也採用 Mysql 來存儲。
  8. 非核心的流水日誌或運行日誌,用 filebeat 和 logstash 進行採集,並導入 Elasticsearch,並實現關鍵信息的監控和報警功能。

五、運維監控

  1. 運行日誌監控關鍵字 ERROR,並作告警處理。
  2. 流水日誌按策劃需求,監控異常數據的發生,並告警。
  3. 所有進程的CPU,內存,通訊延時監控。
  4. 邏輯功能監控,在線人數,緩存人數,公會數量,組隊數量,地圖數量,等等。
  5. RPC成功率,各個Actor佔用內存,關鍵函數執行時間。
  6. 運維操作,自動部署,啟動,關閉,重啟,更新,維護狀態,等等。

© 內容版權所有,轉載或複製需附源站地址 www.tanjp.com 謝謝合作。


分享到:


相關文章: