易游网

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 41|回复: 0

[redis] redis运行lua脚本

[复制链接]
  • TA的每日心情
    郁闷
    7 天前
  • 签到天数: 32 天

    [LV.5]常住居民I

    108

    主题

    133

    帖子

    6

    积分

    超级版主

    Rank: 8Rank: 8

    积分
    6

    技术达人

    发表于 2021-10-13 19:29:02 | 显示全部楼层 |阅读模式
    redis.call() 和 redis.pcall()
    当 redis.call() 在执行命令的过程中发生错误时,脚本会停止执行,并返回一个脚本错误,错误的输出信息会说明错误造成的原因:
    和 redis.call() 不同, redis.pcall() 出错时并不引发(raise)错误,而是返回一个带 err 域的 Lua 表(table),用于表示错误:

    例子:
    EVAL script numkeys key [key …] arg [arg …]
    EVAL "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
    EVAL "return ARGV[1]" 0 value1
    EVAL "redis.call('SET', KEYS[1], ARGV[1]);redis.call('EXPIRE', KEYS[1], ARGV[2]); return 1;" 1 userAge 10 60


    SCRIPT LOAD script
    EVALSHA sha1 numkeys key [key …] arg [arg …]
    SCRIPT LOAD 将脚本 script 添加到Redis服务器的脚本缓存中,并不立即执行这个脚本,而是会立即对输入的脚本进行求值。并返回给定脚本的 SHA1 校验和。如果给定的脚本已经在缓存里面了,那么不执行任何操作。
    在脚本被加入到缓存之后,在任何客户端通过EVALSHA命令,可以使用脚本的 SHA1 校验和来调用这个脚本。脚本可以在缓存中保留无限长的时间,直到执行SCRIPT FLUSH为止。
    SCRIPT EXISTS sha1 [sha1 …]
    SCRIPT FLUSH
    清除Redis服务端所有 Lua 脚本缓存


    I、编写Lua脚本文件测试例子1:
    local key = KEYS[1]
    local val = redis.call("GET", key);

    if val == ARGV[1]
    then
            redis.call('SET', KEYS[1], ARGV[2])
            return 1
    else
            return 0
    end

    redis-cli -a 密码 --eval Lua脚本路径 key [key …] ,  arg [arg …]


    II、统计ip超限脚本实例测试例子2:

    local visitNum = redis.call('incr', KEYS[1])

    if visitNum == 1 then
            redis.call('expire', KEYS[1], ARGV[1])
    end

    if visitNum > tonumber(ARGV[2]) then
            return 0
    end

    return 1;



    III、领券脚本逻辑:测试例子3
    --redis keys
    local user_today_got_key = KEYS[1]; --Lua下表从1开始
    local user_got_key = KEYS[2];
    local total_got_key = KEYS[3];
    --redis args
    local user_per_day_max = tonumber(ARGV[1]);
    local user_max = tonumber(ARGV[2]);
    local max = tonumber(ARGV[3]);
    local userId = ARGV[4];
    local couponId = ARGV[5];

    -- 用户每天可领券的最大数量
    local user_today_got = redis.call("hget", user_today_got_key, userId);
    if(user_today_got and tonumber(user_today_got) >= user_per_day_max) then
        return 1; --fail
    end

    -- 用户可领券的最大数量
    local user_got = redis.call("hget",user_got_key,couponId);
    if(user_got and tonumber(user_got) >= user_max) then
        return 2; --fail
    end

    -- 券的最大数量
    local total_got = redis.call("hget",total_got_key,couponId);
    if(total_got and tonumber(total_got) >= max) then
        return 3; --fail
    end

    redis.call("hincrby",user_today_got_key, userId,1);
    redis.call("hincrby",user_got_key, couponId,1);
    redis.call("hincrby",total_got_key, couponId,1);
    return 0; -- success

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|小黑屋|易游网 Copyright @2015-2021 本站资源全部来源于网络,如有侵犯您的权益请致邮207621422@qq.com撤下. ( 浙ICP备15028007号-1 )

    GMT+8, 2021-10-27 01:44 , Processed in 1.046915 second(s), 27 queries , Gzip On.

    Powered by Discuz! X3.4 Licensed

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表