標籤:
轉載請註明出處,歡迎大家批評指正
1、資料服務器詳細設計
資料服務器在設計上採用三個層次的資料同步,實現玩家資料的高速擷取和修改。
資料層次上分為:記憶體資料,redis資料,mysql資料
設計目的:首先保證資料的可靠,防止資料丟失,保證資料完整。然後實現資料的高速訪問,減少由玩家數量增加對資料服務器效能造成的影響。最後實現營運資料的入庫,以及資料持久化。
在這個基礎上資料服務器不再是一個單一伺服器,它涉及到與其他伺服器之間的互動。
資料服務器的核心在於redis資料層面。通過redis加快玩家資料的快速拉取。
記憶體資料是直接與邏輯伺服器進行互動的,因此記憶體資料劃分到邏輯伺服器進行管理,redis資料劃分為資料服務器管理,mysql資料是對redis資料庫的備份和同步。
主要流程,資料服務器啟動時先從mysql資料庫載入所有的活躍玩家相關資料到redis資料庫中,邏輯伺服器與資料服務器之間的互動都是通過國過redis資料進行操作。Redis資料庫回寫到mysql可以通過回寫進程實現。
圖 1 資料服務器資料扭轉流程圖
1.1 資料服務器主進程
資料服務器主進程核心是對redis的操作,通過redis資料庫實現資料的高速儲存。因此,資料服務器的核心是保證在玩家數量大較大的情況下對玩家資料的增刪改都能維持在一定的時間效率內。
針對於redis資料庫本身,可以考慮實現redis的主從庫搭建,保證redis的資料庫的備份和效率。
資料服務器主進程的構成:
1、mysql資料同步到redis資料庫中。
2、邏輯伺服器和資料服務器的網路程式庫
3、玩家賬戶修改緩衝
4、Redis資料庫的回寫至mysql
5、邏輯資料庫的請求處理
6、記憶體資料庫的組織圖
1.2 資料回存服務
資料服務器接收到邏輯伺服器的請求後,就資料庫操作請求進行操作的隊列緩衝,形成操作隊列。操作隊列同時提供了redis資料庫的及時寫入和mysql資料庫的非同步寫入。
1.3 資料服務器提供介面
對於邏輯伺服器,資料服務器應為其開放以下介面:
1、資料拉取介面,拉取對應玩家的所有資料,將資料儲存到記憶體資料中
2、修改玩家資料介面,提供玩家的部分或全部資訊修改命令
2 資料服務器模組功能
首先redis是一種key-value的記憶體資料庫,以key和value的方式來儲存資料實現高速的訪問和操作。其次mysql是一種關係型資料庫,儲存的是結構化的資料。這種差異決定了在資料入庫redis的時候需要做相應的處理。
2.1 資料入庫redis
通過redis的key-value來儲存資料庫中的表名以及表的索引和hashkey,來實現構造二維的資料表。
針對於每張表,key結構 [表名]:[id值]
要求所有的資料庫表的第一個欄位為id,或者所有的表都為主鍵,並且不能重複,這樣保證了所有的key都不重複
圖 2 資料入庫redis後表現結構
入庫流程方法一:
先將redis清空,再將mysql所有的額資料逐條入庫到redis。逐條入庫的好處是可以對玩家進行其他的操作處理,缺點是啟動伺服器速度慢。
方法二:
先將redis資料庫清空,再將mysql讀取處理的資料緩衝成redis識別的事務,一次性進行redis入庫。
2.2 排序
實現高效的排序功能,可以使用redis的zset進行拍尋隊列構建,對於玩家等級或經驗改變時,對redis資料庫進行修改,當需要或擷取排序時直接擷取zset集合類已經拍好的順序就可以實現高效的排序功能
2.3 redis資料回存mysql
對redis資料庫的操作需要回存到mysql資料庫中。
方案一:採用多線程非同步,通過多線程非同步實現mysql修改回存同步。在資料服務器多開一個線程進行回存。
優點:設計結構相對簡單,不涉及到處理序間通訊,但需要多線程開發支援
方案二:採用多進程方式,回存由專門的進程進行,沒有操作訊息redis資料庫預設轉寄進程轉寄。
優點:簡單的單線程即可滿足需求,但需要進程間通訊。
2.4 網路互動模組及序列化
伺服器之間的網路傳輸由統一的網路模組進行。序列化功能採用protobuf的序列化功能。
3 具體實現
資料服務器設計到大多都是表和redis資料操作,這些操作具有相似性。這樣的繁雜的操作不利於手動修改和書寫代碼。
因此在此處合理的運用產生器就會減少很大一部分工作量,通過產生器快速產生C++代碼,並且靈活的應對資料庫結構的更改。
3.1 產生物和產生器
產生器使用了C#語言快速編寫訪問資料庫結構,並產生類代碼。
產生物可以設計成各種語言的操作檔案,目前產生C++檔案。
3.2 Mysql資料回寫進程
資料回寫進程又一個回寫訊息佇列和一個回寫器組成,回寫訊息佇列緩衝所有要進行回寫操作,再有回寫器進行回寫。多線程回寫訊息佇列操作加鎖。
3.3 玩家登陸資訊查詢
玩家登陸時將拉取玩家資料到記憶體中。這個流程現在redis資料庫中查詢玩家資料,如果存在,返回給邏輯伺服器玩家資料,如果redis資料庫中不存在玩家資料,將再次在mysql中進行查詢,如果存在返回給邏輯伺服器,如果不存在返回查詢失敗。具體流程看
圖 3 玩家資料查詢流程
在修改玩家資料時,需要同步三層資料。資料首先是在記憶體中進行修改,然後發起修改命令給資料服務器,資料服務器將修改命令分別壓入redis資料庫命令隊列和mysql命令隊列。再有兩個線程非同步對命令隊列中的命令執行,完成資料回寫。
圖 4 資料回寫命令執行流程
3.4 玩家活躍程度劃分
為了提高資料的訪問速度和效率,將玩家進行活躍度分級。正在遊戲玩家資料載入到記憶體,快速存取。活躍玩家載入到redis資料庫,實現快速拉取。不活躍玩家存放mysql,需要時訪問查詢。
優點:根據資料的訪問頻度對資料進行分級,使得高頻資料快速存取,節約了記憶體空間。
缺點:不活躍玩家登陸時間相對較長,但不影響遊戲效率。登陸後,玩家又再次進入活躍玩家儲存方案。
基於記憶體,redis,mysql的高速遊戲資料服務器設計架構