redis设计与实现5-Lua脚本、排序和二进制位数组

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: redis设计与实现5-Lua脚本、排序和二进制位数组

Lua脚本

重点回顾

  • Redis服务器在启动时,会对内嵌的Lua环境执行一系列修改操作,从未确保内嵌的Lua环境可以满足Redis在功能性和安全性等方面的需要
  • Redis服务器专门使用一个为客户端来执行Lua脚本中包含的redis命令
  • Redis使用脚本字典来保存所有被EVAL命令执行过,或者SCRIPT LOAD命令载入过的lua脚本,这些脚本可以用于实现SCRIPT EXISTS命令,以及实现脚本复制功能
  • EVAL命令为客户端输入的脚本在Lua环境中定义一个函数,并通过这个函数来执行脚本
  • EVALSHA命令通过直接调用Lua脚本中已定义的函数来执行脚本
  • script flush命令会清空服务器lua_scripts字典中保存的脚本,并充值Lua环境
  • SCRIPT EXISTS命令接收一个或多个SHA1校验和为参数,并通过lua_scripts字典确认校验和对应脚本是否存在
  • SCRIPT LOAD命令接受一个Lua脚本为参数,为该脚本在Lua环境中创建函数,并将脚本保存在lua_scripts脚本中
  • 服务器在执行脚本之前,会为lua环境设置一个超时处理的钩子,当脚本出现超时运行情况时,客户端可以铜鼓向服务器发送SCRIPT KILL 命令让钩子停止正在执行的脚本,或者发送SHUTDOWN nosave命令让钩子关闭整个服务器
  • 主服务器复制EVAL 、 SCRIPT FLUSH、SCRIPT LOAD 三个命令的方法和复制普通Redis命令一样,只要将相同的命令传播给从服务器就可以
  • 主服务器在复制EVALSHA命令中,必须确保素有从服务器都已经载入了EVALSHA命令指定的SHA1校验和对应的脚本,如果不能确保这一点,主服务器会将EVALSHA命令转成等效的EVAL命令,并通过EVAL命令来获得相同的脚本执行效果

排序

回顾

  • SORT命令通过将被排序键包含的元素载入到数组里,然后对数组进行排序
  • 默认情况下,SORT命令假设被排序键包含的都是数字值,以数字值的方式进行排序
  • SORT命令使用了ALPHA选项,那么SORT命令假设被排序键包含的都是字符串,以字符串的方式进行排序
  • SORT命令的排序操作快排算法实现
  • SORT命令会根据用户是否使用了DESC选项决定使用升序还是降序
  • SORT命令使用BY选项时,命令使用其他键的值来进行排序操作
  • SORT命令使用LIMIT选项时,命令只保留排序结果集中LIMIT选项指定的元素
  • SORT命令使用STORE选项时,会将排序结果集保存在指定的键里面
  • SORT命令同时使用多个选项时,,先执行排序操作(ALPHA、ASC、DESC、BY),然后执行LIMIT选项,之后执行GET选项,再执行STORE选项,最后将排序结果集返回给客户端
  • 除了GET选项之外,调整选项的摆放位置不会影响STORE命令的排序结果

二进制位数组

位数组的表示

使用字符串对象表示位数组,因为字符串对象使用SDS数据结构是二进制安全的

image.png

buf数组保存的顺序和我们平时书写位数组的顺序是完全相反的,上图中位数组为 0100 1101 ,

假如每次扩展buf数组之后,程序都需要将位数组已有的位进行移动,然后才执行写入操作,这比setbit命令实现方式更复杂,而且移位带来的CPU时间消耗也会影响命令的执行速度,所以采用setbit命令采用倒序的方式完成扩展,写入操作可以直接在扩展的二进制未中完成,而不必改动数组原来已有的二进制位

bitcount命令实现

三种常用的算法:

  • 遍历算法
  • 查表算法,保存一张表,表的键为某种排列的位数组,值为该位数组中1的个数
  • image.png
  • 二进制位统计算法:variable-precision SWAR算法:计算汉明重量

Redis中采用的算法:

采用了查表和cariable-precision SWAR两种算法,未处理的二进制位数大于等于128位,采用SWAR算法,否则采用查表算法;实现的算法负责度为O(n),n为输入二进制的数量

重点回顾

  • Redis使用SDS保存二进制数组
  • SDS使用逆序保存位数组,这种保存顺序简化了SETBIT命令的实现,使得setbit命令可以在不移动现有二进制位的情况下,对位数组进行空间扩展
  • BITCOUNT命令使用了查表和variable-precision SWAR算法优化命令的执行效率
  • BITOP命令的所有操作都使用C语言内置的位操作来实现

慢日志查询

回顾

  • Redis慢日志查询功能用于记录执行时间超过指定时长的命令
  • Redis服务器将所有的慢查询日志保存在服务器状态的slowlog链表中,每个链表节点都包含一个slowlogEntry结构,每个slowlogEntry结构表示一条慢查询日志
  • 打印和删除慢查询日志可以通过遍历slowlog链表完成
  • slowlog链表的长度就是服务器保存的慢查询日志的数量
  • 新的慢查询日志会被添加到slowlog链表的表头,如果日志的数量超过slowlog-max-len选项的值,多出来的日志将会删除

监视器

回顾

  • 客户端可以通过执行MONITOR命令,将客户端转换成监视器,接收并打印服务器处理的每个命令请求的相关信息
  • 当一个客户端从普通客户端变成监视器,这个客户端REDIS_MONITOR标识会被打开
  • 服务器将所有的监视器记录在monitors链表中
  • 每次处理命令请求中,服务器都会遍历monitors链表,将相关信息发送给监视器



相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
29天前
|
存储 NoSQL Redis
Redis的Lua脚本有什么作用?
Redis Lua脚本用于减少网络开销、实现原子操作及扩展指令集。它能合并操作降低网络延迟,保证原子性,替代不支持回滚的事务。通过脚本,代码复用率提高,且可自定义指令,如实现分布式锁,增强Redis功能和灵活性。
26 1
|
2月前
|
存储 缓存 Java
Openresty(lua+nginx)-Guava-Redis做多级缓存
Openresty(lua+nginx)-Guava-Redis做多级缓存
24 1
|
7天前
|
存储 NoSQL 调度
Redis Lua脚本:原子性的真相揭秘
【4月更文挑战第20天】
24 0
Redis Lua脚本:原子性的真相揭秘
|
26天前
|
NoSQL Java Redis
lua脚本做redis的锁
这段内容是关于使用Redis实现分布式锁的Java代码示例。`RedisLock`类包含`lock`和`unlock`方法,使用`StringRedisTemplate`和Lua脚本进行操作。代码展示了两种加锁方式:一种带有过期时间,另一种不带。还提到了在加锁和解锁过程中的异常处理,并提供了相关参考资料链接。
18 3
|
29天前
|
存储 NoSQL 数据处理
Redis Lua脚本:赋予Redis更强大的逻辑与功能
Redis Lua脚本:赋予Redis更强大的逻辑与功能
|
2月前
|
监控
通过Lua脚本实现禁止员工上班玩游戏的软件的自动化任务管理
使用Lua脚本,企业可以自动化管理员工行为,防止上班时间玩游戏。Lua是一种轻量级脚本语言,适合编写监控任务。示例脚本展示了如何检测工作时间内员工是否玩游戏,并在发现时执行相应操作,如关闭游戏或发送警告。此外,另一脚本演示了如何将监控数据通过HTTP POST自动提交到网站,以实现有效的行为管理。这种解决方案灵活且可定制,有助于提升工作效率。
138 1
|
2月前
|
NoSQL Java 数据库
优惠券秒杀案例 - CAS、Redis+Lua脚本解决高并发并行
优惠券秒杀案例 - CAS、Redis+Lua脚本解决高并发并行
100 0
|
缓存 NoSQL Redis
Redis命令——脚本
Redis 脚本使用 Lua 解释器来执行脚本。 Reids 2.6 版本通过内嵌支持 Lua 环境。执行脚本的常用命令为 EVAL。
1356 0
|
缓存 NoSQL Redis
redis必杀命令:脚本
题记: Redis 脚本使用 Lua 解释器来执行脚本。 Reids 2.6 版本通过内嵌支持 Lua 环境。执行脚本的常用命令为 EVAL。
1260 0
|
22天前
|
存储 NoSQL 算法
09- Redis分片集群中数据是怎么存储和读取的 ?
Redis分片集群使用哈希槽分区算法,包含16384个槽(0-16383)。数据存储时,通过CRC16算法对key计算并模16383,确定槽位,进而分配至对应节点。读取时,根据槽位找到相应节点直接操作。
54 12