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

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
日志服务 SLS,月写入数据量 50GB 1个月
简介: 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
目录
相关文章
|
1月前
|
缓存 NoSQL Redis
Redis 脚本
10月更文挑战第18天
33 3
|
3月前
|
NoSQL Redis
Redis 执行 Lua保证原子性原理
Redis 执行 Lua 保证原子性原理
362 1
|
24天前
|
SQL NoSQL 关系型数据库
2024Mysql And Redis基础与进阶操作系列(5)作者——LJS[含MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页等详解步骤及常见报错问题所对应的解决方法]
MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页、INSERT INTO SELECT / FROM查询结合精例等详解步骤及常见报错问题所对应的解决方法
|
1月前
|
缓存 NoSQL Java
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
61 3
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
|
1月前
|
缓存 分布式计算 NoSQL
大数据-43 Redis 功能扩展 Lua 脚本 对Redis扩展 eval redis.call redis.pcall
大数据-43 Redis 功能扩展 Lua 脚本 对Redis扩展 eval redis.call redis.pcall
31 2
|
1月前
|
NoSQL Java 关系型数据库
阿里 P7二面:Redis 执行 Lua,到底能不能保证原子性?
Redis 和 Lua,两个看似风流马不相及的技术点,为何能产生“爱”的火花,成为工作开发中的黄金搭档?技术面试中更是高频出现,Redis 执行 Lua 到底能不能保证原子性?今天就来聊一聊。 
86 1
|
1月前
|
NoSQL 算法 Redis
Redis的实现三:c语言实现平衡二叉树,通过平衡二叉树实现排序集
本博客介绍了如何在C语言中实现一个平衡二叉树,并通过这个数据结构来模拟Redis中的排序集功能。
15 0
|
2月前
|
存储 JSON Ubuntu
如何使用 Lua 脚本进行更复杂的网络请求,比如 POST 请求?
如何使用 Lua 脚本进行更复杂的网络请求,比如 POST 请求?
|
3月前
|
缓存 监控 NoSQL
【Azure Redis 缓存】使用Python代码获取Azure Redis的监控指标值 (含Powershell脚本方式)
【Azure Redis 缓存】使用Python代码获取Azure Redis的监控指标值 (含Powershell脚本方式)
|
3月前
|
NoSQL Shell Redis
redis一键巡检脚本分享
redis一键巡检脚本分享
43 0
下一篇
无影云桌面