用redis实现的小游戏设计

前段时间接了一个H5游戏的后端开发任务,需求比较简单,就是在大会场里,几百、上千人分成若干组,在一段时间里同时摇手机,实时显示当前排名,最后看哪个组摇的最快,哪个人摇的最快。
由于是所有用户同时摇手机,而且一秒钟之内要摇5-10下,假设一千人同时摇,可能在一秒钟内会有5000至10000次的写入请求,而且在写入后还要同时计算当前各组的排名和个人里前N名的排名,如果用关系数据库,可能会由于瞬间大量插入而导致性能下降,造成游戏前端响应慢并且无法实时显示成绩排名。考虑到该游戏的实时性要求和游戏数据的低价值性(游戏结束后数据基本上就没用了),选择了redis作为后端存储。

该文章主要介绍redis的5种数据类型在本游戏中的使用,关于该游戏的架构设计,不过多说明,总体上就是前端使用websocket接入到后端,后端用netty开发,接收到前端的游戏数据后,将后续处理置入线程池,由线程池负责数据存入redis,并从redis中获取当前最新成绩排名。

在redis中,主要存储了以下内容:
1. 团队、玩家信息
2. 游戏状态、目标得分信息
3. 游戏得分、排名

1. 团队、玩家信息是典型的键值对类型,如团队名称、团队介绍;玩家名称、玩家头像,所以使用Hash类型存储,redis key的命名如:team:teamId、player:playerId。
2. 团队与玩家关系是典型的无需集合,并且一个团队中的玩家信息是不可重复的,所以使用集合(Set)类型存储,redis key的命名如:team.player:teamId
3. 游戏状态、目标得分均只有一个取值,所以用字符串类型存储,redis key的命名如:game.status,target.score
4. 游戏得分包括个人游戏得分和团队游戏得分,是典型的需要排序的数据集合,所以采用了有序集合类型(sorted set),数据被更新后会自动排序,方便支取得到游戏排名数据。redis key的命名如下player.score:playerId、team.score:teamId。

以上只是该游戏中一小部分数据存储的设计,通过这些设计,可以解决游戏中大部分数据的存储,并且可以快速得到个人与团队成绩排名,当然在实际应用中,还需要结合事务、管道等功能,提高数据的一致性和数据存取的快速处理,提高应用的处理性能。
上一篇:Spring bean的生命周期


下一篇:使用ArrayList时设置初始容量的重要性