1
我在Redis集中緩存公交車站到達時間和路由ID,每個公交車站一組。我正在尋找一種簡單的方法來更新這些設置,消除過去的到達時間,同時保留其他未來的到達時間。如何在寫入時根據特定標準過濾一組?從Redis集中過濾/刪除項目
一段時間以來一直未寫入的集合將過期,因此我只關注不斷更新的集合,實質上是在元素級別而不是集合級別設置到期。
我在Redis集中緩存公交車站到達時間和路由ID,每個公交車站一組。我正在尋找一種簡單的方法來更新這些設置,消除過去的到達時間,同時保留其他未來的到達時間。如何在寫入時根據特定標準過濾一組?從Redis集中過濾/刪除項目
一段時間以來一直未寫入的集合將過期,因此我只關注不斷更新的集合,實質上是在元素級別而不是集合級別設置到期。
以下內容將過濾掉小於KEYS[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
}
腳本採用以下參數:
[timestamp]:[extra_data]
值,例如1474904925:route_123
它返回具有以下值的數組:
PHP示例(使用Predis):
$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";
KEYS
LUA變量 - 請參閱docs)KEYS[1]
讀取密鑰/修改KEYS[2]
當前UNIX時間戳VALUES
任何新值添加到集合