您的位置:首页 > 运维架构 > 网站架构

一种新型的游戏服务器架构CDDE

2016-02-26 13:49 561 查看
1.传统的数据模式以整个实体数据读出,处理完成后,整体数据再写入。而在游戏行业,对同一数据的操作频繁性,使得传统处理方式更容易的暴露所在的瓶颈,所有的业务逻辑都压在数据库的负载上,导致可用性以及响应速度的下降。

为了解决这类问题,常规的做法就是在数据库之前防止一层缓存层,减少对同一数据的读取操作,以缓解对资源的竞争。这样处理之后,数据库的权重能力下降,因为缓存中的数据可能更新,那么数据库中的数据可能落后N个版本,要么直接放弃数据库中的数据,仅仅为一个持久化存在。那么这时,数据的核心转移到缓存层。缓存虽然高效但是可靠性并没有数据库那么高,而游戏玩家的数据敏感度又是非常高的,经常的数据回滚也就成为了家常便饭。这会使运营成本增加以及维护成本增加。

2.数据局部更新请求,游戏的逻辑往往是有众多关联的,在一个逻辑中可能修改涉及到数个表,为了防止某个操作失败,在数据库上的做法是采用事务方式进行。然后修改成功后,涉及到UI交互更新部分,又需要根据各个逻辑进行各个区别返回。

曾经我们尝试过一种做法,我们一次性返回所有数据,一颗巨大的用户信息树,包含着当前用户的所有信息,当客户端觉得自己需要返回什么数据的时候,从树中直接获取。为了减少数据传输量,我们在树返回上加了一些过滤规则,用于返回特定关心的数据。这样的返回模式,相对比较通用,没有了协议协商过程。UI需求的改变也相对独立。

看起来是完美的,但是这个对性能导致了极大的影响,这意味着每次请求,不管什么都得查出所有的东西,后来我们把树切小,分成几个部分再加上缓存。才能勉强支撑。

但是实际上,开销依然存在,因为用户根本不关心的很多数据都依然存在于内存中。

3.数据同步,基于以上的做法,我们发现了另外一些缺点,在一些需求中,一个操作可能导致比较复杂的数据修改,那么前端同学就陷入了另外一个危机,数据组合危机。一个命令下去之后,可能需要请求2-3条数据请求,然后根据数据过滤规则再组合出一个完整的数据。

访问变得异常复杂,而且在逻辑复杂化的时候,不管是从开发体验还是性能上都不可接受。

于是乎,我们需要一个友好的数据同步模式,又与逻辑无关的,并且是基于服务器主动推送的。

设想,首先操作逻辑都是基于数据的修改,通过数据的改变(其实可以看成一个事件参考MVVM模式),已经可以描述大部分的UI逻辑,基础数据+修改日志 = 新的数据。

如果我们关心中间修改的过程,可以在修改过程中增加一点事件命令,那么我们就有了一个关于逻辑的拆分。

1. 数据D

2. 命令C

3. 事件E

4. 逻辑D

从流程上是,发起一个命令,执行逻辑操作数据,产生事件。所以简称 CDDE



解决了什么问题?

1.在新的模型中,数据以最新数据存在于内存中,并且分发修改数据给客户端以及数据基础服务。持久化过程因为是基于增量+基础数据的组合,所以数据不以Update方式修改,以Insert模式修改,较大程度的避免了因Update引起的锁问题。

从处理逻辑上,数据已经在内存中构造,并且客户端也无需进行查询,大部分情况下,数据的读都是空闲的。在常规缓存模式中,因为是全写的,所以开销较大,所以一般我们采用延写的方式来避免这部分开销。而新的模型中,差写的开销是非常小的。要解决的无非是脏写的问题,基本上可以认为我们的数据是即写的,回滚的概率降到最低。

2.由于本地数据镜像的存在以及该修改事件的通知,可以直接在UI上直接绑定刷新本地镜像数据或监听修改事件再来刷新UI,这大大的方便了UI逻辑以及对未来需求变动的适应性。但是由于不经过数据库,所以我们需要构建一个自己的事务系统,基于新的模型数据的存储方式(基础数据+修改日志),回滚也相对变得比较简单,但是在短连接模式中,我们无需在一条命令未执行完毕的时候把差异日志写入,因为在一个逻辑中你可能操作某个同样的数据若干次,在命令完成后合并差异日志再发往数据,即节省流量开销又高效。如果某个操作失败,那么数据并不会推送也不会写入数据库,你所要作的就是

1).丢弃当前的内存副本,重新读取一份最新的。(简单粗暴,开销略大)

2).使用当前异常的差异日志,进行数据回滚。(高效,但是需要更多代码实现)

3.基于可靠的数据同步协议,我们认定数据是最新的,无需关心逻辑中对任何数据的操作。那么对UI模块解绑以及对数据的解绑都已经完成。我们可以放心的切分各个模块以达到更好的开发效率与质量。

对各个层级解耦之后可以做到的事情?



注:(蓝色箭头为本地流程)

当在本地模拟出一套运行环境后,可以无需关心通信协议,无需关心数据存储,专注于应用逻辑与用户体验,真正把开发者从繁琐的开发环境中释放出来。

可用性? 扩展性?性能?

本架构的性能并不依赖于数据库,瓶颈在于读取大数据镜像/回滚效率,如果以无状态服务存在,通过弹性扩容集群化可用性可以得到保障,但是性能可能并不会太理想,但是只要控制单个用户的数据规模(数据小型化),或以业务逻辑驱动达成即读即用,仅读取关心数据的方式,那么性能会呈几何倍数上升,这一点是可以肯定的。

如果以小型化生产,把用户切分成数个服务器,以有状态服务存在,通过有效的手段控制回滚次数,那么性能可以得到更好的保障。

实时性?

之前提到过关于短链接以及无状态服务的模式,那么实时的模式是否可以胜任?显然是没有问题的,这套架构的设计之初就是为实时性服务的。去掉回滚和事务机制之后,这就是一套可以做到实时同步的系统,在多个用户监听同一个数据实体,并且控制好命令权限后。数据可以实时的推送给订阅者,达到编写实时交互应用/游戏的目的。通过基础数据+存储的数据日志,可以简单做到回放效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: