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的脚本
  • 相关阅读:
    [C#]画图全攻略(饼图与柱状图)(转)
    ZedGraph控件的使用
    android PopupWindow实现从底部弹出或滑出选择菜单或窗口
    那两年炼就的Android内功修养
    android添加edittext后布局就不好用
    第三方应用分享到微信朋友圈功能
    android的微信签名
    Android开源库
    Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面
    android 显示特殊符号
  • 原文地址:https://www.cnblogs.com/MacoLee/p/13986139.html
Copyright © 2011-2022 走看看