基于内存,redis,mysql的高速游戏数据服务器设计架构

转载请注明出处,欢迎大家批评指正

1、数据服务器详细设计

数据服务器在设计上采用三个层次的数据同步,实现玩家数据的高速获取和修改。

数据层次上分为:内存数据,redis数据,mysql数据

设计目的:首先保证数据的可靠,防止数据丢失,保证数据完整。然后实现数据的高速访问,减少由玩家数量增加对数据服务器性能造成的影响。最后实现运维数据的入库,以及数据持久化。

在这个基础上数据服务器不再是一个单一服务器,它涉及到与其他服务器之间的交互。

数据服务器的核心在于redis数据层面。通过redis加快玩家数据的快速拉取。

内存数据是直接与逻辑服务器进行交互的,因此内存数据划分到逻辑服务器进行管理,redis数据划分为数据服务器管理,mysql数据是对redis数据库的备份和同步。

主要流程,数据服务器启动时先从mysql数据库加载所有的活跃玩家相关数据到redis数据库中,逻辑服务器与数据服务器之间的交互都是通过国过redis数据进行操作。Redis数据库回写到mysql可以通过回写进程实现。

            图 1 数据服务器数据扭转流程图

1.1 数据服务器主进程

数据服务器主进程核心是对redis的操作,通过redis数据库实现数据的高速存储。因此,数据服务器的核心是保证在玩家数量大较大的情况下对玩家数据的增删改都能维持在一定的时间效率内。

针对于redis数据库本身,可以考虑实现redis的主从库搭建,保证redis的数据库的备份和效率。

数据服务器主进程的构成:

1、mysql数据同步到redis数据库中。

2、逻辑服务器和数据服务器的网络库

3、玩家账户修改缓存

4、Redis数据库的回写至mysql

5、逻辑数据库的请求处理

6、内存数据库的组织结构

1.2 数据回存服务

数据服务器接收到逻辑服务器的请求后,就数据库操作请求进行操作的队列缓冲,形成操作队列。操作队列同时提供了redis数据库的及时写入和mysql数据库的异步写入。

1.3 数据服务器提供接口

对于逻辑服务器,数据服务器应为其开放以下接口:

1、数据拉取接口,拉取对应玩家的所有数据,将数据保存到内存数据中

2、修改玩家数据接口,提供玩家的部分或全部信息修改命令

2 数据服务器模块功能

首先redis是一种key-value的内存数据库,以key和value的方式来存储数据实现高速的访问和操作。其次mysql是一种关系型数据库,存储的是结构化的数据。这种差异决定了在数据入库redis的时候需要做相应的处理。

2.1 数据入库redis

通过redis的key-value来存储数据库中的表名以及表的索引和hashkey,来实现构造二维的数据表。

针对于每张表,key结构 [表名]:[id值]

要求所有的数据库表的第一个字段为id,或者所有的表都为主键,并且不能重复,这样保证了所有的key都不重复

图 2 数据入库redis后表现结构

入库流程方法一:

先将redis清空,再将mysql所有的额数据逐条入库到redis。逐条入库的好处是可以对玩家进行其他的操作处理,缺点是启动服务器速度慢。

方法二:

先将redis数据库清空,再将mysql读取处理的数据缓存成redis识别的事务,一次性进行redis入库。

2.2 排序

实现高效的排序功能,可以使用redis的zset进行拍寻队列构建,对于玩家等级或经验改变时,对redis数据库进行修改,当需要或获取排序时直接获取zset集合类已经拍好的顺序就可以实现高效的排序功能

2.3 redis数据回存mysql

对redis数据库的操作需要回存到mysql数据库中。

方案一:采用多线程异步,通过多线程异步实现mysql修改回存同步。在数据服务器多开一个线程进行回存。

优点:设计结构相对简单,不涉及到进程间通信,但需要多线程开发支持

方案二:采用多进程方式,回存由专门的进程进行,没有操作消息redis数据库默认转发进程转发。

优点:简单的单线程即可满足需求,但需要进程间通讯。

2.4 网络交互模块及序列化

服务器之间的网络传输由统一的网络模块进行。序列化功能采用protobuf的序列化功能。

3 具体实现

数据服务器设计到大多都是表和redis数据操作,这些操作具有相似性。这样的繁杂的操作不利于手动修改和书写代码。

因此在此处合理的运用生成器就会减少很大一部分工作量,通过生成器快速生成C++代码,并且灵活的应对数据库结构的更改。

3.1 生成物和生成器

生成器使用了C#语言快速编写访问数据库结构,并生成类代码。

生成物可以设计成各种语言的操作文件,目前生成C++文件。

3.2 Mysql数据回写进程

数据回写进程又一个回写消息队列和一个回写器组成,回写消息队列缓存所有要进行回写操作,再有回写器进行回写。多线程回写消息队列操作加锁。

3.3 玩家登陆信息查询

玩家登陆时将拉取玩家数据到内存中。这个流程现在redis数据库中查询玩家数据,如果存在,返回给逻辑服务器玩家数据,如果redis数据库中不存在玩家数据,将再次在mysql中进行查询,如果存在返回给逻辑服务器,如果不存在返回查询失败。具体流程看下图

    

                图 3 玩家数据查询流程

在修改玩家数据时,需要同步三层数据。数据首先是在内存中进行修改,然后发起修改命令给数据服务器,数据服务器将修改命令分别压入redis数据库命令队列和mysql命令队列。再有两个线程异步对命令队列中的命令执行,完成数据回写。

图 4 数据回写命令执行流程

3.4 玩家活跃程度划分 

为了提高数据的访问速度和效率,将玩家进行活跃度分级。正在游戏玩家数据加载到内存,快速访问。活跃玩家加载到redis数据库,实现快速拉取。不活跃玩家存放mysql,需要时访问查询。

优点:根据数据的访问频度对数据进行分级,使得高频数据快速访问,节约了内存空间。

缺点:不活跃玩家登陆时间相对较长,但不影响游戏效率。登陆后,玩家又再次进入活跃玩家存储方案。

时间: 2024-08-24 23:10:13

基于内存,redis,mysql的高速游戏数据服务器设计架构的相关文章

数据迁移实战:基于Kettle的Mysql到DB2的数据迁移

From:https://my.oschina.net/simpleton/blog/525675 一.什么是ETL ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数据从来源端经过抽取(extract).转换(transform).加载(load)至目的端的过程.ETL一词较常用在数据仓库,但其对象并不限于数据仓库. 二.Kettle简单说明 Kettle是一款国外开源的ETL工具,纯java编写,可以在Window.Linux.Unix上运行,数据抽取高效稳定

《SPARK/TACHYON:基于内存的分布式存储系统》-史鸣飞(英特尔亚太研发有限公司大数据软件部工程师)

史鸣飞:大家好,我是叫史鸣飞,来自英特尔公司,接下来我向大家介绍一下Tachyon.我事先想了解一下大家有没有听说过Tachyon,或者是对Tachyon有没有一些了解?对Spark呢? 首先做一个介绍,我来自英特尔的大数据团队,我们团队主要是致力于各种大数据的软件开发以及这些软件在工业界的推广和应用,我所在的团队主要负责Spark及其软件栈的开发和推广.我们是国内最早参加Spark开发和推广的团队,我们在2012年就加入了Spark社区.在Spark和相关的项目中间投入了大量的人力,长期以来我

微信后台数据服务器

功能简介 为微信公众号进行业务开发,运营者可以通过该服务器向微信用户提供自助数据查询服务,或者通过微信用户采集数据进行集中处理. 主要功能 1.提供基于微信菜单的导航服务,数据服务器提供完整的日志记录 2.用于查询数据,发送控制指令,运营者随时随地通过客户端软件设置服务器数据规则和权限 3.可转接人工服务,让服务更及时,更体贴 4.可以主动发送图文信息,实现微信提醒功能. 案例 1.某医院诊室自助服务号,用户关注后,通过微信查询当前就诊进度. 2.某学校通过微信为学生提供成绩查询 3.某医疗机构

Redis+Mysql模式和内存+硬盘模式的异同

http://www.open-open.com/lib/view/open1346029825942.html 学习任何新知识,都是一个循序渐进的过程,从刚开始的懵懂无知,到简单熟悉,然后突然的彻悟,成果让人欣喜若狂,心情也会快乐很久. redis+mysql和内存+硬盘类似的地方 首先看图: 首先,我们知道,mysql是持久化存储,存放在磁盘里面,检索的话,会涉及到一定的IO,为了解决这个瓶颈,于是出现了缓存,比如现在用的最多的 memcached(简称mc).首先,用户访问mc,如果未命中

基于Redis+MySQL+MongoDB存储架构应用

摘  要: Redis+MySQL+MongoDB技术架构实现了本项目中大数据存储和实时云计算的需求.使用MongoDB切片的水平动态添加,可在不中断平台业务系统的同时保障扩容后的查询速度和云计算效能:依据切片键索引分片,位于各切片独立进行计算,使大数据下的实时分析成为现实.对于高频访问的数据放在了Redis中,有效地降低磁盘I/O,使业务系统响应更为敏捷,满足了高并发下应用服务的高呑吐要求. 关键词: 移动位置服务SaaS:Redis:MongoDB 基于移动位置服务的应用是根据用户所在位置提

基于内存的类似redis的缓存方法

项目中需要用到redis,业务起来之后用到的地方更多,问题来了,因为操作redis太频繁,导致操作redis成为整个项目的瓶颈,经过调研和比较这时候基于内存的cache登场,简单来说就是纯内存层面的cache,可以实现1.缓存数量的限制(不能无限制的堆内存,会撑爆)2.能设置过期时间(内存中只缓存高频出现的数据) 放上业务流程的对比图,就是在redis之前加了一层,比较redis虽然基于内存但是连接包括操作还是得产生网络io操作 下面是我做的对比测试: 普通数据: 1.假设全部不命中(内存和re

基于express+redis高速实现实时在线用户数统计

作者:zhanhailiang 日期:2014-11-09 本文将介绍怎样基于express+redis高速实现实时在线用户数统计. 1. 在github.com上创建项目uv-tj.将其同步到本地: [root@~/wade/nodejs]# git clone [email protected]:billfeller/uv-tj.git 2. 使用npm init初始化node项目(本例不须要复杂的操作,所以暂不使用express工具来生成express应用程序骨架): [root@~/wa

一种红包发送功能的实现(redis+mysql+quartz)

这篇文章主要是对半年前开发的红包模块进行整理,把其中主要的设计思想以及具体的实现方案进行介绍,如有设计以及实现上的缺陷,或是存在漏洞,请大家批评指正! 红包功能大家都很熟悉了,那在这里就简单的对红包功能进行描述... 功能描述:红包业务主要的功能包括四部分,分别是红包发送,红包接收,红包回收,以及红包记录查询. 1)红包发送:发送者账户->红包中间层 2)红包接收:红包中间层->接收者账户 3)红包回收:红包中间层中若存在红包留存超过24小时,则将其回收,红包中间层->发送者账户 功能描

redis缓存服务器(Nginx+Tomcat+redis+MySQL实现session会话共享)

一.redis介绍 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set --有序集合)和hash(哈希类型).与memcached一样,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现master-slave(主从)同步. Redis是一个高性能的key-valu