redis 教程 6(Redis 的Pipeline , Lua)

Pipeline

Pipeline简介

Pipeline(流水线) 能够将一组redis命令进行组装, 通过一次RTT(Round Trip Time) 传输给redis, 然后再将这组命令的执行结果按照顺序返回给redis客户端

为什么需要Pipeline

下图为redis 客户端对redis的n次请求过程
在这里插入图片描述

注意: redis客户端执行一次命令分为四个步骤,

  • 发送命令
  • 命令排队
  • 命令执行
  • 返回结果
    整个过程称之为Round Trip Time (RTT, 往返时间), 那在redis的所有操作命令里面, 提供了很多批量的操作, 能够有效的节省RTT 时间, 但是像hgetall, 没有批量命令, 如果要执行n次的话, 那就跟上图一样, 会有n次的RTT消耗, 这个时候Pipeline就刚好改善了这个问题。

在这里插入图片描述

注意: 上图这个过程就是使用PIpeline针对redis客户端多次命令发送的优化过程,极大的减少了RTT。

Pipeline 性能测试

对于Pipeline是能够改善RTT, 但是性能到底如何, 我们来分析下, 假设我们有10000次set命令需要执行, 分别在没有Pipeline的情况下, 在有Pipeline的情况下, 对比使用的时间。

注意: 下表是在10000条set命令, 不通的网络情况下, 在不使用Pipeline, 和使用Pipeline的情况所耗时间, 从表可以很直观的看出, Pipeline的性能很强

网络延迟非PipelinePipeline
本级0.17ms573ms134ms
内网服务器0.41ms1610ms240ms
异地机房7ms78499ms1104ms

与原生批量命令对比

Pipeline 的性能我们已经能够清楚, 那对于批量的redis命令有什么优缺点呢?

  1. 原生的批量命令是原子的, Pipeline是非原子的
  2. 原生批量命令是一个命令多个key, Pipeline是两次(来回)网络传输, 对应多个命令, 多个key
  3. 原生批量命令是redis服务端支持实现的, 而Pipeline需要服务端, 客户端共同配合实现。

注意: Pipeline的使用也要建立在调试的结果上, 不能一味的组装命令,

Lua

Pipeline可以组装多个redis命令, 但是是非原子性的, 是不安全的, 那如果即想组装命令, 又可以做到原子性呢? 这个时候Lua就出现了。
Lua 就是能够保证多条命令组合的原子性

Lua 与事物

Lua 保证了多条命令的组合是原子性的
事物, 即一批操作要么都执行成功, 要么都执行失败, 保证数据的一致性
redis 提供了multi 和exec 两个命令的组合, 在这两个命令之间的一组redis命令按照原子顺序执行, multi代表食物的开始, exec代表食物的结束。

multi
sadd user:a:follow  user:b
sadd user:b:fans user:a
// 这时命令并没有真整执行, 知识保存在redis里面
// 此时如果执行
sismember user:a:follow user:b 返回0
exec
返回1
再执行 sismember user:a:follow user:b 返回1

Lua 的用法

  1. eval

eval 脚本内容 key 个数 key 列表 参数列表

redis 127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 key3 key4
1) "key1"
2) "key2"
3) "key3"
4) "key4"

在这里插入图片描述

  1. evalsha

evalsha 脚本 SHA1 值 key个数 key列表 参数列表
sha1 : 通过 SCRIPT LOAD 生成的 sha1 校验码。
numkeys: 用于指定键名参数的个数。
key [key …]: 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。
arg [arg …]: 附加参数,在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)。

redis 127.0.0.1:6379> SCRIPT LOAD "return 'hello moto'"
"232fd51614574cf0867b83d384a5e898cfd24e5a"

redis 127.0.0.1:6379> EVALSHA "232fd51614574cf0867b83d384a5e898cfd24e5a" 0
"hello moto"

在这里插入图片描述

  1. lua 的Redis Api

Lua 可以使用redis.call函数实现对Redis 的访问
redis.call(“set”, “hello”, “world”)
redis.call(“get”, “hello”)
在redis 的执行效果如下:

redis 127.0.0.1:6379> eval 'return redis.call("get", KEY[1])'  1 hello
"word"

Lua 还可以使用redis.pcall 函数实现对redis的调用, redis.call执行失败,脚本执行结束回返回错误, redis.pcall 会忽略错误继续执行。

Lua 可以用redis.log函数将Lua脚本的日志输出到redis 的日志文件中, 需要控制日志级别。

Redis 如何管理Lua脚本

  1. script load

script load 是将Lua脚本加载到Redis 内存中

  1. script exists

script exists sha1 {sha1 …}
判断sha1 是否已经加载到redis 内存中

  1. script flush

script flush
次命令用于清除Redis内存已经加载的所有Lua脚本

  1. script kill

script kill
杀掉正在执行的Lua脚本, 杀掉一些一直阻塞的lua脚本

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值