美文网首页Java 杂谈
redis 与 lua 的结合

redis 与 lua 的结合

作者: fkxuexi | 来源:发表于2019-04-08 20:21 被阅读6次

一、前言:

redis 为我们提供了很多的命令,但是很多时候我们需要组合这些命令,但是有设计到一个问题:命令组合起来之后,在高并发的情况下,怎么保证原子性呢?此时lua为我们提供了解决的方案。lua 还是比较好入门的,但是我今天在玩这个玩意儿的时候还是遇到了很多问题,因为分享出来希望大家不会遇到这个问题。

二、还是言明环境:

  • redis 3.2.100 for windows
    因为最近 windows10 for docker 的网络没有整明白不得已在windows安装了redis,这种东西最好是在linux下面玩

三、lua 与 reids 的简单入门:

这里只是做一个简单的介绍,因为在这里详细的介绍一门语言不现实,还是以使用为主,

3.1 实现一个简单的需求:

  • 获取以天为自增的唯一序列
    • 这个里面首先需要自增,肯定是要使用到 incr 这个命令的
    • 其实需要以天为单位,说明这个序列是需要有过期时间的
    • 需要批量的生成,因为是进行批量的请求,但是总不能每一条记录都请求一次这个太不划算,io交互太多
      ps:在新版的 RedisTemplate 里面提供了这个方法,自增的同时是可以设置过期时间的,但是项目中配置的是 jedis,所以很无奈的只能自己造。这个通过事务也能实现,但是没有必要,lua可以是一个更好的选择

3.2 lua 的简单入门:

  • 接受外面传入的参数key
    local key = KYES[1]
    local 表明这个是局部变量,建议能用局部变量就用局部变量
  • 接受值,例如过期时间或者key对应的值
    local tll = ARGV[1]
  • 在 lua 中的一些结构,对于if for 这样的语句块需要使用 end 来作为结尾,例如:
if    true then
  todo
end
for i=0,len do
  todo
end
  • lua 中的注释是以 -- 来标示的
  • lua 中的调用redis 命令:redis.call('commond',key,val……)
  • lua 中字符串拼接使用 .. 即可拼接

3.3 开始实战:

新建文件以 .lua 结尾

-- 接受key
local key = KEYS[1]
-- 接受过期时间
local ttl = ARGV[1]
-- 需要生成的个数
local len = ARGV[2] 
-- 定义一个接受的数组,来接受批量生成的序列号
local codeArr = {}
-- 判断,如果key不存在,则先初始化key,且设置过期时间
if redis.call('EXISTS',key) == 0 then 
-- 插入一条记录
    redis.call('SET',key,0)
-- 设置过期时间
    redis.call('EXPIRE',key,ttl)
end
for i = 0 , len do
-- 循环产生序列号,并放置到数组当中,
    codeArr[i] = redis.call('INCR',key)
end 
-- 返回给客户端
return codeArr  

3.4 redis 客户端调用 lua 脚本

ps:注意下面演示的是在 windows 的环境下

  • 进入到 redis 的安装的bin目录
  • 在cmd命令窗口中执行下列命令:
redis-cli.exe --eval ExistAndIncre.lua RESERVE_CODE , 100000 10

需要注意的是:

  • 我们不能进入到redis的客户端里面去了,要在外面的环境中执行,否则会报错
  • --eval lua文件位置 后面的第一个参数不需要知名有多少个key,否则这个就会作为 KEYS[1] 的值,目前不知道原因,测试出来的是这样的结果,这个和大多博客上的描述的不一样,切记


    image.png
    image.png
  • 中间的 ',' 注意前后都有一个空格,同时后面多个值的时候使用空格隔开即可

四、lua 的好处:

lua 主要是类似于批处理的功能,把众多的命令组合起来进行执行,但是这些在 lua 脚本中组合的命令是原子的,在高并发的情况下很多时候判断和执行如果不是原子的话,由于先后顺序的原因很有可能发生数据不一致的情况,所以我们要避免在判断和执行之间不能有时间窗口,lua就是为了解决这个问题的

很多复杂的场景中,需要组合众多的 redis 的命令的时候就可以考虑 lua ,在 redisson 的框架中的实现也是大量的采用了lua脚本的

由于工作需要来学习的,所以不是很深入,以后有机会再使用到在慢慢的补。

博客首发地址csdn:https://blog.csdn.net/weixin_42849915
简书地址:https://www.jianshu.com/u/4b48be4cf59f
希望结识更多的乐于分享的伙伴一起前行

相关文章

  • redis 与 lua 的结合

    一、前言: redis 为我们提供了很多的命令,但是很多时候我们需要组合这些命令,但是有设计到一个问题:命令组合起...

  • 9.lua脚本与redis结合

    Redis和Lua结合 1:redis.call:在脚本中调用Redis命令,遇到错误会直接返回 2:redis....

  • 分布式锁之redis-lua脚本

    目录 redis分布式锁,Lua,Lua脚本,lua redis,redis lua 分布式锁,redis set...

  • Redis 文章转载

    php结合redis/lua实现分布式redis锁 Redis面试题整理-字节头条腾讯面试题 (2020最新版含详...

  • Redis第四天

    Redis+Lua语言限流实战 Redis+LUA语言限流流程图 Redis+Lua语言抢红包实战

  • Spring Cache与Redis结合使用

    Spring Cache与Redis结合使用 Spring Cache与Redis结合使用Redis创建Sprin...

  • Redis Lua编程与调试工具使用

    前言 Redis自2.6.0版本开始内置Lua解释器。 Lua,轻量级脚本语言,号称最快的脚本语言。 两者结合将爆...

  • Redis

    1、为什么lua脚本结合redis命令可以实现原子性 Redis 提供了非常丰富的指令集,但是用户依然不满足,希望...

  • 《redis学习》之lua

    Redis+Lua的好处 redis在2.6开始加入了lua脚本,使用lua脚本有如下好处: 减少网络开销。复合操...

  • lua与redis pipeline

    lua Redis在2.6版引入了对Lua的支持 使用Lua可以非常明显的提升Redis的效率。 只要脚本所对应的...

网友评论

    本文标题:redis 与 lua 的结合

    本文链接:https://www.haomeiwen.com/subject/unapiqtx.html