Redis中的Lua脚本

EVAL 命令
命令格式
EVAL script numkeys key [key ...] arg [arg ...]
命令说明

1、script 参数:

  • 一段Lua脚本程序,会在Redis服务器上下文中运行,不需要(也不应该)定义为一个Lua函数。

2、numkeys 参数:

  • 指定键名参数的个数。

3、key [key …] 参数:

  • 从EVAL的第三个参数开始,使用了numkeys个键,这些键名参数可以在Lua中通过全局变量KEYS数组,用1为基址的形式访问(KEYS[1], KEYS[2]···)。

4、arg [arg …]参数:

  • 可以在Lua中通过全局变量ARGV数组访问,访问形式和KEYS变量类似(ARGV[1], ARGV[2]···)。
示例
eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second

在这个示例中,key [key …] 参数的作用并不明显。其最大的作用是在Lua脚本中调用Redis命令。

Lua脚本中调用Redis命令

使用call()命令:

eval "return redis.call('mset',KEYS[1],ARGV[1],KEYS[2],ARGV[2])" 2 key1 key2 first second
EVALSHA 命令

EVAL命令每次执行脚本时都需要发送脚本,因此Redis提供了内部缓存机制,避免每次重新编译脚本。然而,这样会消耗带宽。为此,Redis提供了EVALSHA命令,其功能与EVAL相同,但接受的第一个参数是脚本的SHA1摘要。

借助script命令:

  • script flush:清除所有脚本缓存。
  • script exists:检查指定脚本是否存在于缓存中。
  • script load:将一个脚本装入缓存,返回SHA1摘要,但不立即运行。
  • script kill:终止当前正在运行的脚本。

生成SHA1摘要:

script load "return redis.call('set',KEYS[1],ARGV[1])"

然后执行脚本:

evalsha "c686f316aaf1eb01d5a4de1b0b63cd233010e63d" 1 key1 testscript
redis-cli 执行脚本

使用redis-cli命令直接执行脚本,新建一个Lua脚本文件来获取Redis中存入的key1值。编写Lua命令:

local value = redis.call('get','key1')
return value

然后执行:

./redis-cli -p 6379 --eval ../scripts/test.lua

或:

./redis-cli -p 6379 script load "$(cat ../scripts/test.lua)"

Redis与限流

使用Redis+Lua语言实现限流

项目代码示例:

项目代码示例

方案好处:

  • 分布式支持:Redis 本身是单线程的,但可以通过在多个实例上运行 Lua 脚本来实现分布式限流。

使用Lua脚本的好处:

  • 减少网络开销:Lua 脚本在服务器端执行,减少了客户端与服务器之间的通信次数。
  • 原子操作:整个限流逻辑作为一个原子操作执行,不会出现并发问题。
  • 复用:脚本可以被多个客户端复用,无需每个客户端都发送相同的限流逻辑。

示例代码

-- 简单的限流 Lua 脚本示例
local limit = tonumber(ARGV[1])  -- 限流大小
local key = KEYS[1]              -- 用于限流的 Redis key
local current = redis.call('get', key)

if current then
    if tonumber(current) >= limit then
        return 0  -- 达到限流大小,返回 0
    else
        -- 如果当前数量小于限流大小,增加计数
        redis.call('incr', key)
        return 1
    end
else
    -- 如果是第一次请求,设置 key 并过期
    redis.call('set', key, 1, 'EX', ARGV[2])  -- ARGV[2] 是过期时间
    return 1
end

这个脚本可以被 EVAL 命令执行,用于控制对某个资源的访问频率。

通过这种方式,Redis 的 Lua 脚本功能不仅提高了性能,还增加了 Redis 在复杂场景下的可用性。

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搬砖的小熊猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值