大型游戏开放平台对redis v2.0.4使用感悟点滴
2011-03-27 19:59
337 查看
redis是一个开源的、高级的key-value存储(官方网站http://www.redis.io/语)。它支持string、hash、list、set和sorted set。
下面我将分别用“场景”、“选型”、“应用”和“陷阱”等几个方面叙述一下我2个月使用redis的经验。
场景
在大型游戏开放平台项目中,我们面临着和传统Sns网站不一样的场景。传统Sns网站,它的内容由用户提供而被另外一些用户浏览,即UGC模式——用户聚集内容。这样内容的提供者和受众是同一拨人。而我们大型游戏开放平台则不一样,它甚至可以说和传统的门户网站有些类似,内容由一拨人(游戏开放平台的内容是由MMO游戏的玩家提供,门户网站内容由编辑提供)提供,由另外一拨人(基于游戏开放平台的社区的用户浏览,门户万展内容也由用户浏览)浏览。但和传统门户网站不同的是,游戏开放平台的数据海量的(MMO游戏玩家可比门户网站的编辑多得多)。
由于我们公司网络游戏已经有了很悠久的历史,不像其他Sns网站的起始发展阶段那样缺乏内容,而是内容太多,以至于出现起始阶段内容超过开放平台用户的这种现象。其他Sns网站,可以一开始就用LAMP架构搭建一个网站,一两台服务器即可,不用考虑什么分布式架构、分层结构,可以随着用户的增长逐步更改、拆分网站架构。而我们游戏开放平台,就算刚开始没有访问用户,大猫小猫两三只,也必须将MMO游戏的全量需要开放的数据导入到开放平台中,因为我们根本就不知道这大猫小猫都是访问哪些游戏的哪些数据。这样一开始就成了一个头重脚轻的问题——庞大的数据,少量的请求。
这样,必然面对庞大的硬件投入:一个新兴的MMO游戏的开放数据,就达百G量级,更勿论老牌的、有上千个区组的MMO游戏。这种量级的数据,必然面对其他新团队不曾面对的数据库分库分表,缓存的问题。这里重点要说的就是缓存的问题。大型游戏开放平台需要缓存的地方有以下几个:
1)读取缓存,为了避免重放访问(不是重放攻击哦,重放攻击Cache也是不能完全解决的)对数据库的压力。
2)新鲜事(游戏角色动态),这种玩意儿,很明显,非常适应key-value存储。放在数据库中,则只能放在CLOB或者LONGTEXT这样的字段中,性能显然不高。
3)状态一致性,这个使用数据库太重了,自己开发,则没有那个时间。
选型
技术运营部门给我们两个选择:memcache和redis。优缺点如下:
1.memcache是老牌的cache系统,稳定、安全、文档资料齐全、用的人多,出了问题有人可被咨询;而redis是新兴的cache系统,不稳定、没有经历过苛刻的测试、没有被其他大公司线上环境使用(后来我们才知道sina微博也正在使用它,只是也很不稳定)、出了问题只能自己看源码。redis不同版本的底层通讯协议也在变换,你想升级一下redis都有可能哭死。
2.memcache内置支持分布式访问多个物理cache;而redis需要另外开发支持
3.memcache不支持硬盘存储备份,一旦断电,全完蛋;redis有两种硬盘存储模式支持(snapshot和aof),另外redis可以将key-value中的部分调用较少的value存储在硬盘中,即VM(虚拟内存),只是极其不稳定。
4.redis专门强调过它的键值的原子性
综上原因,我们最终选择了redis。
应用
1)读取缓存。使用set、get和expire命令。每次从数据库中读取某个值时,将该值set进redis中,并使用expire设置超时时间,之后,再次读取该值时,直接从redis中get出来
2)新鲜事(游戏角色动态)。使用rpush、ltrim和lrange。后端程序使用rpush新值,然后ltrim最旧的值。前端程序lrange分页出需要的动态。
3)状态一致性。每个接收端都sub状态,pub进最新的状态;或者使用set最新状态,get出最新状态。
陷阱
1)读取缓存。有可能get出错误的值,比如,我曾经get某个值时,get出了INFO命令的结果。
2)新鲜事(游戏角色动态)。由于redis不支持key的LRU算法,当内存撑满到设置的内存最大的阀值,不能将调用最少的键值给删除掉。redis不支持list的每个value的expire。我曾经想过每次使用rpush后设置expire,这样就可以将长时间不玩游戏的玩家的“旧事”从redis中干掉。但是测试后发现,在expire后,使用rpush,会将之前rpush的数据给删除掉,而v2.0.4版本不能使用persist命令去掉expire。目前我们只能加硬件和降低cache每个角色的动态数量。
3)状态一致性。如果使用pub/sub模式,sub端需要有一个线程阻塞等待sub;如果使用set/get模式,get端需要timer线程定时get出最新状态。
4)VM问题。由于成本问题,我们被迫使用VM,当内存不够时,将某些key的值存入VM中。但是VM在v2.0.4有很多问题,首先是影响性能,导致取数据非常缓慢。另外有可能照成redis-server宕机。
下面我将分别用“场景”、“选型”、“应用”和“陷阱”等几个方面叙述一下我2个月使用redis的经验。
场景
在大型游戏开放平台项目中,我们面临着和传统Sns网站不一样的场景。传统Sns网站,它的内容由用户提供而被另外一些用户浏览,即UGC模式——用户聚集内容。这样内容的提供者和受众是同一拨人。而我们大型游戏开放平台则不一样,它甚至可以说和传统的门户网站有些类似,内容由一拨人(游戏开放平台的内容是由MMO游戏的玩家提供,门户网站内容由编辑提供)提供,由另外一拨人(基于游戏开放平台的社区的用户浏览,门户万展内容也由用户浏览)浏览。但和传统门户网站不同的是,游戏开放平台的数据海量的(MMO游戏玩家可比门户网站的编辑多得多)。
由于我们公司网络游戏已经有了很悠久的历史,不像其他Sns网站的起始发展阶段那样缺乏内容,而是内容太多,以至于出现起始阶段内容超过开放平台用户的这种现象。其他Sns网站,可以一开始就用LAMP架构搭建一个网站,一两台服务器即可,不用考虑什么分布式架构、分层结构,可以随着用户的增长逐步更改、拆分网站架构。而我们游戏开放平台,就算刚开始没有访问用户,大猫小猫两三只,也必须将MMO游戏的全量需要开放的数据导入到开放平台中,因为我们根本就不知道这大猫小猫都是访问哪些游戏的哪些数据。这样一开始就成了一个头重脚轻的问题——庞大的数据,少量的请求。
这样,必然面对庞大的硬件投入:一个新兴的MMO游戏的开放数据,就达百G量级,更勿论老牌的、有上千个区组的MMO游戏。这种量级的数据,必然面对其他新团队不曾面对的数据库分库分表,缓存的问题。这里重点要说的就是缓存的问题。大型游戏开放平台需要缓存的地方有以下几个:
1)读取缓存,为了避免重放访问(不是重放攻击哦,重放攻击Cache也是不能完全解决的)对数据库的压力。
2)新鲜事(游戏角色动态),这种玩意儿,很明显,非常适应key-value存储。放在数据库中,则只能放在CLOB或者LONGTEXT这样的字段中,性能显然不高。
3)状态一致性,这个使用数据库太重了,自己开发,则没有那个时间。
选型
技术运营部门给我们两个选择:memcache和redis。优缺点如下:
1.memcache是老牌的cache系统,稳定、安全、文档资料齐全、用的人多,出了问题有人可被咨询;而redis是新兴的cache系统,不稳定、没有经历过苛刻的测试、没有被其他大公司线上环境使用(后来我们才知道sina微博也正在使用它,只是也很不稳定)、出了问题只能自己看源码。redis不同版本的底层通讯协议也在变换,你想升级一下redis都有可能哭死。
2.memcache内置支持分布式访问多个物理cache;而redis需要另外开发支持
3.memcache不支持硬盘存储备份,一旦断电,全完蛋;redis有两种硬盘存储模式支持(snapshot和aof),另外redis可以将key-value中的部分调用较少的value存储在硬盘中,即VM(虚拟内存),只是极其不稳定。
4.redis专门强调过它的键值的原子性
综上原因,我们最终选择了redis。
应用
1)读取缓存。使用set、get和expire命令。每次从数据库中读取某个值时,将该值set进redis中,并使用expire设置超时时间,之后,再次读取该值时,直接从redis中get出来
2)新鲜事(游戏角色动态)。使用rpush、ltrim和lrange。后端程序使用rpush新值,然后ltrim最旧的值。前端程序lrange分页出需要的动态。
3)状态一致性。每个接收端都sub状态,pub进最新的状态;或者使用set最新状态,get出最新状态。
陷阱
1)读取缓存。有可能get出错误的值,比如,我曾经get某个值时,get出了INFO命令的结果。
2)新鲜事(游戏角色动态)。由于redis不支持key的LRU算法,当内存撑满到设置的内存最大的阀值,不能将调用最少的键值给删除掉。redis不支持list的每个value的expire。我曾经想过每次使用rpush后设置expire,这样就可以将长时间不玩游戏的玩家的“旧事”从redis中干掉。但是测试后发现,在expire后,使用rpush,会将之前rpush的数据给删除掉,而v2.0.4版本不能使用persist命令去掉expire。目前我们只能加硬件和降低cache每个角色的动态数量。
3)状态一致性。如果使用pub/sub模式,sub端需要有一个线程阻塞等待sub;如果使用set/get模式,get端需要timer线程定时get出最新状态。
4)VM问题。由于成本问题,我们被迫使用VM,当内存不够时,将某些key的值存入VM中。但是VM在v2.0.4有很多问题,首先是影响性能,导致取数据非常缓慢。另外有可能照成redis-server宕机。
相关文章推荐
- Android平台游戏开发引擎使用指引
- sina微博开放平台中使用OAuth验证并发表微博
- dbank开放平台使用流程简介
- QQ空间开放平台开发教程-SDK和API的使用
- 【游戏数据库】大型网络游戏数据库设计方面讨论?(微软平台) 游戏数据库
- 饿了么开放平台接入(2)——使用Java对接店铺
- 百度语音识别开放平台SDK使用方法
- 大型交通流仿真平台——Matsim中文使用手册03
- 百度语义理解开放平台使用方法
- 设想:未来游戏之服务端平台开放客户端百花齐放
- 简谈“开放平台”设计中的一些感悟
- 百度语音识别开放平台SDK使用方法
- Android游戏服务端如何部署到云开放平台或者其他服务器上
- Cocos2d-X游戏开发之社交网络平台的使用(EziSocial)(基础介绍)
- 使用structs2开源框架+tomcat开源服务+mysql开源数据库+微信开放接口构建考务信息推送平台
- 微信网页第三方登录原理 微信开放平台和公众平台的区别 1.公众平台面向的时普通的用户,比如自媒体和媒体,企业官方微信公众账号运营人员使用,当然你所在的团队或者公司有实力去开发一些内容,也可以调用公众
- SpriteKit游戏开发点滴[6]使用物理引擎(上)
- 使用UE4发布安卓平台游戏
- 开放平台对接使用数字签名技术
- XNA Game Studio是一套有着强大功能和简单界面的游戏制作平台,游戏开发商和游戏玩家都可以使用这套工具开发针对Windows XP以及Xbox360的游戏,XNA Game Studio分为两种版本,一种是面向初学者的EXPRESS版本,还有一种是面向专业用户的专业版。用户使用EXPRESS版本开发游戏完全免费,并且可以随意在PC上发行,不过用该工具开发的游戏若是在360上网络发行,就需要交纳99美元的年费。