这里数据IO是指游戏数据存盘和读取。

假设IO处理不好。server在IO时会导致。游戏卡顿较长的时间,严重影响游戏体验。

近期服务端刚好对IO这一块做了优化,把优化过程记录一下。

一 原始版

刚開始立项的时候,仅仅是做了一个Demo,加上也刚開始做服务端,仅仅是做了一个仅仅可以測试用的server。

当时是在每一个场景对象area中加入了一个users对象,通过uid来保存每一个玩家的数据。

当玩家登录的时候,将玩家的数据读入。退出的时候将玩家的数据写回。

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宕机数据丢失,再添加了一个定时存盘。

function onTick(){
for (var uid in users) {
var user = users[uid];
DBMgr.write(user);
}
}

这样做有两个非常明显的问题:

1 假设一个玩家下线之后马上又一次登录,就会又一次IO的过程;

2 每次都须要将所有玩家的数据写入。玩家多了之后会卡非常长时间。

二 进阶版

为了解决如上问题,添加了一个cache。

玩家离线后。先将其数据移到cache中,每隔一段时间,将cache中的玩家写入存储介质中。

登录的时候先在cache中查找玩家的数据,假设找不到。再去读数据。

然后结构就变成了这样:

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];
}
}

然而,前面两个问题并没有彻底地解决掉。

1 假设玩家下线之后。刚好onTick时间到,这样数据就被写回了,下次登录就得又一次读一次;

2 若是在onTick这个周期内下线的玩家太多。onTick之中还是会有非常多玩具须要写入。

三 终极版

为了优化前面的两点,不再玩家的数据移到cache,而是在cache中保存玩家的下次存盘时间。

每次登录直接在users中找数据,假设找不到,就读数据库。

假设玩家下线。就将其下次存盘时间在变为对应的负数,来标记玩家已经下线。

在onTick中,先将到存盘时间的玩家存盘,然后已下线的玩家从users和cache中同一时候移除。

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为存盘间隔时间
}
} 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;
}
}
};

这种结构定时存盘一批玩家数据,即使玩家离线也能够在内存中保存一段时间。

眼下我们的服务端存盘机制就是这种,假设以后有优化再补充。

手游server之数据IO进化的更多相关文章

  1. 记一个手游app数据文件的破解

    出于一些非常猥琐的须要,同一时候自己也想做一些新奇的尝试,周末用了大半天时间破解了某款手游的数据文件. 过程比我预想的要顺利,主要原因还是我们开发者的懈怠.咳咳. 步骤例如以下: 下载安装包,解压,发 ...

  2. Cocos2d-x手游技术分享(1)-【天天打蚊子】数据存储与音效篇

    前言: 手游项目<天天打蚊子>终于上线,特地写几篇技术分享文章,分享一下其中使用到的技术,其中使用cocos2d-x引擎,首选平台iOS,也请有iPhone或者iPad的朋友帮忙下载好评. ...

  3. 如何从“点子”落地到“执行”?—完整解析1个手游传播类mini项目的进化

    本文来自网易云社区 作者:林玮园 从点子到落地,是不确定到确定的过程,是从模糊概念到具体现实的实现过程.无论什么点子,在落地变现的过程中都会有很多疑问产生. 首先,不确定点子本身是否成立.点子的背后是 ...

  4. SLG手游Java服务器的设计与开发——数据管理

    文章版权归腾讯GAD所有,禁止匿名转载:禁止商业使用:禁止个人使用. 一.前言 上文介绍了我们的SLG手游的服务器架构设计以及网络通信部分,本文介绍数据管理部分,在数据存储方面,我选择了Mysql.M ...

  5. Unity3D手游开发实践

    <腾讯桌球:客户端总结> 本次分享总结,起源于腾讯桌球项目,但是不仅仅限于项目本身.虽然基于Unity3D,很多东西同样适用于Cocos.本文从以下10大点进行阐述: 架构设计 原生插件/ ...

  6. 腾讯首度公开S级手游品质管理方法

    weimjsam   引言 在最新的手游市场占有率统计中,腾讯游戏稳稳占据一半江山,目前仍以每月一到两款的速度推出新品,在如此复杂多变.响应要求极高的市场环境下,能持续推出高质量产品并保持高效迭代更新 ...

  7. 手游Apk破解疯狂,爱加密apk加固保护开发人员

    2013年手游行业的规模与收入均实现了大幅增长,发展势头强劲.权威数据显示, 我国移动游戏市场实际销售收入从2012年的32.4亿猛增到2013年的112.4亿元,同比增长了246.9%,手游用户从2 ...

  8. SLG手游Java服务器的设计与开发——架构分析

    微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...

  9. 《疯狂iOS讲义(下)——iPhone/iPad高级应用与手游开发(含CD光盘1张)》

    <疯狂iOS讲义(下)——iPhone/iPad高级应用与手游开发(含CD光盘1张)> 基本信息 作者: 李刚    肖文吉 出版社:电子工业出版社 ISBN:9787121224379 ...

随机推荐

  1. Oracle_备份整库

    @echo off color 0b & cls echo echo 设置备份文件存放文件夹... echo set "tbuf=C:\OracleBackup" if n ...

  2. ES6 Template String 模板字符串

    模板字符串(Template String)是增强版的字符串,用反引号(`)标识,它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量. 大家可以先看下面一段代码: $(&quo ...

  3. ajax 三级联动写法

    主页面代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  4. php常见报错

    Php常见错误提示 一.Fatal error: Call to undefined function……函数不存在,可能的原因:系统不存在这个函数且你也没自定义 二.syntax error, un ...

  5. Python3爬虫----爬取网页内的图片

    无聊把公司内网爬了一遍. https://github.com/gig886/Python/tree/master/爬虫

  6. webSphere

    WebSphere 是 IBM 的软件平台.它包含了编写.运行和监视全天候的工业强度的随需应变 Web 应用程序和跨平台.跨产品解决方案所需要的整个中间件基础设施,如服务器.服务和工具.WebSphe ...

  7. (转)OL记载Arcgis Server切片

    http://blog.csdn.net/gisshixisheng/article/details/47955787 概述: 本文讲述如何在OpenLayers中调用Arcgis Server切片并 ...

  8. pytorch实战(7)-----卷积神经网络

    一.卷积: 卷积在 pytorch 中有两种方式: [实际使用中基本都使用 nn.Conv2d() 这种形式] 一种是 torch.nn.Conv2d(), 一种是 torch.nn.function ...

  9. 6.2 C# 2:利用 yield 语句简化迭代器

    class Program { static void Main(string[] args) { object[] values = new object[] { "a", &q ...

  10. 【JavaScript框架封装】使用原生js封装的类似于JQuery的框架及核心源码分享(多文件版本)

    这个版本的JQuery是对上一个版本的JQuery,使用了require.js进行了二次封装,基本上把前面的每一个框架封装成为一个单独的模块,最终的目录结构如下: 由于代码量和目录比较多,这个封装好的 ...