zoukankan      html  css  js  c++  java
  • Redis事务与Lua

    为了保证多条命令组合的原子性, Redis提供了简单的事务功能以及集成Lua脚本来解决这个问题。

    事务
    事务表示一组动作, 要么全部执行, 要么全部不执行。

    Redis提供了简单的事务功能, 将一组需要一起执行的命令放到multi和exec两个命令之间。 
    multi命令代表事务开始, exec命令代表事务结束,它们之间的命令是原子顺序执行的。
    如果要停止事务的执行, 可以使用discard命令代替exec命令即可。

    如果事务中的命令出现错误, Redis的处理机制也不尽相同:

    命令错误
    该种类型属于语法错误, 会造成整个事务无法执行, key和value的值未发生变化。
    
    运行时错误
    如命令写错了,误把sadd写为zadd,该种类型会执行成功,且不支持回滚。需要开发人员自己进行修复

    有些应用场景需要在事务之前, 确保事务中的key没有被其他客户端修改过, 才执行事务, 否则不执行(类似乐观锁) 。 Redis提供了watch命令来解决这类问题(multi命令之前执行)。


    Redis提供了简单的事务, 之所以说它简单, 主要是因为它不支持事务中的回滚特性, 同时无法实现命令之间的逻辑关系计算, 当然也体现了Redis的“keep it simple”的特性。

    在Redis中使用Lua
    在Redis中执行Lua脚本有两种方法: eval和evalsha。
    eval

    用法:eval 脚本内容 key个数 key列表 参数列表
    示例:
    > eval 'return "hello " .. KEYS[1] .. ARGV[1]' 1 redis world
    > "hello redisworld"
    此时KEYS[1]="redis", ARGV[1]="world", 所以最终的返回结果是"hello redisworld"。
    
    如果Lua脚本较长, 还可以使用redis-cli--eval直接执行文件。

    eval命令执行Lua脚本过程

    evalsha
    除了使用eval, Redis还提供了evalsha命令来执行Lua脚本。 首先要将Lua脚本加载到Redis服务端, 得到该脚本的SHA1校验和,evalsha命令使用SHA1作为参数可以直接执行对应Lua脚本, 避免每次发送Lua脚本的开销。 这样客户端就不需要每次执行脚本内容, 而脚本也会常驻在服务端, 脚本功能得到了复用。

    用法:

    加载脚本: script load命令可以将脚本内容加载到Redis内存中,得到SHA1。
    示例:
    # redis-cli script load "$(cat lua_get.lua)"
    "7413dc2440db1fea7c0a0bde841fa68eefaf149c"
    
    执行脚本: evalsha的使用方法如下, 参数使用SHA1值, 执行逻辑和eval一致。
    用法:evalsha 脚本SHA1值 key个数 key列表 参数列表
    示例:
    # evalsha 7413dc2440db1fea7c0a0bde841fa68eefaf149c 1 redis world
    "hello redisworld"

    使用evalsha执行Lua脚本过程

    Lua脚本功能为Redis开发和运维人员带来如下三个好处:

    ·Lua脚本在Redis中是原子执行的, 执行过程中间不会插入其他命令。
    ·Lua脚本可以帮助开发和运维人员创造出自己定制的命令, 并可以将这些命令常驻在Redis内存中, 实现复用的效果。
    ·Lua脚本可以将多条命令一次性打包, 有效地减少网络开销。

    Redis管理Lua脚本相关命令

    script load script 此命令用于将Lua脚本加载到Redis内存中。
    script exists 判断sha1是否已经加载到Redis内存中。
    script flush 清除Redis内存已经加载的所有Lua脚本。
    script kill 杀掉正在执行的Lua脚本。如果Lua脚本比较耗时, 甚至Lua脚本存在问题, 那么此时Lua脚本的执行会阻塞Redis, 直到脚本执行完毕或者外部进行干预将其结束。 (如果当前Lua脚本正在执行写操作, 那么script
    kill将不会生效)

    Redis Lua相关参数

    lua-time-limit 默认5s,当Lua脚本时间超过lua-time-limit后, 向其他命令调用发送BUSY的信号, 但是并不会停止掉服务端和客户端的脚本执行, 
    所以当达到lua-time-limit值之后, 其他客户端在执行正常的命令时, 将会收到“Busy Redis is busy running a script”错误, 并且提示使用script kill或者shutdown nosave命令来杀掉这个busy的脚本
  • 相关阅读:
    背水一战 Windows 10 (61)
    背水一战 Windows 10 (60)
    背水一战 Windows 10 (59)
    背水一战 Windows 10 (58)
    背水一战 Windows 10 (57)
    背水一战 Windows 10 (56)
    背水一战 Windows 10 (55)
    背水一战 Windows 10 (54)
    背水一战 Windows 10 (53)
    背水一战 Windows 10 (52)
  • 原文地址:https://www.cnblogs.com/MacoLee/p/13986139.html
Copyright © 2011-2022 走看看