Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Lua 从Redis集中筛选/删除项目_Lua_Redis - Fatal编程技术网

Lua 从Redis集中筛选/删除项目

Lua 从Redis集中筛选/删除项目,lua,redis,Lua,Redis,我在一个Redis集合中缓存公交车站到达时间和路线ID,每个公交车站一个集合。我正在寻找一种简单的方法来更新这些集合,删除过去的到达时间,同时保留将来的任何其他到达时间。如何在写入时根据特定条件筛选集合 一段时间内未写入的集合将过期,因此我只关心不断更新的集合,本质上是在元素级别而不是集合级别设置过期。以下内容将筛选出小于键[2]的值。(在我的例子中是UNIX时间戳,因为Redis中的LUA脚本无法访问日期/时间信息,所以就这样传递了)。然后,第二个子句添加传递给脚本的任何附加值 local m

我在一个Redis集合中缓存公交车站到达时间和路线ID,每个公交车站一个集合。我正在寻找一种简单的方法来更新这些集合,删除过去的到达时间,同时保留将来的任何其他到达时间。如何在写入时根据特定条件筛选集合


一段时间内未写入的集合将过期,因此我只关心不断更新的集合,本质上是在元素级别而不是集合级别设置过期。

以下内容将筛选出小于
键[2]的值。
(在我的例子中是UNIX时间戳,因为Redis中的LUA脚本无法访问日期/时间信息,所以就这样传递了)。然后,第二个子句添加传递给脚本的任何附加值

local members_expired = 0 -- number of members expired/removed
local additions_attempted = 0 -- number of SADD attempts
local members_added = 0 -- number of members successfully added
local key = KEYS[1] -- the key of the set to update
local current_time = KEYS[2] -- the current timestamp

-- iterate through existing members and "expire" (remove) any members
-- less than the current time
for index, value in next, redis.call('SMEMBERS', key) do
    -- interpret the first 10 characters of the member as a timestamp,
    -- allowing us to include additional data such as the route ID
    if string.sub(value, 1, 10) < current_time then
        redis.call('SREM', key, value);
        members_expired = members_expired + 1
    end
end

-- iterate through provided members and attempt to insert them into the
-- target set
for index, value in next, ARGV do
    additions_attempted = additions_attempted + 1
    members_added = members_added + redis.call('SADD', key, value)
end

-- number of duplicate members
local duplicates_ignored = additions_attempted - members_added

-- entire set will expire in 1 week unless it's updated in the meantime
redis.call('EXPIRE', key, 604800)

return {
    members_added,
    members_expired,
    duplicates_ignored
}
和的参数为:

  • 脚本或SHA1散列
  • 始终为“2”(传递给
    键的参数数
    LUA变量-请参阅)
  • 键[1]
    要读取/修改的键
  • 键[2]
    当前UNIX时间戳
  • (及以上)
    要添加到集合中的任何新值
  • $predis = new Predis\Client();
    $time = time();
    
    // some time in the future to add to the set
    $values = [
        ($time + 3600) . ':route_123',
        ($time + 7200) . ':route_123',
        ($time + 7200) . ':route_456',
        ($time + 7200) . ':route_456', // this is a duplicate
    ];
    
    $filter_script = <<<LUA
    local members_expired = 0 -- number of members expired/removed
    local additions_attempted = 0 -- number of SADD attempts
    local members_added = 0 -- number of members successfully added
    local key = KEYS[1] -- the key of the set to update
    local current_time = KEYS[2] -- the current timestamp
    
    -- iterate through existing members and "expire" (remove) any members
    -- less than the current time
    for index, value in next, redis.call('SMEMBERS', key) do
        -- interpret the first 10 characters of the member as a timestamp,
        -- allowing us to include additional data such as the route ID
        if string.sub(value, 1, 10) < current_time then
            redis.call('SREM', key, value);
            members_expired = members_expired + 1
        end
    end
    
    -- iterate through provided members and attempt to insert them into the
    -- target set
    for index, value in next, ARGV do
        additions_attempted = additions_attempted + 1
        members_added = members_added + redis.call('SADD', key, value)
    end
    
    -- number of duplicate members
    local duplicates_ignored = additions_attempted - members_added
    
    -- entire set will expire in 1 week unless it's updated in the meantime
    redis.call('EXPIRE', key, 604800)
    
    return {
        members_added,
        members_expired,
        duplicates_ignored
    }
    LUA;
    
    // We can run the script directly...
    list($members_added, $members_expired, $duplicates_ignored) = $predis->eval(
        $filter_script,
        2,
        'somekey',
        $time,
        $values[0],
        $values[1],
        $values[2],
        $values[3]
    );
    
    echo "Members added: $members_added\n";
    echo "Members expired: $members_expired\n";
    echo "Duplicate members ignored: $duplicates_ignored\n";
    echo "\n";
    
    // or save it for faster execution if we're going to run repeatedly
    $members_added_total = 0;
    $members_expired_total = 0;
    $duplicates_ignored_total = 0;
    $filter_script_sha = $predis->script('LOAD', $filter_script);
    
    foreach ($values as $value) {
        list($members_added, $members_expired, $duplicates_ignored) =
            $predis->evalsha($filter_script_sha, 2, 'somekey', $time, $value);
    
        echo "[$members_added, $members_expired, $duplicates_ignored]\n";
    
        $members_added_total += $members_added;
        $members_expired_total += $members_expired;
        $duplicates_ignored_total += $duplicates_ignored;
    }
    
    echo "Members added: $members_added_total\n";
    echo "Members expired: $members_expired_total\n";
    echo "Duplicate members ignored: $duplicates_ignored_total\n";