2012年9月20日 星期四

遊戲系統定時更新資料

曾經在兩年前問過小海
我要做個像線上遊戲(MMO)那種自動回血的機制
難道要一直 update Database 嗎?
這樣不是很操系統

那時討論的結論似乎是
也只有這種方法啊 定時(3秒/5秒)就 update 一次 DB
不然也辦不到自動回血
而麻煩的是 每個玩家回血的速度要是不一樣
又多了判斷式 那真的是把CPU跟IO都操光了 Orz

今天把兩年前寫的 system 檔案拿出來看
似乎是這樣的結論沒錯
暴力法隔n時間 update 一次

時至今日程式架構一輪跑完了
要回頭開始補齊一些當初只寫個雛形的地方了
首先就是 system 這部份

先來看目前架構圖

有鑒於這兩年科技發展
又碰到了一些新的東西
這兩天重新想了一下 System Update 機制
似乎有更好的兩種方法可以使用
1. 把需要即時更新的資料放到 memcached, 使用node.js來 update
2. player table 新增 last_update 的 field, 等下次更新取出這兩次更新的差時來 update 回血...etc

第一點很不錯, IO徹底的降低, 需要修正的地方如下
#1 把 online 玩家需要即時更新的資料放到 memcached
#2 原本對 MySQL 更新的地方(user command)改成對 memcached 更新
#3 要處理 MySQL 跟 memcached 的同步問題, 也就是定時要 sync 回 MySQL
#4 使用者登出或是 session timeout 時也要 sync 一次回 MySQL
#5 node.js 定時更新 memcached 裡面的資料
#6 定時 sync memcached 資料回 MySQL採用 node.js (上面的 #3, #4)

第二點
很意外的又想到 當下不需要使用的資料其實沒必要去更新它
畢竟沒有及時需求也沒有代表性
所以新增個最後更新時間的欄位(last_update)
等下次更新的時候取出這兩次更新的差時來計算要更新多少資料回去
需要修正的地方如下
#1 update player 的時候順便計算兩次 update 的差時
#2 用差時來計算所需要更新的資料 並寫回 MySQL

本來想用第一點 雖然要改的很多但是感覺就夠潮
可是有個麻煩的地方就是
這個遊戲的戰鬥系統 可以去攻擊未上線的玩家
且未上線的玩家 也要能夠自動回血
所以第一點蠻適用於現在的 MMORPG 因為只有 online 玩家要處理
我總不可能把所有 MySQL 的 online/offline 玩家都 load 到 memcached
這樣太龐大了

所以退而求其次放棄潮 用第二點的方法
且我不知道何時就已經有這個 last_update 這欄位了 神奇
寫這篇是想把想法整理過再來寫 code
如果有問題會再回來回應 XD

沒有留言:

張貼留言

開放匿名留言 請大家注意網路禮儀