基於內存,redis,mysql的高速遊戲數據服務器設計架構

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、修改玩家數據接口,提供玩家的部分或全部信息修改命令

數據服務器模塊功能

首先redis是一種key-value的內存數據庫,以keyvalue的方式來存儲數據實現高速的訪問和操作。其次mysql是一種關係型數據庫,存儲的是結構化的數據。這種差異決定了在數據入庫redis的時候需要做相應的處理。

2.1 數據入庫redis

通過rediskey-value來存儲數據庫中的表名以及表的索引和hashkey,來實現構造二維的數據表。

針對於每張表,key結構 [表名][id]

要求所有的數據庫表的第一個字段爲id,或者所有的表都爲主鍵,並且不能重複,這樣保證了所有的key都不重複

 

圖 2 數據入庫redis後表現結構

 

入庫流程方法一:

先將redis清空,再將mysql所有的額數據逐條入庫到redis。逐條入庫的好處是可以對玩家進行其他的操作處理,缺點是啓動服務器速度慢。

方法二:

先將redis數據庫清空,再將mysql讀取處理的數據緩存成redis識別的事務,一次性進行redis入庫。

2.2 排序

實現高效的排序功能,可以使用rediszset進行拍尋隊列構建,對於玩家等級或經驗改變時,對redis數據庫進行修改,當需要或獲取排序時直接獲取zset集合類已經拍好的順序就可以實現高效的排序功能

2.3 redis數據回存mysql 

redis數據庫的操作需要回存到mysql數據庫中。

方案一:採用多線程異步,通過多線程異步實現mysql修改回存同步。在數據服務器多開一個線程進行回存。

優點:設計結構相對簡單,不涉及到進程間通信,但需要多線程開發支持

方案二:採用多進程方式,回存由專門的進程進行,沒有操作消息redis數據庫默認轉發進程轉發。

優點:簡單的單線程即可滿足需求,但需要進程間通訊。

2.4 網絡交互模塊及序列化

服務器之間的網絡傳輸由統一的網絡模塊進行。序列化功能採用protobuf的序列化功能。

具體實現

數據服務器設計到大多都是表和redis數據操作,這些操作具有相似性。這樣的繁雜的操作不利於手動修改和書寫代碼。

因此在此處合理的運用生成器就會減少很大一部分工作量,通過生成器快速生成C++代碼,並且靈活的應對數據庫結構的更改。

3.1 生成物和生成器

生成器使用了C#語言快速編寫訪問數據庫結構,並生成類代碼。

生成物可以設計成各種語言的操作文件,目前生成C++文件。

 

3.2 Mysql數據回寫進程 

數據回寫進程又一個回寫消息隊列和一個回寫器組成,回寫消息隊列緩存所有要進行回寫操作,再有回寫器進行回寫。多線程回寫消息隊列操作加鎖。

 

3.3 玩家登陸信息查詢

玩家登陸時將拉取玩家數據到內存中。這個流程現在redis數據庫中查詢玩家數據,如果存在,返回給邏輯服務器玩家數據,如果redis數據庫中不存在玩家數據,將再次在mysql中進行查詢,如果存在返回給邏輯服務器,如果不存在返回查詢失敗。具體流程看下圖

 

    

                圖 3 玩家數據查詢流程

在修改玩家數據時,需要同步三層數據。數據首先是在內存中進行修改,然後發起修改命令給數據服務器,數據服務器將修改命令分別壓入redis數據庫命令隊列和mysql命令隊列。再有兩個線程異步對命令隊列中的命令執行,完成數據回寫。

 

圖 4 數據回寫命令執行流程

3.4 玩家活躍程度劃分 

爲了提高數據的訪問速度和效率,將玩家進行活躍度分級。正在遊戲玩家數據加載到內存,快速訪問。活躍玩家加載到redis數據庫,實現快速拉取。不活躍玩家存放mysql,需要時訪問查詢。

優點:根據數據的訪問頻度對數據進行分級,使得高頻數據快速訪問,節約了內存空間。

缺點:不活躍玩家登陸時間相對較長,但不影響遊戲效率。登陸後,玩家又再次進入活躍玩家存儲方案。



轉自:http://www.cnblogs.com/captainl1993/p/4788236.html

發佈了67 篇原創文章 · 獲贊 19 · 訪問量 27萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章