Redis实现排行榜功能实战

前言

在日常的服务器开发过程中,经常会遇到排行榜的需求。这里我们主要讨论使用redis zset来实现一般的常用排行榜。也就是单key排行榜,分数为整数,一般长度不过万。

ZSet概述

Redis的ZSet(Sorted Set)是一种有序集合,它结合了Set和SortedList的特性,成员是唯一的,且按照成员的分数(score)进行从小到大排序。在ZSet中,每个元素都会关联一个分数,分数可以重复,但元素不能重复。这使得ZSet非常适合用于实现排行榜等场景。

每个直播间都有粉丝的排行榜,可以通过key+直播间id来作为redis的key。例如broadcast:20210108231。每个直播间的观众按照点赞数排序。则观众刚刚进入直播间即可通过ZADD添加排行榜。

张三观众进入直播间。
李四进入直播间
ZADD [key] [score] [value]

ZADD broadcast:20240108231 1 zhangsan
ZADD broadcast:20240108231 1 lisi

2、加分值

`李四`送了直播间两颗小红心。李四分值`加2`。
`ZINCRBY [key] increment [member]

ZINCRBY broadcast:20240108231 2 lisi

3、展示榜单
通过如上指令对直播间分值进行设置之后,得到redis的value如下:

127.0.0.1:6379> ZRANGE broadcast:20240108231 0 -1 WITHSCORES
1) "zhaoliu"
2) "2"
3) "wangwu"
4) "5"
5) "lisi"
6) "8"
7) "zhangsan"
8) "10"

4、查看直播间人数

ZCARD key 返回集合数量。

127.0.0.1:6379> zcard  broadcast:20240108231
(integer) 4

5、离开直播间
张三离开直播间,则删除对应key。
ZREM [key] [value]

127.0.0.1:6379>  ZREM broadcast:20240108231 zhangsan
(integer) 1
127.0.0.1:6379>  ZREVRANGE broadcast:20240108231 0 2
1) "lisi"
2) "wangwu"
3) "zhaoliu"

6、周榜

真实场景中肯定会有时间段的划分,例如查看日榜、周榜、月榜。只需要按照最小的单位按照时间区分成不同的集合,最后求出这些集合的并集即可。

ZADD broadcast:1 10 zhangsan
ZADD broadcast:1 10 lisi
ZADD broadcast:2 5 zhangsan
ZADD broadcast:2 5 wangwu
如此,得到两个zset集合,最后得到两个集合的并集。
ZUNIONSTORE destination numkeys key [key …] [WEIGHTS weight [weight …]] [AGGREGATE SUM|MIN|MAX]

127.0.0.1:6379> ZUNIONSTORE broadcast:week:1 2 broadcast:1 broadcast:2
(integer) 3
127.0.0.1:6379> ZRANGE broadcast:week:1 0 -1 WITHSCORES
1) "wangwu"
2) "5"
3) "lisi"
4) "10"
5) "zhangsan"
6) "15"

WEIGHTS 可以设置每个集合的权重,意为在原来集合分数乘权重得到输出集合的值。
两个集合并集时,如果有相同的key,则可以通过 SUM|MIN|MAX 进行控制。默认为SUM

JAVA实现排行榜

要实现一个排行榜,我们需要做以下几件事:

  • 创建一个ZSet,其中包含用户ID和对应的分数。
  • 获取排行榜数据,并按照分数降序排列。

以下是一个简单的Java代码示例,展示了如何使用Jedis库来实现基于Redis的ZSet的秒级排行榜

public class RedisZSetRank{
    
    @Autowired
    private RedisTemplate redisTemplate;

    // 添加用户分数到排行榜
    public void addScore(String userId, double score) {
         redisTemplate.opsForZSet().add("ranking",userId,score);

    }

    // 获取排行榜数据
    public Set<String> getRanking() {
        // 获取前10名
        return redisTemplate.opsForZSet().reverseRange("ranking", 0, 10); 
    }
    
    // 查看某条记录的排名
    public Long ranking(String code) {
        Long ranking = redisTemplate.opsForZSet().rank("ranking", code);
        if (ranking != null) {
            //有序集合的索引是从0开始的,所以查询出来的排名要+1。
            return ranking + 1;
        }
        return ranking;
    }
    
    public static void main(String[] args) {

        // 添加用户分数
        rank.addScore("user1", 100);
        rank.addScore("user2", 200);

        // 获取排行榜数据
        Set<String> rankingData = rank.getRanking();
        for (String userId : rankingData) {
            System.out.println("User ID: " + userId);
        }
    }
}

这样就实现了简单的排行榜。

总结

Redis 的有序集合 Sorted Set中的成员是唯一的,但分数(score)却可以重复,这一点恰恰可以被我们用来实现排行榜的功能。

谷歌浏览器github加速插件,国内访问及下载速度达到2M/S,杠杠的!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/489130.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

谷歌AI搜索惊现恶意网站推荐!用户安全再遭威胁?

近日&#xff0c;谷歌推出的新搜索生成体验(SGE)功能引发广泛关注。然而&#xff0c;这一旨在提升搜索体验的AI功能却陷入了争议&#xff0c;有报道称其可能在生成的响应中推广欺诈网站和恶意软件&#xff0c;为用户带来安全风险。 AI-321 | 专注于AI工具分享的网站 AI工具集 …

文件的介绍

文件介绍 文件是计算机中用于存储数据的一种载体。一般储存在磁盘上。 文件通常以一定的格式和结构存储数据&#xff0c;可以包含文本、图像、音频、视频等各种类型的信息。 文件可以通过文件系统进行管理和组织&#xff0c;用户可以对文件进行创建、打开、编辑、保存、复制…

Chrome 插件各模块之间的消息传递

Chrome 插件各模块之间的消息传递 一、消息传递 1. 消息传递分类 Chrome 插件的 Action、Background 和 content_script 三个模块之间的信息传输插件和插件之间的信息传输网页向插件进行信息传输与原生应用进行消息传递 2. 消息传递 API runtime API runtime.sendMessage(…

新房装修后,经验总结和坑点复盘

房子装修的时候&#xff0c;谁在盯着你的钱包&#xff1f;谁想从你这里捞钱&#xff1f;一是负责签合同的装修公司&#xff0c;二是负责实际装修的工地工头。装修公司要从你这份合同里为公司赚取运营成本和利润&#xff0c;工地装修工头要从你这里赚取他私人的利益。 在签合同…

C语言例4-13:已知圆柱体的底半径是1.5,高是2.0,计算其体积并输出。

代码如下&#xff1a; //已知圆柱体的底半径是1.5&#xff0c;高是2.0&#xff0c;计算其体积并输出。 #include<stdio.h> #define PI 3.1415926 int main(void) {float radius1.5, high2.0,vol;vol PI*radius*radius*high; //计算圆柱体的体积printf("vol %7.…

jsonpath和json数据(序列化loads()、反序列化eval())及断言处理(断言封装)

jsonpath&#xff1a;对json串进行搜索 安装jsonpath 安装&#xff1a;pip install jsonpath 导入&#xff1a; from jsonpath import jsonpath jsonpath能通过简单的方式就能提取给定JSON中的字段。 jsonpath官方地址&#xff1a;https://goessner.net/articles/JsonPath/ 在…

AI视频渲染原理是什么?

一、AI渲染原理 AI视频渲染是一种结合了人工智能技术的新型渲染方式&#xff0c;它主要通过深度学习和其他机器学习方法来优化传统渲染流程&#xff0c;以提高效率和质量。以下是AI视频渲染可能涉及的一些基本原理&#xff1a; 1. **智能采样**&#xff1a; - AI可以帮助决定在…

Go第三方框架--gin框架(二)

4. gin框架源码–Engine引擎和压缩前缀树的建立 讲了这么多 到标题4才开始介绍源码&#xff0c;主要原因还是想先在头脑中构建起 一个大体的框架 然后再填肉 这样不容易得脑血栓。标题四主要涉及标题2.3的步骤一 也就是 标题2.3中的 粗线框中的内容 4.1 Engine 引擎的建立 见…

R语言学习——Rstudio软件

R语言免费但有点难上手&#xff0c;是数据挖掘的入门级别语言&#xff0c;拥有顶级的可视化功能。 优点&#xff1a; 1统计分析&#xff08;可以实现各种分析方法&#xff09;和计算&#xff08;有很多函数&#xff09; 2强大的绘图功能 3扩展包多&#xff0c;适合领域多 …

【Python实用标准库】argparser使用教程

argparser使用教程 1.介绍2.基本使用3.add_argument() 参数设置4.参考 1.介绍 &#xff08;一&#xff09;argparse 模块是 Python 内置的用于命令项选项与参数解析的模块&#xff0c;其用主要在两个方面&#xff1a; 一方面在python文件中可以将算法参数集中放到一起&#x…

基于nodejs+vue基于协同过滤算法的私人诊python-flask-django-php

实现后的私人诊所管理系统基于用户需求分析搭建的&#xff0c;并且会有个人中心&#xff0c;患者管理&#xff0c;医生管理&#xff0c;科室管理&#xff0c;出诊医生管理&#xff0c;预约挂号管理&#xff0c;预约取消管理&#xff0c;病历信息管理&#xff0c;药品信息管理&a…

国内IP节点更换攻略,一键解决烦恼

在如今的互联网时代&#xff0c;网络已经成为人们生活中不可或缺的一部分。而对于许多网民来说&#xff0c;网络速度的快慢直接关系到他们的上网体验。在国内&#xff0c;很多用户常常遇到一个问题&#xff0c;那就是网络速度不稳定。有时候可以流畅地上网&#xff0c;有时候却…

【LeetCode热题100】108. 将有序数组转换为二叉搜索树(二叉树)

一.题目要求 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡二叉搜索树。 二.题目难度 简单 三.输入样例 示例 1&#xff1a; 输入&#xff1a;nums [-10,-3,0,5,9] 输出&#xff1a;[0,-3,9,-10,null,5] 解释&#x…

React Native 应用打包上架

引言 在将React Native应用上架至App Store时&#xff0c;除了通常的上架流程外&#xff0c;还需考虑一些额外的优化策略。本文将介绍如何通过配置App Transport Security、Release Scheme和启动屏优化技巧来提升React Native应用的上架质量和用户体验。 配置 App Transport…

【目标检测】西红柿成熟度数据集三类标签原始数据集280张

文末有分享链接 标签名称names: - unripe - semi-ripe - fully-ripe D00399-西红柿成熟度数据集三类标签原始数据集280张

Spring文件配置以及获取

前言 我们都知道很多应用都是有配置文件的,可以对应用的一些参数进行配置,如conf... 本篇我们讲解关于Spring的配置文件以及程序怎么获取其中写入的参数 Spring中的配置文件主要有三种 还有yml和ymal文件 下面我们将介绍关于常用的两种 preoperties 和 yml文件的格式和读取…

【SQL】1667. 修复表中的名字(UPPER()、LOWER()、SUBSTRING()、CONCAT())

前述 SQL中字符串截取函数(SUBSTRING) SQL 字母大小写转换函数UPPER()、UCASE()、LOWER()和LCASE() 题目描述 leetcode题目&#xff1a;1667. 修复表中的名字 Code select user_id, concat(upper(substring(name, 1, 1)),lower(substring(name, 2)) ) as name from Users o…

5G双域专网+零信任的神奇魔法

引言 在当今数字化程度不断提升的社会中&#xff0c;信息安全已经成为企业和组织发展的关键要素之一。特别是在网络连接日益广泛的环境下&#xff0c;对于数据的保护和隐私的维护变得尤为重要。随着5G技术的飞速发展&#xff0c;5G双域专网为企业提供了更快速、更可靠的连接&a…

对标开源3D建模软件blender,基于web提供元宇宙3D建模能力的dtns.network德塔世界是否更胜一筹?

对标开源3D建模软件blender&#xff0c;基于web提供元宇宙3D建模能力的dtns.network德塔世界是否更胜一筹&#xff1f; blender是一款优秀的3D建模开源软件&#xff0c;拥有免费开源、功能强大、渲染速度优秀的优点。而开源的dtns.network德塔世界&#xff0c;亦是专业级的元宇…

cinder学习小结

1 官方文档 翻译官方文档学习 链接Cinder Administration — cinder 22.1.0.dev97 documentation (openstack.org) 1.1 镜像压缩加速 在cinder.conf配allow_compression_on_image_upload True可打开开关 compression_format xxx可设置镜像压缩格式&#xff0c;可为gzip 1.2 …