Redis 排行榜:实现、操作与性能优化

Redis 是一个高性能的内存数据库,支持多种数据结构,其中有序集合(Sorted Set)特别适合用于实现排行榜功能。本文将详细介绍如何使用 Redis 的有序集合实现一个简单而高效的排行榜系统,包括排行榜的基本操作、示例代码以及优化建议。

一,有序集合(Sorted Set)简介

有序集合是 Redis 提供的一种数据结构,它结合了集合和有序列表的特点。每个元素都有一个唯一的成员和一个分数,Redis 会根据分数对元素进行排序。常用的有序集合命令包括:

  • ZADD:向有序集合添加元素。
  • ZREM:移除有序集合中的元素。
  • ZINCRBY:增加有序集合中元素的分数。
  • ZRANGE:按分数从低到高获取有序集合中的元素。
  • ZREVRANGE:按分数从高到低获取有序集合中的元素。
  • ZRANK:获取元素在有序集合中的排名(从低到高)。
  • ZREVRANK:获取元素在有序集合中的排名(从高到低)。

二,实现排行榜的基本操作

1. 添加或更新分数

使用 ZADD 命令向排行榜中添加新用户或更新用户的分数。

import redis.clients.jedis.Jedis;public class Leaderboard {private Jedis jedis;private String leaderboardKey = "leaderboard";public Leaderboard() {jedis = new Jedis("localhost", 6379);}// 添加或更新用户分数public void addOrUpdateUserScore(String user, double score) {jedis.zadd(leaderboardKey, score, user);}
}

2. 获取前 N 名用户

使用 ZREVRANGE 命令按分数从高到低获取排行榜中的前 N 名用户。

import java.util.Set;public class Leaderboard {// 获取前 N 名用户public Set<String> getTopNUsers(int n) {return jedis.zrevrange(leaderboardKey, 0, n - 1);}
}

3. 获取用户的排名和分数

使用 ZREVRANK 命令获取用户在排行榜中的排名,使用 ZSCORE 命令获取用户的分数。

public class Leaderboard {// 获取用户排名(从高到低)public Long getUserRank(String user) {return jedis.zrevrank(leaderboardKey, user);}// 获取用户分数public Double getUserScore(String user) {return jedis.zscore(leaderboardKey, user);}
}

4. 删除用户

使用 ZREM 命令从排行榜中删除用户。

public class Leaderboard {// 删除用户public void removeUser(String user) {jedis.zrem(leaderboardKey, user);}
}

三,示例代码

以下是一个完整的示例代码,展示了如何使用 Redis 实现一个简单的排行榜系统。

import redis.clients.jedis.Jedis;import java.util.Set;public class Leaderboard {private Jedis jedis;private String leaderboardKey = "leaderboard";public Leaderboard() {jedis = new Jedis("localhost", 6379);}// 添加或更新用户分数public void addOrUpdateUserScore(String user, double score) {jedis.zadd(leaderboardKey, score, user);}// 获取前 N 名用户public Set<String> getTopNUsers(int n) {return jedis.zrevrange(leaderboardKey, 0, n - 1);}// 获取用户排名(从高到低)public Long getUserRank(String user) {return jedis.zrevrank(leaderboardKey, user);}// 获取用户分数public Double getUserScore(String user) {return jedis.zscore(leaderboardKey, user);}// 删除用户public void removeUser(String user) {jedis.zrem(leaderboardKey, user);}public static void main(String[] args) {Leaderboard leaderboard = new Leaderboard();// 添加或更新用户分数leaderboard.addOrUpdateUserScore("user1", 100.0);leaderboard.addOrUpdateUserScore("user2", 200.0);leaderboard.addOrUpdateUserScore("user3", 150.0);// 获取前 2 名用户Set<String> topUsers = leaderboard.getTopNUsers(2);System.out.println("Top 2 users: " + topUsers);// 获取用户排名和分数Long rank = leaderboard.getUserRank("user1");Double score = leaderboard.getUserScore("user1");System.out.println("User1 rank: " + rank + ", score: " + score);// 删除用户leaderboard.removeUser("user1");System.out.println("User1 removed.");}
}

四,优化建议

1. 使用管道(Pipeline)

当需要批量执行多个命令时,可以使用管道(Pipeline)来减少网络延迟,提高性能。

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;public class Leaderboard {private Jedis jedis;private String leaderboardKey = "leaderboard";public Leaderboard() {jedis = new Jedis("localhost", 6379);}// 批量添加或更新用户分数public void addOrUpdateUserScores(Map<String, Double> userScores) {Pipeline pipeline = jedis.pipelined();for (Map.Entry<String, Double> entry : userScores.entrySet()) {pipeline.zadd(leaderboardKey, entry.getValue(), entry.getKey());}pipeline.sync();}public static void main(String[] args) {Leaderboard leaderboard = new Leaderboard();// 批量添加或更新用户分数Map<String, Double> userScores = new HashMap<>();userScores.put("user1", 100.0);userScores.put("user2", 200.0);userScores.put("user3", 150.0);leaderboard.addOrUpdateUserScores(userScores);// 获取前 2 名用户Set<String> topUsers = leaderboard.getTopNUsers(2);System.out.println("Top 2 users: " + topUsers);}
}

2. 使用缓存

如果排行榜数据不会频繁变化,可以将排行榜结果缓存到内存中,减少对Redis的频繁访问。

import redis.clients.jedis.Jedis;import java.util.HashMap;
import java.util.Map;
import java.util.Set;public class Leaderboard {private Jedis jedis;private String leaderboardKey = "leaderboard";private Map<Integer, Set<String>> cache = new HashMap<>();public Leaderboard() {jedis = new Jedis("localhost", 6379);}// 获取前 N 名用户,使用缓存public Set<String> getTopNUsers(int n) {if (cache.containsKey(n)) {return cache.get(n);} else {Set<String> topUsers = jedis.zrevrange(leaderboardKey, 0, n - 1);cache.put(n, topUsers);return topUsers;}}public static void main(String[] args) {Leaderboard leaderboard = new Leaderboard();// 添加或更新用户分数leaderboard.addOrUpdateUserScore("user1", 100.0);leaderboard.addOrUpdateUserScore("user2", 200.0);leaderboard.addOrUpdateUserScore("user3", 150.0);// 获取前 2 名用户,使用缓存Set<String> topUsers = leaderboard.getTopNUsers(2);System.out.println("Top 2 users: " + topUsers);}
}

3. 使用分片(Sharding)

对于大规模的排行榜,可以使用分片技术,将数据分布到多个Redis实例中,减少单个实例的压力。

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;import java.util.ArrayList;
import java.util.List;public class ShardedLeaderboard {private ShardedJedis shardedJedis;public ShardedLeaderboard() {List<JedisShardInfo> shards = new ArrayList<>();shards.add(new JedisShardInfo("localhost", 6379));shards.add(new JedisShardInfo("localhost", 6380));shardedJedis = new ShardedJedis(shards);}// 添加或更新用户分数public void addOrUpdateUserScore(String user, double score) {shardedJedis.zadd("leaderboard", score, user);}// 获取前 N 名用户public Set<String> getTopNUsers(int n) {return shardedJedis.zrevrange("leaderboard", 0, n - 1);}public static void main(String[] args) {ShardedLeaderboard leaderboard = new ShardedLeaderboard();// 添加或更新用户分数leaderboard.addOrUpdateUserScore("user1", 100.0);leaderboard.addOrUpdateUserScore("user2", 200.0);leaderboard.addOrUpdateUserScore("user3", 150.0);// 获取前 2 名用户Set<String> topUsers = leaderboard.getTopNUsers(2);System.out.println("Top 2 users: " + topUsers);}
}

通过以上优化建议,开发者可以进一步提升Redis排行榜系统的性能和可扩展性,确保在高并发和大数据量的情况下依然能够高效运行。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从零开始构建:Python自定义脚本自动化你的日常任务

从零开始构建&#xff1a;Python自定义脚本自动化你的日常任务 Python 作为一种简洁且功能强大的编程语言&#xff0c;被广泛应用于各种自动化任务中。通过编写 Python 脚本&#xff0c;你可以轻松地将日常重复性工作自动化&#xff0c;例如文件操作、数据处理、网络爬虫、系统…

vue3--通用 button 组件实现

背景 在日常开发中,我们一般都是利用一些诸如:element-ui、element-plus、ant-design等组件库去做我们的页面或者系统 这些对于一些后台管理系统来说是最好的选择,因为后台管理系统其实都是大同小异的,包括功能、布局结构等 但是对于前台项目,比如官网、门户网站这些 …

【Linux驱动开发】嵌入式Linux驱动开发基本步骤,字符驱动和新字符驱动开发入门,点亮LED

【Linux驱动开发】嵌入式Linux驱动开发基本步骤&#xff0c;字符驱动和新字符驱动开发入门&#xff0c;点亮LED 文章目录 开发环境驱动文件编译驱动安装驱动自动创建设备节点文件 驱动开发驱动设备号地址映射&#xff0c;虚拟内存和硬件内存地址字符驱动旧字符驱动新字符驱动 …

live2d 实时虚拟数字人形象页面显示,对接大模型

live2dSpeek 测试不用gpu可以正常运行 https://github.com/lyz1810/live2dSpeek 运行的话还需要额外下载https://github.com/lyz1810/edge-tts支持语音 ## 运行live2dSpeek >npm install -g http-server >http-server . ## 运行edge-tts python edge-tts.py

使用 Helsinki-NLP 中英文翻译本地部署 - python 实现

通过 Helsinki-NLP 本地部署中英文翻译功能。该开源模型性价比相对高&#xff0c;资源占用少&#xff0c;对于翻译要求不高的应用场景可以使用&#xff0c;比如单词&#xff0c;简单句式的中英文翻译。 该示例使用的模型下载地址&#xff1a;【免费】Helsinki-NLP中英文翻译本…

心觉:激活潜意识财富密码:每天一练,财富自动来

Hi&#xff0c;我是心觉&#xff0c;与你一起玩转潜意识、脑波音乐和吸引力法则&#xff0c;轻松掌控自己的人生&#xff01; 挑战每日一省写作200/1000天 为什么有些人总是轻而易举地吸引到财富 而你却努力多年仍然徘徊在财务的困境中&#xff1f; 你每天都在辛苦工作&…

MambaVision原理和源码调测

Hatamizadeh, Ali and Jan Kautz. “MambaVision: A Hybrid Mamba-Transformer Vision Backbone.” ArXiv abs/2407.08083 (2024): n. pag. 1.模型原理 关键思路&#xff1a; 通过重新设计Mamba的架构和在最终层增加自注意力块&#xff0c;提高了Mamba模型对视觉特征的建模能力…

C语言练习

题目&#xff1a; 1.运用switch选择语句&#xff0c;编写一段C语言&#xff0c;请根据输入的数字&#xff0c;显示相应的星期日&#xff0c;如果数字所对应的星期日并不存在请显示“抱歉&#xff0c;您输入的内容并不存在。” 分析&#xff1a;1.在本题中&#xff0c;要运用到…

C语言之扫雷小游戏(完整代码版)

说起扫雷游戏&#xff0c;这应该是很多人童年的回忆吧&#xff0c;中小学电脑课最常玩的必有扫雷游戏&#xff0c;那么大家知道它是如何开发出来的吗&#xff0c;扫雷游戏背后的原理是什么呢&#xff1f;今天就让我们一探究竟&#xff01; 扫雷游戏介绍 如下图&#xff0c;简…

【网络安全】漏洞案例:提升 Self-XSS 危害

未经许可,不得转载。 文章目录 Self-XSS-1Self-XSS-2Self-XSS-1 目标应用程序为某在线商店,在其注册页面的First Name字段中注入XSS Payload: 注册成功,但当我尝试登录我的帐户时,我得到了403 Forbidden,即无法登录我的帐户。 我很好奇为什么我无法登录我的帐户,所以我…

如何破解 AI 聊天机器人让它们吐露秘密!窥探 AI 系统指令的 10 种技巧

​ 有时&#xff0c;为了确保 AI 的安全性和透明性&#xff0c;用户需要自己动手&#xff0c;揭开系统指令的面纱。 如果人工智能现在已经成为生活中的事实&#xff0c;并影响着我们的福祉&#xff0c;人们理应知道它的运作原理。 对一些人来说&#xff0c;科幻电影中的经典…

新装ubuntu22.04必做两件事,不然可能没法用

一、换服务源 在全部里面找到软件和安装&#xff1b;打开后 在更多里面匹配一下最适合自己的软件源&#xff1b;这个过程比较漫长&#xff1b;要耐心等待 二、换软件安装中心 先执行&#xff1a; sudo apt upgrade 后执行&#xff1a; sudo apt install plasma-discover…

初级网络工程师之从入门到入狱(四)

本文是我在学习过程中记录学习的点点滴滴&#xff0c;目的是为了学完之后巩固一下顺便也和大家分享一下&#xff0c;日后忘记了也可以方便快速的复习。 网络工程师从入门到入狱 前言一、Wlan应用实战1.1、拓扑图详解1.2、LSW11.3、AC11.4、抓包1.5、Tunnel隧道模式解析1.6、AP、…

【AIF-C01认证】亚马逊云科技生成式 AI 认证正式上线啦

文章目录 一、AIF-C01简介二、考试概览三、考试知识点3.1 AI 和 ML 基础知识3.2 生成式人工智能基础3.3 基础模型的应用3.4 负责任 AI 准则3.5 AI 解决方案的安全性、合规性和监管 四、备考课程4.1 「备考训练营」 在线直播课4.2 「SkillBuilder」学习课程 五、常见问题六、参考…

Flutter技术学习

以下内容更适用于 不拘泥于教程学习&#xff0c;而是从简单项目入手的初学者。 在开始第一个项目之前&#xff0c;我们先要了解 两个概念。 Widget 和 属性 Widget 是用户界面的基本构建块&#xff0c;可以是任何 UI 元素。属性 是 widget 类中定义的变量&#xff0c;用于配…

【IEEE独立出版 | 厦门大学主办】第四届人工智能、机器人和通信国际会议(ICAIRC 2024)

【IEEE独立出版 | 厦门大学主办】 第四届人工智能、机器人和通信国际会议&#xff08;ICAIRC 2024&#xff09; 2024 4th International Conference on Artificial Intelligence, Robotics, and Communication 2024年12月27-29日 | 中国厦门 >>往届均已成功见刊检索…

深入理解Transformer的笔记记录(精简版本)NNLM → Word2Vec

文章的整体介绍顺序为&#xff1a; NNLM → Word2Vec → Seq2Seq → Seq2Seq with Attention → Transformer → Elmo → GPT → BERT 自然语言处理相关任务中要将自然语言交给机器学习中的算法来处理&#xff0c;通常需要将语言数学化&#xff0c;因为计算机机器只认数学符号…

Node.js管理工具NVM

nvm&#xff08;Node Version Manager&#xff09;是一个用于管理多个 Node.js 版本的工具。以下是 nvm 的使用方法和一些常见命令&#xff1a; 一、安装 nvm 下载 nvm&#xff1a; 地址&#xff1a;https://github.com/coreybutler/nvm-windows/releases访问 nvm 的 GitHub 仓…

稳字诀! 洞见 强者的社交格局:从不恋战——早读(逆天打工人爬取热门微信文章解读)

都是文字 引言Python 代码第一篇 洞见 强者的社交格局&#xff1a;从不恋战第二篇 稳字诀结尾 引言 今天很奇怪 一直都挺烦造的 好像有很多事情忙 但是就是忙着找不定 不能定下心来 主要还是在股市 其他方面应该没啥 计划表还是不够给力 没办法把心在约定住 稳字诀 勤燃香,奋…

GPT和BERT

GPT和BERT都是基于Trm的应用&#xff0c;可以理解为GPT是decoder的应用&#xff0c;BERT可以说是encoder的应用 GPT 如图&#xff0c;就是GPT的原理&#xff0c;GPT是做生成式的任务的&#xff0c;没有办法进行下游任务改造&#xff0c;训练也是针对生成式的任务进行训练 BE…