V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ryalu
V2EX  ›  Redis

求教大佬,线上 redis cluster 中适合使用 redis lua script 吗?以及使用时有什么注意事项?

  •  
  •   ryalu · 2023-07-18 12:02:30 +08:00 · 1039 次点击
    这是一个创建于 499 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我将一部分逻辑代码通过 lua 脚本实现,变相的实现原子操作(如下),但之前使用 lua 脚本是遇到过 not in the same slot 的错误,感觉我的这个脚本可能与会遇到。如果我真的通过 key 加前缀的方式保证他们在同一个 slot 内是不是也会导致 cluster 处于一个不健康的集群状态。

    local userAttributionKey = KEYS[1];
    local humeSource = KEYS[2];
    local attributeKeys = cjson.decode(KEYS[3]);
    
    if redis.call("EXISTS", userAttributionKey) == 1 then
        -- get attribution cache
        local res = redis.call("GET", userAttributionKey);
        if res then
            return { 1, res };
        end
    end
    
    local matchResult = {};
    local hits = {};
    local latestTime = 0;
    for i = 1, #attributeKeys do
        local indexInfoString = redis.call("GET", attributeKeys[i]);
        if indexInfoString then
            local indexInfo = cjson.decode(indexInfoString);
            local reportSource = indexInfo['report_source'];
            local uniqId = indexInfo['uniq_id'];
            local timestamp = tonumber(indexInfo['timestamp']);
    
            if humeSource == '' or humeSource == indexInfo['report_source'] then
                -- check attribute index info
                if reportSource ~= '' and uniqId ~= '' then
                    if timestamp > latestTime then
                        indexInfo['hit'] = attributeKeys[i];
                        indexInfo['match_res'] = 'matched';
                        matchResult = indexInfo;
                        latestTime = timestamp;
                    end
    
                    table.insert(hits, attributeKeys[i]);
                else
                    return redis.error_reply("Invalid Info:" .. indexInfoString);
                end
            end
    
            -- delete attribute key cache
            redis.call("DEL", attributeKeys[i])
        end
    end
    
    if #hits > 0 then
        matchResult['hits'] = hits;
        local matchResultStr = cjson.encode(matchResult);
    
        -- set attribution cache
        redis.call("SET", userAttributionKey, matchResultStr, "EX", ARGV[1]);
        return { 1, matchResultStr };
    end
    
    return { 0, cjson.encode(matchResult) };
    

    请教下大佬和前辈,我这是不是一种错误的使用方式?以及 lua script 使用时有什么注意事项?

    guyeu
        1
    guyeu  
       2023-07-19 14:02:46 +08:00
    加 key 能保证在同一个 slot 吗?
    guyeu
        2
    guyeu  
       2023-07-19 14:03:01 +08:00
    key 加前缀
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1267 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 23:21 · PVG 07:21 · LAX 15:21 · JFK 18:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.