• (九)redis使用lua脚本


    Redis 脚本使用 Lua 解释器来执行脚本。 Redis 2.6 版本通过内嵌支持 Lua 环境。执行脚本的常用命令为 EVAL。
    时间复杂度:取决于执行的脚本。

    使用Lua脚本的好处:

    • 减少网络开销。可以将多个请求通过脚本的形式一次发送,减少网络时延。
    • 原子操作。redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。因此在编写脚本的过程中无需担心会出现竞态条件,无需使用事务。
    • 复用。客户端发送的脚本会永久存在redis中,这样,其他客户端可以复用这一脚本而不需要使用代码完成相同的逻辑。

    语法

    redis 127.0.0.1:6379> EVAL script numkeys key [key ...] arg [arg ...]
    
    • script: 参数是一段 Lua 5.1 脚本程序。脚本不必(也不应该)定义为一个 Lua 函数。
    • numkeys: 用于指定键名参数的个数。
    • key [key ...]: 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。
    • arg [arg ...]: 附加参数,在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)。

    示例:

    127.0.0.1:6379> eval "return ARGV[1]" 0 100 
    "100"
    127.0.0.1:6379> eval "return {ARGV[1],ARGV[2]}" 0 100 101
    1) "100"
    2) "101"
    
    127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
    1) "key1"
    2) "key2"
    3) "first"
    4) "second"
    
    127.0.0.1:6379> eval "redis.call('SET', KEYS[1], ARGV[1]);redis.call('EXPIRE', KEYS[1], ARGV[2]); return 1;" 1 test 10 60
    (integer) 1
    127.0.0.1:6379> ttl test
    (integer) 59
    127.0.0.1:6379> get test
    "10"
    
    • {}在lua里是指数据类型table,类似数组。
    • redis.call()可以调用redis命令。

    命令行里使用

    如果直接使用redis-cli命令,格式会有点不一样:

    redis-cli --eval lua_file.lua key1 key2 , arg1 arg2 arg3
    
    • eval 后面参数是lua脚本文件,.lua后缀。
    • 不用写numkeys,而是使用,隔开。注意,前后有空格。

    示例:
    incrbymul.lua

    local num = redis.call('GET', KEYS[1]);  
    
    if not num then
    	return 0;
    else
    	local res = num * ARGV[1]; 
    	redis.call('SET',KEYS[1], res); 
    	return res;
    end
    

    命令行运行:

    $ redis-cli --eval incrbymul.lua lua:incrbymul , 8
    (integer) 0
    $ redis-cli incr lua:incrbymul 
    (integer) 1
    $ redis-cli --eval incrbymul.lua lua:incrbymul , 8
    (integer) 8
    $ redis-cli --eval incrbymul.lua lua:incrbymul , 8
    (integer) 64
    $ redis-cli --eval incrbymul.lua lua:incrbymul , 2
    (integer) 128
    

    由于redis没有提供命令可以实现将一个数原子性的乘以N倍,这里我们就用Lua脚本实现了,运行过程中确保不会被其它客户端打断。

    使用jedis执行lua脚本

        String script = "return { KEYS[1],KEYS[2],ARGV[1],ARGV[2],ARGV[3] }";  
    
        List<String> keys = new ArrayList<String>();  
        keys.add("key1");  
        keys.add("key2");
    
        List<String> args = new ArrayList<String>();  
        args.add("first");  
        args.add("second");  
        args.add("third"); 
    
        List<String> response = (List<String>) jedis.eval(script, keys, args); 
    
    
  • 相关阅读:
    jQuery给动态添加的元素绑定事件的方法
    无法加载父级样式或设置IIS的asp站点启用父路径
    ASP.NET MVC 必须设置 ErrorMessageString 或 ErrorMessageResourceName,但不能同时设置二者。
    layer弹窗监控键盘事件
    js 刷新windows.open另一个窗口页面或window.open的页面如何刷新(父页面)上层页面
    jquery提交表单,回调函数
    iis Server Error in '/' Application
    jni&&jvmti&&JMC
    Backpropagation
    k-means-algorithm
  • 原文地址:https://www.cnblogs.com/everyingo/p/13062182.html
Copyright © 2020-2023  润新知