在Redis中使用Lua脚本

原子性问题

  • redis虽然是单一线程的,仍然会存在线程安全问题
    • 这个线程安全问题不是来源于Redis服务器内部
    • 是来源于提供给多个客户端使用
      • 多个客户端之间没有做好数据的同步策略,
        • 就会产生数据不一致的问题

效率问题

  • redis本身的吞吐量是非常高的,
    • 因为它首先是基于内存的数据库。
    • 在实际使用过程中,有一个非常重要的因素影响redis的吞吐量,那就是网络
      • 多次网络请求对性能影响比较大
      • 所以我们需要一种机制能够编写一些具有业务逻辑的命令
        • 减少网络请求

Lua

  • Redis中内嵌了对Lua环境的支持,
    • 允许开发者使用Lua语言编写脚本传到Redis中执行,
    • Redis客户端可以使用Lua脚本,直接在服务端原子的执行多个Redis命令
  • 使用脚本的好处:
    • 减少网络开销,
      • 在Lua脚本中可以把多个命令放在同一个脚本中运行
    • 原子操作
      • redis会将整个脚本作为一个整体执行,中间不会被其他命令插入
      • 编写脚本的过程中无需担心会出现竞态条件
    • 复用性,客户端发送的脚本会永远存储在redis中,
      • 这意味着其他客户端可以复用这一脚本来完成同样的逻辑

Lua是一个高效的轻量级脚本语言

  • 用标准C语言编写并以源代码形式开放,
  • 其设计目的是为了嵌入应用程序中,
  • 从而为应用程序提供灵活的扩展和定制功能;

Redis与Lua

  • 在Lua脚本中调用Redis命令
    • 以使用redis.call函数调用
      • redis.call(‘set’,’hello’,’world’)
        local value=redis.call(‘get’,’hello’)
      • redis.call 函数的返回值就是redis命令的执行结
      • redis.call函数会将这5种类型的返回值转化对应的Lua的数据类型

从Lua脚本中获得返回值

  • 我们可以像调用其他redis内置命令一样调用我们自己写的脚本,
    • 所以同样redis会自动将脚本返回值的Lua数据类型转化为Redis的返回值类型。
    • 在脚本中可以使用return 语句将值返回给redis客户端,
      • 通过return语句来执行,如果没有执行return,默认返回为nil

EVAL命令的格式是

  • [EVAL][脚本内容] [key参数的数量][key …] [arg …]
    • lua脚本的内容为: return redis.call(‘set’,KEYS[1],ARGV[1]) //KEYS和ARGV必须大写
      • eval "return redis.call('set',KEYS[1],ARGV[1])" 1 lua1 hello
    • 如果没有参数则为0
      • 729e0d9e65c748a7e2b7be31948f288b870.jpg

EVALSHA命令

  • 脚本比较长的情况下,
    • 每次调用脚本都需要把整个脚本传给redis,比较占用带宽。
  • 为了解决这个问题,redis提供了EVALSHA命令
    • 允许开发者通过脚本内容的SHA1摘要来执行脚本。
  • Redis在执行EVAL命令时
    • 计算脚本的SHA1摘要并记录在脚本缓存中
  • 执行EVALSHA命令时
    • Redis会根据提供的摘要从脚本缓存中查找对应的脚本内容,
    • 如果找到了就执行脚本,
    • 否则返回“NOSCRIPT No matching script,Please use EVAL”

转载于:https://my.oschina.net/u/3847203/blog/3023066

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值