大型游戏开放平台对redis v2.0.4使用感悟点滴

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宕机。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值