遊戲數據存儲方案?

同時更改記錄A和記錄B,如何保證數據一致性落地。

大家都有什麼存儲方案呢? nosql的也可以。

目前的思路,相對邏輯代碼比較複雜不可控。

mysql:

1、啟動事務

2、內存變更

3、提交到資料庫,等待回調

4、回調:

成功:處理業務

失敗:回滾,重置內存數據


謝邀。

我目前用的就是類似你說的這個方式。

請求到達 -&> 解包 -&> 啟動內存資料庫事務 -&> 請求路由給對應功能模塊 -&> 執行業務邏輯 -&> (接下來,兩種可能):

1. 正常處理完請求 -&> 提交內存資料庫事務-&> 內存資料庫事務寫入事務日誌 -&> 內存資料庫事務轉成資料庫事務執行

2. 非法請求或程序BUG -&> 拋出異常 -&> 內存資料庫事務回滾

內存資料庫事務轉資料庫事務我試過兩種方式:

1. 動態組裝SQL並執行

2. 用預先prepare好的語句綁定參數執行

兩種都可以,prepare好處就是不需要動態拼接SQL,遊戲端這邊省內存又省CPU,MySQL那邊也省CPU,但是update語句不是動態拼接SQL,要預先prepare語句只能全量更新,之前有擔心效率不行,還好實際運行起來感覺沒啥問題。不過prepare語句有一個數量限制,小心別被坑了就是。

我使用MySQL,所以事先要將MySQL的自動事務提交禁用,改用手工提交事務,否則可能出現同步一半的時候同步程序自身異常導致內存資料庫事務只提交一半到MySQL得情況。

內存資料庫的事務日誌是非常重要的,寫入MySQL之前需要先寫同步日誌,這樣可以在MySQL通信故障時有數據可以還原,不用擔心寫日誌的IO,順序寫入的效率是很好的,絕對沒大負擔。

另外我在同步日誌里記錄了完整新舊數據和請求的類型、玩家ID、事務執行時間,記錄的格式是自定義的二進位文件格式,每個文件頭部有完整的表結構信息,可以用一個對應的分析工具結合lua腳本來分析玩家行為,回查漏洞或者BUG。

也可以從同步日誌截取生成完整的同步用的SQL或者回滾某段時間數據變化的SQL。

生成SQL邏輯很簡單,UPDATE和DELETE不需要特殊處理,INSERT用REPLACE語法替代就可以讓SQL反覆執行,不需要人工精確對比。

內存資料庫因為是自己實現的,所以要實現事務機制沒有多複雜,插入的反操作就是刪除、刪除的反操作就是插入、修改的反操作還是修改。只要把新舊數據記錄下來,要做事務回滾很容易。

內存資料庫的代碼是按MySQL資料庫結構自動映射生成的,所以只需要設計好底層結構,開發人員不需要管這些底層的機制,只需要按功能設計資料庫結構就可以了。


1.保證一致性,用事務加鎖就ok了啊。

2.nosql沒有事務功能的話,可以自己搞一個鎖服務中間件,mysql也可以充當鎖服務中間件。


現在的一款網頁遊戲

請求-解包-處理-更改內存-存redis-每日凌晨存mysql資料庫(redis存七天活躍)

做好log記錄、redis aof 和 mysql binlog並且做了防災主備

有問題特別是元寶問題查看log 做redis操作,如果需要回滾一般是按天回滾,找回mysql,清redis,程序自己從mysql拉取回滾數據。

至於業務處理失敗本身就不會更改內存數據。


nosql 沒有事務概念的如何處理?


BAAS:

LeanCloud

Bmob


推薦閱讀:

如何評價微軟的orleans框架?
遊戲伺服器使用MongoDB作為資料庫,還有必要使用Redis緩存嗎?
作為遊戲客戶端開發,需要掌握哪些伺服器方面的知識,以及如何學習?
手游開發中網路通信使用長連接還是短連接比較好?
互聯網中TCP Socket伺服器的實現過程需要考慮哪些安全問題?

TAG:資料庫 | 遊戲伺服器 |