使用Redis实现游戏排行榜

排行榜在当今应用中扮演着至关重要的角色。无论是游戏中的玩家排名、社交平台的用户活跃度榜单,还是其他领域的各种榜单,排行榜都是用户参与性和互动性的关键。在实现排行榜功能时,选择合适的数据库和数据结构至关重要。Redis,作为一种内存数据库,以其高性能和灵活性而备受青睐。下面将探讨如何使用Redis的有序集合(Sorted Set)来实现排行榜功能。

1 Redis的有序集合

Redis是一种内存型数据库,查询效率高。Redis有一种数据结构叫有序集合(Sorted Set),与普通集合相比,它的每个成员都关联一个分数,这个分数用于对成员进行排序。有序集合在插入和查询时都能够以 O ( l o g n ) O(log{n}) O(logn)的复杂度完成,这为排行榜的实现提供了高效的基础。有序集合不仅提供了快速的插入和查询操作,还支持范围查询,使得获取某个范围内的排名成员变得非常简单。

(关于Sorted Set如何实现高效的插入和查询,可以看我的这篇文章《Redis的跳跃表》)

2 使用有序集合实现排行榜

那么,我们要如何用Sorted Set来实现排行榜呢?

其实非常简单,首先根据需求,我们定义一个有序集合的key,例如:

  • 玩家等级的排行榜,我们可以用rank:level来作key值。
  • 每天更新的排行榜,可以在后面加个日期rank:level:0412
  • 还有些比如是每天对指定BOSS的伤害排行,可以用rank:damage:bossID:0412

当排行数值改变的时候,我们用zadd指令来更新数据:

zadd rank:level 玩家等级 玩家ID #参数是`score`和`member`

也可以用

ZINCRBY rank:level 10 lxx1 #使lxx1的积分增加10(如果lxx1在rank:level中不存在,则新增,设置积分为10)

需要查询排行榜数据的时候,我们用zrevrange指令来获取数据(下标是从0开始):

zrevrange rank:level 0 99 WITHSCORES    # 获取前100名的ID和分数
zrevrange rank:level 100 199 WITHSCORES # 获取101-200名的ID和分数
zrevrange rank:level 0 99               # 仅获取ID

这里我们使用zrevrange,因为zset是按从小到大排序的,zrevrange是逆序返回zset中的数据。

取出玩家ID之后,我们再从另外的地方(MySQLredis或者内存中)获取玩家的其他数据(名字,头像等),组合出完整的榜单数据。

查看排行玩家的排行和数值:

zscore rank:level lxx1 #获取玩家lxx1的分数
zrevrank rank:level lxx1 #获取玩家lxx1的排名

如果要移除某个玩家的排行,可以使用zrem指令:

zrem rank:level 玩家ID

3 实现数值相同时,按时间先后排序

游戏排行榜中,经常有这样的需求:玩家等级相同时,按照到达这个等级的时间先后顺序排序。

使用Sorted Set时,我们可以将数值乘以一个系数,然后加上时间戳来实现这个功能。

比如,玩家等级27级,当前时间戳是1705589522,我们可以将这两个数组组合起来,由于时间戳是越小排序越前(和等级越大排序越前相反),我们使用相减的方式:

val = 27*1e10 + 1e10 - 1705589522

最终的结果是278294410478,其中前面的27表示等级,后面的8294410478是时间戳和1e10的差值(10位数的时间戳最大可以用到2086年,有生之年够用了),等级越大,这个值越大,而等级相同时,时间戳小的值更大。

值得注意的是,Sorted Set底层是使用double类型来存储数值,所以当排序的值过大时,加上这个时间戳可能就会不够精细。

通常来说,使用double能表示的精确的正整数可以达到 2 53 − 1 {2}^{53}-1 2531(900719925474099116位数字)(关于这个值的计算,可以看我的另一篇文章《double 类型中可精确表达的最大正整数》)

不过对于排行榜而言,如果本身的数值已经很大了,通常也不需要按照时间来排序了。比如BOSS伤害十几亿,这时候玩家连具体数值可能都看不到,通常也不会相同,用不着时间先后排序了。

4 排行榜的合并

合服的时候,使用Sorted Set也可以很方便的合并排行榜。

Redis提供了并集(zunionstore)操作,并集指的是将两个或多个zset中的元素合并为一个新的zset

它的语法如下:

ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]

其中destination表示合并到的目标keynumkeys表示后面有多少个key要用来合并。例如有三个key需要合并:rank:s1:levelrank:s2:levelrank:s3:level,我们可以这样写:

ZUNIONSTORE rank:s1:level 3 rank:s1:level rank:s2:level rank:s3:level

表示将三个key合并,然后存储到rank:s1:level这个key中。

不过需要注意的是,在Redis的集群模式下,这样操作有可能会报错。(具体看这里《Redis 报错:CROSSSLOT Keys in request don’t hash to the same slot 的解决方案》)。

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

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

相关文章

golang学习笔记(内存逃逸分析)

golang的内存逃逸 逃逸分析( Escape analysis) 是指由编译器决定内存分配的位置, 不需要程序员指定。 函数中申请一个新的对象。 如果分配在栈中, 则函数执行结束可自动将内存回收;如果分配在堆中, 则函数…

解决layui的bug 在layui tree 组件中 禁用选中父节点后自动选中子节点功能

最近做权限管理后台,用了layui tree 组件,发现选中了父节点后,自动选中了子节点。不满足现实业务需求。所以微调了下源代码。 在用树形组件中,在用文档中 tree.setChecked(demoId, [2, 3]); //批量勾选 id 为 2、3 的节点 用这句…

linux 服务器利用阿里网盘API实现文件的上传和下载

文章目录 背景脚本初始化 阿里云盘API工具 aligo安装aligoaligo教程实战parse.py 演示上传文件上传文件夹下载文件下载文件夹 背景 最近在用ubuntu系统做实验,而ubuntu 系统的文件上传和下载操作很麻烦; 于是便打算使用阿里网盘的API 进行文件下载与上传…

腾锐D2000-8 MXM VPX,全国产,可广泛应用于边缘计算网关、入侵检测、VPN、网络监控等等应用领域

腾锐D2000-8 MXM VPX 1. 概述 XMVPX-108 是一款基于飞腾 D2000/8 处理器的低功耗逻辑运算和图形处理 VPX 刀片, 板贴 32GB DDR4 内存,搭载飞腾 X100 套片,满足通用 IO 接口功能。GPU 采用 MXM 小型插卡形式, 搭配 8GB 显卡。提供…

NIO和NIO.2对比

Java NIO (New Input/Output) 是从Java 1.4版本开始引入的一个新的I/O API,用于替代原来的BIO(Blocking I/O)API。NIO提供了更加灵活和高效的网络通信方式,特别适合于高吞吐量的网络编程。NIO的主要特点是非阻塞模式,它…

3.4 无关、基和维度

这一节是关于子空间的真实大小。对于 m n m\times n mn 的矩阵,它有 n n n 个列,但是它真正的维数不一定为 n n n,维数可以由无关列的个数来得到。列空间的实际维度就是秩 r r r。 无关的概念是用于向量空间中的任意向量 v 1 , . . . ,…

【LAMMPS学习】八、基础知识(5.7)Drude感应偶极子

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语,以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

人工智能|推荐系统——工业界的推荐系统之召回

基于物品的协同过滤 ⽤索引,离线计算量⼤,线上计算量⼩ Swing额外考虑重合的⽤户是否来⾃⼀个⼩圈⼦,两个⽤户重合度⼤,则可能来⾃⼀个⼩圈⼦,权重降低。 基于用户的协同过滤 同样是离线计算索引,在线召回的流程 离散特征处理 Embedding 层参数数量=向量维度 类别数量 矩

DS高阶:图论算法经典应用

一、最小生成树(无向图) 在了解最小生成树算法之前,我们首先要先了解以下的准则: 连通图中的每一棵生成树,都是原图的一个极大无环子图,即:从其中删去任何一条边,生成树就不在连通&a…

mysql查询数据不对

sum(id)是算id这一列的数值总和,无论主键与否,sum都是算数值总和 count(id)或count(*)是算当前列的行数,id是主键才行

第十三节:Vben Admin实战-系统管理之菜单管理

系列文章目录 基础篇 第一节:Vben Admin介绍和初次运行 第二节:Vben Admin 登录逻辑梳理和对接后端准备 第三节:Vben Admin登录对接后端login接口 第四节:Vben Admin登录对接后端getUserInfo接口 第五节:Vben Admin权限-前端控制方式 第六节:Vben Admin权限-后端控制方式…

MYSQL从入门到精通(一)

1、概述 【1】使用率最高 2、数据库的重要性 【1】数组、集合、文件 【2】数据管理系统-MySQL 【3】持久化数据,容易管理、查询 3、相关概念 【1】DB database 数据库 【2】DBMS 数据库管理系统(MySQL就是其中一种) 【3】SQL 结构查询语…

SQL-慢查询的定位及优化

定位慢查询sql 启用慢查询日志: 确保MySQL实例已经启用了慢查询日志功能。可以通过以下命令查看是否启用: SHOW VARIABLES LIKE slow_query_log;如果未启用,可以通过以下命令启用: SET GLOBAL slow_query_log ON;配置慢查询日志&…

商业银行终端安全管理创新与实践

文章目录 前言一、终端使用和管理现状二、终端面临的安全风险1、传统的终端安全工具无法有效识别新型威胁2、黑客攻击的目标重心瞄向终端三、终端安全防护技术的探索和实践1、远程办公场景首次尝试基于威胁情报技术的木马防护措施,取得良好成效2、自研终端数字化管控系统,提升…

GUI SWING从入门到精通

**************************************************************************************************************************************************************************** 1、百闻不如一经历 package com.day; import com.day.pojo.SonFrame;// 主函数入口 publ…

网络基础-子网与子网划分

子网 子网(Subnet)是将一个大的IP地址空间划分成若干个小的子网络的过程。在网络中,IP地址用于唯一标识网络中的设备。子网允许网络管理员将网络分割成更小的部分,以便更有效地管理和组织网络资源。每个子网都有一个独特的IP地址范…

Windows 下用 git clone ... 下载资料,资料下载到什么地方去了?

当你使用 git clone 命令在 Windows 系统上克隆一个仓库时,资料会被下载到你指定的目录中。如果你没有指定目录,那么资料会被下载到你当前所在的目录(命令提示符或终端的当前工作目录)中的一个新文件夹里,这个文件夹的…

FIFO Generate IP核使用——AXI接口FIFO简介

AXI接口FIFO是从Native接口FIFO派生而来的。AXI内存映射接口提供了三种样式:AXI4、AXI3和AXI4-Lite。除了Native接口FIFO支持的应用外,AXI FIFO还可以用于AXI系统总线和点对点高速应用。 AXI接口FIFO不支持Builtin FIFO和 Shift Register FIFO配置。 当…

WebSocket 多屏同显和异显

介绍 多屏同显:通过在一个应用上进行操作之后,另一个应用也能跟着一起发生改变,例如app1播放了晴天这首音乐,那么app2也要同步播放这首音乐,确保所有屏幕显示的内容完全相同。多屏异显:每个屏幕可以显示不同的内容,或者在内容更新时存在一定的延迟,而不需要严格保持同步…

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(四)

本系列课程,将重点讲解Phpsploit-Framework框架软件的基础使用! 本文章仅提供学习,切勿将其用于不法手段! 继续接上一篇文章内容,讲述如何进行Phpsploit-Framework软件的基础使用和二次开发。 当我们牢记登陆账户、…