轉載請註明出處,歡迎你們批評指正mysql
數據服務器在設計上採用三個層次的數據同步,實現玩家數據的高速獲取和修改。redis
數據層次上分爲:內存數據,redis數據,mysql數據sql
設計目的:首先保證數據的可靠,防止數據丟失,保證數據完整。而後實現數據的高速訪問,減小由玩家數量增長對數據服務器性能形成的影響。最後實現運維數據的入庫,以及數據持久化。數據庫
在這個基礎上數據服務器再也不是一個單一服務器,它涉及到與其餘服務器之間的交互。緩存
數據服務器的核心在於redis數據層面。經過redis加快玩家數據的快速拉取。服務器
內存數據是直接與邏輯服務器進行交互的,所以內存數據劃分到邏輯服務器進行管理,redis數據劃分爲數據服務器管理,mysql數據是對redis數據庫的備份和同步。網絡
主要流程,數據服務器啓動時先從mysql數據庫加載全部的活躍玩家相關數據到redis數據庫中,邏輯服務器與數據服務器之間的交互都是經過國過redis數據進行操做。Redis數據庫回寫到mysql能夠經過回寫進程實現。多線程
圖 1 數據服務器數據扭轉流程圖運維
數據服務器主進程核心是對redis的操做,經過redis數據庫實現數據的高速存儲。所以,數據服務器的核心是保證在玩家數量大較大的狀況下對玩家數據的增刪改都能維持在必定的時間效率內。異步
針對於redis數據庫自己,能夠考慮實現redis的主從庫搭建,保證redis的數據庫的備份和效率。
數據服務器主進程的構成:
一、mysql數據同步到redis數據庫中。
二、邏輯服務器和數據服務器的網絡庫
三、玩家帳戶修改緩存
四、Redis數據庫的回寫至mysql
五、邏輯數據庫的請求處理
六、內存數據庫的組織結構
數據服務器接收到邏輯服務器的請求後,就數據庫操做請求進行操做的隊列緩衝,造成操做隊列。操做隊列同時提供了redis數據庫的及時寫入和mysql數據庫的異步寫入。
對於邏輯服務器,數據服務器應爲其開放如下接口:
一、數據拉取接口,拉取對應玩家的全部數據,將數據保存到內存數據中
二、修改玩家數據接口,提供玩家的部分或所有信息修改命令
首先redis是一種key-value的內存數據庫,以key和value的方式來存儲數據實現高速的訪問和操做。其次mysql是一種關係型數據庫,存儲的是結構化的數據。這種差別決定了在數據入庫redis的時候須要作相應的處理。
經過redis的key-value來存儲數據庫中的表名以及表的索引和hashkey,來實現構造二維的數據表。
針對於每張表,key結構 [表名]:[id值]
要求全部的數據庫表的第一個字段爲id,或者全部的表都爲主鍵,而且不能重複,這樣保證了全部的key都不重複
圖 2 數據入庫redis後表現結構
入庫流程方法一:
先將redis清空,再將mysql全部的額數據逐條入庫到redis。逐條入庫的好處是能夠對玩家進行其餘的操做處理,缺點是啓動服務器速度慢。
方法二:
先將redis數據庫清空,再將mysql讀取處理的數據緩存成redis識別的事務,一次性進行redis入庫。
實現高效的排序功能,可使用redis的zset進行拍尋隊列構建,對於玩家等級或經驗改變時,對redis數據庫進行修改,當須要或獲取排序時直接獲取zset集合類已經拍好的順序就能夠實現高效的排序功能
對redis數據庫的操做須要回存到mysql數據庫中。
方案一:採用多線程異步,經過多線程異步實現mysql修改回存同步。在數據服務器多開一個線程進行回存。
優勢:設計結構相對簡單,不涉及到進程間通訊,但須要多線程開發支持
方案二:採用多進程方式,回存由專門的進程進行,沒有操做消息redis數據庫默認轉發進程轉發。
優勢:簡單的單線程便可知足需求,但須要進程間通信。
服務器之間的網絡傳輸由統一的網絡模塊進行。序列化功能採用protobuf的序列化功能。
數據服務器設計到大多都是表和redis數據操做,這些操做具備類似性。這樣的繁雜的操做不利於手動修改和書寫代碼。
所以在此處合理的運用生成器就會減小很大一部分工做量,經過生成器快速生成C++代碼,而且靈活的應對數據庫結構的更改。
生成器使用了C#語言快速編寫訪問數據庫結構,並生成類代碼。
生成物能夠設計成各類語言的操做文件,目前生成C++文件。
數據回寫進程又一個回寫消息隊列和一個回寫器組成,回寫消息隊列緩存全部要進行回寫操做,再有回寫器進行回寫。多線程回寫消息隊列操做加鎖。
3.3 玩家登錄信息查詢
玩家登錄時將拉取玩家數據到內存中。這個流程如今redis數據庫中查詢玩家數據,若是存在,返回給邏輯服務器玩家數據,若是redis數據庫中不存在玩家數據,將再次在mysql中進行查詢,若是存在返回給邏輯服務器,若是不存在返回查詢失敗。具體流程看下圖
圖 3 玩家數據查詢流程
在修改玩家數據時,須要同步三層數據。數據首先是在內存中進行修改,而後發起修改命令給數據服務器,數據服務器將修改命令分別壓入redis數據庫命令隊列和mysql命令隊列。再有兩個線程異步對命令隊列中的命令執行,完成數據回寫。
圖 4 數據回寫命令執行流程
3.4 玩家活躍程度劃分
爲了提升數據的訪問速度和效率,將玩家進行活躍度分級。正在遊戲玩家數據加載到內存,快速訪問。活躍玩家加載到redis數據庫,實現快速拉取。不活躍玩家存放mysql,須要時訪問查詢。
優勢:根據數據的訪問頻度對數據進行分級,使得高頻數據快速訪問,節約了內存空間。
缺點:不活躍玩家登錄時間相對較長,但不影響遊戲效率。登錄後,玩家又再次進入活躍玩家存儲方案。