我将一部分逻辑代码通过 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 使用时有什么注意事项?