redis实现排行榜
1 前言
实现一个排版榜,我们通常想到的就是mysql的order by 简单粗暴就撸出来了。但是这样真的优雅吗?
数据库是系统的瓶颈,这是众所周知的。如果给你一张百万的表,让你排序做排行榜,花费的时间是十分可怕的。
不如缓存吧,order by的时候强制使用索引。但是这样真的优雅吗?
2 Redis的排行榜
我们分析一下排行榜,一个用户一个排名,意味着要去重,这时我们会想到Java的一种数据结构Set。不过Set又是无序的。有没有一种结构是可以保住元素唯一以及有序的呢。
幸运的是,还真的有。Redis的ZSet的就是这样的一种数据结构。Zset里面的元素是唯一的,有序的,按分数从小到大排序。作为一名优秀的crud程序员,我们从这几个方方面入手了解zset结构。
2.1 ZADD 增加与修改
其时间复杂度为 O(M*log(N)), N 是有序集的基数, M 为成功添加的新成员的数量。如果key不存在就插入,存在就更新。
使用如下:
redis> ZADD page_rank 10 google.com
(integer) 1
说明:
page_rankde 是key,10是分数,google.com是value
2.2 ZRANK 查询
时间复杂度: O(log(N))
使用如下:
redis> ZRANGE salary 0 -1 # 显示所有成员
1) "peter"
2) "tom"
3) "jack"
redis> ZRANK salary tom # 显示 tom 的薪水排名,第二
(integer) 1
说明:
salary的key,tom是value,只要输入特定的key与value就能查询到对应的排名。
2. del 删除
直接使用redis的del命令
3 分数设计
回到排行榜的实现,要利用zset结构来实现的话,重要的是如何设计分数。分析一下排行榜单的设计。如果排行榜的设计按一个维度比如金币数量,那只需把其数量取反作为分数score即可。取反是因为zset默认从小到大排序。
实现如下:
public Double getScore( Long oneDayGoldBean) {
String score = String.valueOf(oneDayGoldBean);
return -Double.valueOf(score);
}
如果排行榜的设计按两个维度比如金币数量和用时。由于score是一个可以double类型的参数,设计的时候可以把用时作为小数,用一天的总毫秒数减去花费毫秒数作为小数部分,然后当做字符串拼接起来,然后取反作为score.
实现如下:
public Double getScore( Long oneDayGoldBean, Long useTime) {
String value1 = String.valueOf(oneDayGoldBean/1.0);
long todayEndSS = getTodayEndSS(useTime);
String value2 = String.valueOf(todayEndSS);
String score =value1+value2;
return -Double.valueOf(score);
}
private long getTodayEndSS(long current){
//今天零点零分零秒的毫秒数
long zero = 0L;
//今天23点59分59秒的毫秒数
long twelve = zero + 24 * 60 * 60 * 1000;
return (twelve - current) / 1000;
}
4 代码实现
@Override
public boolean insertLeaderboard() {
Double score = getScore(100l, 1000l);
return redisTemplate.opsForZSet().add("leaderboard", "1", score);
}
@Override
public Set checkLeaderboard() {
// 0 -1 表示返回所有的value的set值
return redisTemplate.opsForZSet().range("leaderboard", 0, -1);
}
源码
https://github.com/blackdogss/HelloWorld/tree/master/helloRS
redis实现排行榜的更多相关文章
- Redis实现排行榜功能(实战)
需求前段时间,做了一个世界杯竞猜积分排行榜.对世界杯64场球赛胜负平进行猜测,猜对+1分,错误+0分,一人一场只能猜一次.1.展示前一百名列表.2.展示个人排名(如:张三,您当前的排名106579). ...
- redis实现排行榜功能
目录 加入排行榜 操作排行榜 redis的zset可以很方便地用来实现排行榜功能,下面简单介绍python如何使用redis实现排行榜功能 加入排行榜 获取redis实例 import redis m ...
- 使用 Redis 实现排行榜功能
排行榜功能是一个很普遍的需求.使用 Redis 中有序集合的特性来实现排行榜是又好又快的选择. 一般排行榜都是有实效性的,比如“用户积分榜”.如果没有实效性一直按照总榜来排,可能榜首总是几个老用户,对 ...
- 使用 Redis 实现排行榜功能 (转载 https://segmentfault.com/a/1190000002694239)
排行榜功能是一个很普遍的需求.使用 Redis 中有序集合的特性来实现排行榜是又好又快的选择. 一般排行榜都是有实效性的,比如"用户积分榜".如果没有实效性一直按照总榜来排,可能榜 ...
- 基于redis的排行榜设计和实现
前言: 最近想实现一个网页闯关游戏的排行榜设计, 相对而言需求比较简单. 秉承前厂长的训导: “做一件事之前, 先看看别人是怎么做的”. 于是乎网上搜索并参考了不少排行榜的实现机制, 很多人都推荐了r ...
- 想知道谁是你的最佳用户?基于Redis实现排行榜周期榜与最近N期榜
本文由云+社区发表 前言 业务已基于Redis实现了一个高可用的排行榜服务,长期以来相安无事.有一天,产品说:我要一个按周排名的排行榜,以反映本周内用户的活跃情况.于是周榜(按周重置更新的榜单)诞生了 ...
- 用mongo和redis查询排行榜、统计活跃用户
nosql数据库能解决关系型数据库遇到的性能和扩展性的问题,本博客将以mongodb和redis两种nosql数据库为基础,简单的介绍下面两个业务场景的解决方案: 1.查询排行榜(以当日总步数排名为例 ...
- redis实现排行榜思路
用redis的排序集合类型 sortset()实现排行榜 zadd();添加 ZREVRANGE();查看
- 基于redis排行榜的实战总结
前言: 之前写过排行榜的设计和实现, 不同需求其背后的架构和设计模型也不一样. 平台差异, 有的立足于游戏平台, 为多个应用提供服务, 有的仅限于单个游戏.排名范围差异, 有的面向全局排名, 有的只做 ...
随机推荐
- V语言横空出世,C/C++/Java/Python/Go地位不保
V语言已在github正式开源,目前已收获近9000星,引发开发者的强烈关注. V语言到底是怎样一门语言?已经有了C/C++/Java/Python/Go..., 我们还需要另外一门语言吗? 先看看V ...
- Linux 运行jar包命令(Cent OS 7后台运行jar包)
Linux 运行jar包命令如下: 方式一 特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出 那如何让窗口不锁定? 方式二 java -jar shareniu. ...
- 开设“C程序答疑解惑”的初衷
博主经常在QQ群里.论坛里看到好多C语言初学者,甚至是有一定编程经验的人,咨询在编程中遇到的一些稀奇古怪的问题.博主对这些问题做过分析汇总,有些问题确实隐蔽的非常深,像break关键字用的不对啦,局部 ...
- Java编程思想:序列化基础部分
import java.io.*; import java.util.Date; import java.util.Random; public class Test { public static ...
- Java编程思想:NIO知识点
import java.io.*; import java.nio.*; import java.nio.channels.FileChannel; import java.nio.charset.C ...
- [记录]一则HTTP配置文件参考记录
# cat ../conf/httpd.conf | grep -vE "^$|^#" ServerTokens OS ServerRoot "/etc/httpd&qu ...
- 实验吧--web--你真的会php吗
---恢复内容开始--- 实验吧的一道题php审计题.拉下来写一写. http://ctf5.shiyanbar.com/web/PHP/index.php 打开之后说have fun 那就抓包来看看 ...
- Hadoop学习(3)-mapreduce快速入门加yarn的安装
mapreduce是一个运算框架,让多台机器进行并行进行运算, 他把所有的计算都分为两个阶段,一个是map阶段,一个是reduce阶段 map阶段:读取hdfs中的文件,分给多个机器上的maptask ...
- 学习16内容# 1.自定义模块 # 2.time # 3.datetime # 4.random
模块的定义与分类 模块是什么? 这几天,我们进入模块的学习.在学习模块之前,我们首先要知道,什么是模块? 一个函数封装一个功能,你使用的软件可能就是由n多个函数组成的(先不考虑面向对象).比如 ...
- C#编程之JSON序列化与反序列化
1.在C#管理NuGet程序包中添加Json.NET 2.C#将对象序列化成JSON字符串 模型类1 /// <summary> /// JSON字符串模型.是否出错 /// </s ...