基于redis的排行榜设计和实现
前言:
最近想实现一个网页闯关游戏的排行榜设计, 相对而言需求比较简单. 秉承前厂长的训导: “做一件事之前, 先看看别人是怎么做的”. 于是乎网上搜索并参考了不少排行榜的实现机制, 很多人都推荐了redis的有序集(sorted set). 我觉得十分的赞, 技术方案很难在超越已有的模型了, 就看业务上的需求, 做些小改动.
相关文章系列:
记得大概在一年前吧, 写过两篇关于排行榜的文章, 不过那是针对游戏平台(类似微信, 手Q等)而言的. 每个用户都有自己的排行榜, 不是全局性的.
• 社交游戏的排行榜设计和实现(1)
• 社交游戏的排行榜设计和实现(2)
有序集初体验:
先来看几个后续会使用的redis命令语法:
ZADD key score1 member1 [score2 member2]
添加一个或多个成员到有序集合,或者如果它已经存在更新其分数 ZRANGE key start stop [WITHSCORES]
由索引返回一个成员范围的有序集合。 ZSCORE key member
获取给定成员相关联的分数在一个有序集合 ZRANK key member
确定成员的索引中有序集合
更详细和完整的命令, 请点击该链接.
• 案例设计
输入5个学生的成绩(name, score), 实现top-3的查询, 修改某个同学的得分, 再次查询top-3.
1). 添加成绩记录
添加 (lucy, 61), (lily 60), (uncle wang, 10), (lilei, 98), (hanmeimei, 99) 这5人的成绩, 并假定class_rank 为sorted set的name.
2). 第一次top-3查询
3). 更新uncle wang的分数
注: zadd命令既可以添加, 也可以更新
4). 再次top-3查询
场景的设计, 以及最后输出的结果与预期符合.看来redis的sorted set满足需求, 而且特别的方便.
原理浅析:
有了前文的直观体验, 再来研究redis中的有序集合(sorted set), 究竟是何种数据结构, 它能提供什么样的接口, 以及满足什么样的需求呢?
我们来探究下它支持的功能, 首先当然就是支持按分值排序的功能. 由此可以猜测它底层是按score为key, name为value的tree结构(因为支持范围查询, 以及按分值排序). 但是该有序集又支持按name来修改score. 这样需求下, 又演变成name为key, score为value的map结构了. 单独的一种数据结构, 无法满足其需求, 两个都不可或缺. 那答案究竟是什么?
redis源码的定义如下:
typedef struct zset {
// 字典
dict *dict;
// 跳跃表
zskiplist *zsl;
} zset;
这样就比较清晰了, 它采用了复合结构, 字典维护了name=>score的映射表, 而跳跃表则维护了按score排序的列表. 按name和按score的范围查询都天然支持.
具体的解读,可参考<<redis 设计和实现--有序集>>.同时引用官文文档的一张示意图:
总结:
其实我很早就想这篇文章,作为一个游戏编程的爱好者而言,排行榜作为一个基础服务,必然会接触到.早做准备必然是好事,后续如果有机会.我想依据实际的项目,来具体阐述一下,毕竟理论和实战, 还是有所差异.
公众号&游戏站点:
个人微信公众号: 木目的H5游戏世界
个人游戏作品集站点, www.mmxfgame.com, 请点击访问: http://120.26.221.54/.
基于redis的排行榜设计和实现的更多相关文章
- 想知道谁是你的最佳用户?基于Redis实现排行榜周期榜与最近N期榜
本文由云+社区发表 前言 业务已基于Redis实现了一个高可用的排行榜服务,长期以来相安无事.有一天,产品说:我要一个按周排名的排行榜,以反映本周内用户的活跃情况.于是周榜(按周重置更新的榜单)诞生了 ...
- 基于redis排行榜的实战总结
前言: 之前写过排行榜的设计和实现, 不同需求其背后的架构和设计模型也不一样. 平台差异, 有的立足于游戏平台, 为多个应用提供服务, 有的仅限于单个游戏.排名范围差异, 有的面向全局排名, 有的只做 ...
- Java实现排行榜基于Redis
访问我的博客 前言 排行榜作为互联网应用中几乎必不可少的一个元素,其能够勾起人类自身对比的欲望,从而来增加商品的销量.排行榜的实现方式基本大同小异,大部分都基于 Redis 的有序集合 sorted ...
- 基于Redis的限流系统的设计
本文讲述基于Redis的限流系统的设计,主要会谈及限流系统中限流策略这个功能的设计:在实现方面,算法使用的是令牌桶算法来,访问Redis使用lua脚本. 1.概念 In computer netw ...
- 基于Redis的分布式锁设计
前言 基于Redis的分布式锁实现,原理很简单嘛:检测一下Key是否存在,不存在则Set Key,加锁成功,存在则加锁失败.对吗?这么简单吗? 如果你真这么想,那么你真的需要好好听我讲一下了.接下来, ...
- 基于Redis&MySQL接口幂等性设计
基于Redis&MySQL接口幂等性设计 欲把相思说似谁,浅情人不知. 1.幂等 幂等性即多次调用接口或方法不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致. 2.幂等使用场景 前 ...
- 基于redis分布式缓存实现(新浪微博案例)
第一:Redis 是什么? Redis是基于内存.可持久化的日志型.Key-Value数据库 高性能存储系统,并提供多种语言的API. 第二:出现背景 数据结构(Data Structure)需求越来 ...
- 项目分布式部署那些事(1):ONS消息队列、基于Redis的Session共享,开源共享
因业务发展需要现在的系统不足以支撑现在的用户量,于是我们在一周之前着手项目的性能优化与分布式部署的相关动作. 概况 现在的系统是基于RabbitHub(一套开源的开发时框架)和Rabbit.WeiXi ...
- 基于redis分布式缓存实现
Redis的复制功能是完全建立在之前我们讨论过的基 于内存快照的持久化策略基础上的,也就是说无论你的持久化策略选择的是什么,只要用到了Redis的复制功能,就一定会有内存快照发生,那么首先要注意你 的 ...
随机推荐
- C# 从CIL代码了解委托,匿名方法,Lambda 表达式和闭包本质
前言 C# 3.0 引入了 Lambda 表达式,程序员们很快就开始习惯并爱上这种简洁并极具表达力的函数式编程特性. 本着知其然,还要知其所以然的学习态度,笔者不禁想到了几个问题. (1)匿名函数(匿 ...
- UITableView优化的方法
使用不透明视图. 不透明的视图可以极大地提高渲染的速度.因此如非必要,可以将table cell及其子视图的opaque属性设为YES(默认值). 其中的特例包括背景色,它的alpha值应该为1(例如 ...
- 【BZOJ】1407 NOI 2002 荒岛野人Savage
拓展欧几里得入门题 两个野人若要走到同一个洞穴,设他们走了x步,则p[i]*x+c[i]≡p[j]*x+c[j](mod ans),ans即答案: 移项得到(p[i]-p[j])*X+ansY=c[j ...
- 如何让一个DIV浮动在另一个DIV上面
直接上DEMO了 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3 ...
- 轻松解决Linux安装Eclipse方法
随着Linux的发展,很多人开始学习Linux系统,你了解Linux系统么?你是Linux系统的应用者么?本文为你详细介绍Linux安装Eclipse,为你在学习Linux安装Eclipse时起一定的 ...
- js执行顺序<转>
JavaScript执行引擎并非一行一行地分析和执行程序,而是一段一段地分析执行的.而且在分析执行同一段代码中,定义式的函数语句会被提取出来优先执行.函数定义执行完后,才会按顺序执行其他代码. 先看看 ...
- 《利用python进行数据分析》读书笔记--第十一章 金融和经济数据应用(一)
自2005年开始,python在金融行业中的应用越来越多,这主要得益于越来越成熟的函数库(NumPy和pandas)以及大量经验丰富的程序员.许多机构发现python不仅非常适合成为交互式的分析环境, ...
- iOS开发 ReactiveCocoa入门教程 第二部分
ReactiveCocoa 是一个框架,它允许你在你的iOS程序中使用函数响应式(FRP)技术.加上第一部分的讲解,你将会学会如何使用信号量(对事件发出数据流)如何替代标准的动作和事件处理逻辑.你也会 ...
- 浅谈HTTP协议(下)
下面来讲响应消息.响应消息也分为响应起始行.响应头部.CRLF.响应主体. 响应起始行包括协议版本.响应状态码.原因短句.这里的重点就是响应状态码,它一共分为5类,状态码准确的说是一个三位数. 1xx ...
- thinkphp下载远程图片到本地
$url="http://www.test.com/test.jpg";//图片远程地址 $local="./Upload/test/test.jpg";//下 ...