日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

手游server之数据IO进化

發(fā)布時(shí)間:2023/11/29 编程问答 56 豆豆
生活随笔 收集整理的這篇文章主要介紹了 手游server之数据IO进化 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
這里數(shù)據(jù)IO是指游戲數(shù)據(jù)存盤和讀取。


假設(shè)IO處理不好。server在IO時(shí)會(huì)導(dǎo)致。游戲卡頓較長(zhǎng)的時(shí)間,嚴(yán)重影響游戲體驗(yàn)。


近期服務(wù)端剛好對(duì)IO這一塊做了優(yōu)化,把優(yōu)化過(guò)程記錄一下。



一 原始版

剛開(kāi)始立項(xiàng)的時(shí)候,僅僅是做了一個(gè)Demo,加上也剛開(kāi)始做服務(wù)端,僅僅是做了一個(gè)僅僅可以測(cè)試用的server。


當(dāng)時(shí)是在每一個(gè)場(chǎng)景對(duì)象area中加入了一個(gè)users對(duì)象,通過(guò)uid來(lái)保存每一個(gè)玩家的數(shù)據(jù)。
當(dāng)玩家登錄的時(shí)候,將玩家的數(shù)據(jù)讀入。退出的時(shí)候?qū)⑼婕业臄?shù)據(jù)寫回。

var users = {};function onLogin(uid){var user = DBMgr.read(uid);users[uid] = user; }function onLogout(uid){var user = users[uid];DBMgr.write(user);delete users[uid]; }
為了防止server宕機(jī)數(shù)據(jù)丟失,再添加了一個(gè)定時(shí)存盤。
function onTick(){for (var uid in users) {var user = users[uid];DBMgr.write(user);} }
這樣做有兩個(gè)非常明顯的問(wèn)題:
1 假設(shè)一個(gè)玩家下線之后馬上又一次登錄,就會(huì)又一次IO的過(guò)程;
2 每次都須要將所有玩家的數(shù)據(jù)寫入。玩家多了之后會(huì)卡非常長(zhǎng)時(shí)間。



二 進(jìn)階版

為了解決如上問(wèn)題,添加了一個(gè)cache。


玩家離線后。先將其數(shù)據(jù)移到cache中,每隔一段時(shí)間,將cache中的玩家寫入存儲(chǔ)介質(zhì)中。


登錄的時(shí)候先在cache中查找玩家的數(shù)據(jù),假設(shè)找不到。再去讀數(shù)據(jù)。


然后結(jié)構(gòu)就變成了這樣:

var users = {}; var cache = {};function onLogin(uid){if (!!cache[uid]) {users[uid] = cache[uid];delete cache[uid];} else {users[uid] = DBMgr.read(uid);} }function onLogout(uid){var user = users[uid];cache[uid] = user;delete users[uid]; }function onTick(){for (var uid in cache) {var user = cache[uid];DBMgr.write(user);delete cache[uid];} }
然而,前面兩個(gè)問(wèn)題并沒(méi)有徹底地解決掉。


1 假設(shè)玩家下線之后。剛好onTick時(shí)間到,這樣數(shù)據(jù)就被寫回了,下次登錄就得又一次讀一次;
2 若是在onTick這個(gè)周期內(nèi)下線的玩家太多。onTick之中還是會(huì)有非常多玩具須要寫入。

三 終極版

為了優(yōu)化前面的兩點(diǎn),不再玩家的數(shù)據(jù)移到cache,而是在cache中保存玩家的下次存盤時(shí)間。
每次登錄直接在users中找數(shù)據(jù),假設(shè)找不到,就讀數(shù)據(jù)庫(kù)。


假設(shè)玩家下線。就將其下次存盤時(shí)間在變?yōu)閷?duì)應(yīng)的負(fù)數(shù),來(lái)標(biāo)記玩家已經(jīng)下線。


在onTick中,先將到存盤時(shí)間的玩家存盤,然后已下線的玩家從users和cache中同一時(shí)候移除。

var users = {}; var cache = {};function onLogin(uid){var user = users[uid];if (!user) {user = DBMgr.read(uid);users[uid] = user;cache[uid] = curTime + WRITE_GAP;// WRITE_GAP為存盤間隔時(shí)間} }function onLogout(uid){cache[uid] = 0 - (curTime + WRITE_GAP); }function onTick() {for (var uid in cache) {var time = cache[uid];if (curTime < Math.abs(time)) {continue;}DBMgr.write(users[uid]);if (time < 0) { // 離線玩家delete users[uid];delete cache[uid];} else { // 在線玩家cache[uid] = curTime + WRITE_GAP;}} };

這種結(jié)構(gòu)定時(shí)存盤一批玩家數(shù)據(jù),即使玩家離線也能夠在內(nèi)存中保存一段時(shí)間。

眼下我們的服務(wù)端存盤機(jī)制就是這種,假設(shè)以后有優(yōu)化再補(bǔ)充。

轉(zhuǎn)載于:https://www.cnblogs.com/wzjhoutai/p/6940512.html

總結(jié)

以上是生活随笔為你收集整理的手游server之数据IO进化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。