手游server之数据IO进化
假設(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ù)寫回。
為了防止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)就變成了這樣:
然而,前面兩個(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í)候移除。
這種結(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)題。
- 上一篇: HDU Victor and World
- 下一篇: PLC基础入门