zoukankan      html  css  js  c++  java
  • 在redis中使用lua脚本

      在实际工作过程中,可以使用lua脚本来解决一些需要保证原子性的问题,而且lua脚本可以缓存在redis服务器上,势必会增加性能。 
    不过lua也会有很多限制,在使用的时候要注意。

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

    eval

    EVAL script numkeys key [key ...] arg [arg ...]

      其中: <1> script:你的lua脚本

           <2> numkeys:  key的个数

           <3> key:redis中各种数据结构的替代符号

           <4> arg: 你的自定义参数

       举个例子:

    eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 user age ysl 21

      第一个参数的字符串就是script,也就是lua脚本。2表示keys的个数,KEYS[1] 就是 username的占位符, KEYS[2]就是 age的占位符,ARGV[1]就是ysl的占位符,ARGV[2]就是20的占位符,,以此类推,,,所以最后的结果应该就是:{return username age ysl 20}

      通常境况下,我们不要在redis-cli中直接写lua脚本,这样非常不方便编辑,通常情况下我们都是把lua script放到一个lua文件中,然后执行这个lua脚本

      编写lua脚本test.lua,内容如下:

    return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}  

      然后我们通过下面命令执行,这种方式和前面介绍的不一样,参数 --eval script  key1 key2 , arg1 age2 这种模式,key和value用一个逗号隔开就好了,

    ./redis-cli --eval /usr/redis/sbin/test.lua username age , ysl 20

    evalsha

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

      加载脚本: script load命令可以将脚本内容加载到Redis内存中。

     redis-cli script load “$(cat lua_get.lua)” 

      执行脚本:evalsha 脚本sha1值 key个数 key列表 参数列表 

    lua的Redis API
      lua可以使用redis.call函数实现对Redis的访问
      redis.call(“set”,”hello”,”world”)
      redis.call(“get”,”hello”)

      除此之外Lua还可以使用redis.pcall函数实现对Redis的调用,redis.call和redis.pcall的不同在于,如果redis.call执行失败,那么脚本执行结束会直接返回错误,而redis.pcall会忽略错误继续执行脚本。

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

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

    Redis如何管理Lua脚本
    1.script load
    此命令用于将Lua脚本加载到Redis内存中
    2.script exists
    scripts exists sha1 [sha1 …]
    此命令用于判断sha1是否已经加载到Redis内存中
    3.script flush
    此命令用于清除Redis内存已经加载的所有Lua脚本,在执行script flush后,sha1不复存在。
    4.script kill
    此命令用于杀掉正在执行的Lua脚本。

    抢红包中Redis和Lua命令的使用:
    首先编写lua脚本
    在Java类中,String script=”“;进行拼接。
    获取底层Redis的操作对象
    Jedis jedis=(Jedis) redisTemplate.getConnectionFactory().getConnection().getNativeConnection();
    如果脚本没有加载过,那么进行加载,这样就会返回一个sha1编码

    if(sha1==null)
        sha1=jedis.scriptLoad(script);

    执行脚本,返回结果
    Object res=jedis.evalsha(sha1,1,redisPacketId +”“,args);
    根据res的值来确定是否保存到数据库。

  • 相关阅读:
    树莓派aria2 init文档
    树莓派aria2 init文档
    HDU 6000 Wash【优先队列优化贪心】【最大值+最小值】
    HDU 6000 Wash【优先队列优化贪心】【最大值+最小值】
    HDU 3264||POJ 3831 Open-air shopping malls【计算机几何】【圆相交面积模板】
    HDU 3264||POJ 3831 Open-air shopping malls【计算机几何】【圆相交面积模板】
    HDU 6178 Monkeys【dfs】【输入外挂模板】
    HDU 6178 Monkeys【dfs】【输入外挂模板】
    HDU 6181 Two Paths【次短路】【模板题】
    返回一个二维整数数组中最大子数组的和
  • 原文地址:https://www.cnblogs.com/senlinyang/p/8820572.html
Copyright © 2011-2022 走看看