既存のttlを削除せずにキーをSET
redisすることは可能ですか?現時点で私が知っている唯一の方法は、TTLを見つけてSETEX
を実行することですが、正確性は低くなります。
Redis documentation によると、キーが上書きされるため、SET
コマンドはTTLを削除します。
ただし、EVAL
コマンドを使用してLuaスクリプトを評価し、自動的に実行することができます。
以下のスクリプトは、キーのTTL=値を確認します。値が正の場合、新しい値でSETEX
を呼び出し、残りのTTLを使用します。
ローカルttl = redis.call( 'ttl'、ARGV [1])ttl> 0の場合、redis.call( 'SETEX'、ARGV [1]、ttl、ARGV [2])を返しますend
例:
>キー123を設定
OK
>有効期限キー120
(整数)1
...数秒後
> ttlキー
(整数)97
> eval "ローカルttl = redis.call( 'ttl'、ARGV [1])ttl> 0の場合、redis.call( 'SETEX'、ARGV [1]、ttl、ARGV [2])end" 0キー987
OK
> ttlキー
96
>キーを取得
「987」
INCR
、INCRBY
、DECR
などが役立つ場合があります。彼らはTTLを変更しません。
> setex test 3600 13
OK
> incr test
(integer) 14
> ttl test
(integer) 3554
[〜#〜] setbit [〜#〜]を使用して新しい値に応じて値ビットを1つずつ変更することで、キーにTTLのキーに影響を与えずに値を変更できます 。
ただし、この方法の欠点は、特に値が非常に大きい場合は、明らかにパフォーマンスに影響することです。
[〜#〜]注[〜#〜]:これをトランザクション(マルチexec)ブロックで実行することをお勧めします
TTLを自分で保守する
復元TTL値を設定した後
実行されるコマンドの持続性が不明であるため、明らかに推奨されません。
別の方法は、データ型としてリストを使用し、 [〜#〜] lpush [〜#〜] を使用してリストに新しい値を追加した後、使用 [〜#〜] ltrim [〜# 〜] リストのサイズを単一の要素に維持します。これはキーのTTLを変更しません。
これは、既存のTTLをチェックし、必要に応じて使用するための関数です。
有効期限引数0-既存の有効期限を使用、> 0-新しい有効期限を設定、未定義-有効期限なし。
/**
* update an item. preserve ttl or set a new one
* @param {object} handle the redis handle
* @param {string} key the key
* @param {*} content the content - if an object it'll get stringified
* @param {number||null} expire if a number > 0 its an expire time, 0
means keep existing ttl, undefined means no expiry
* @return {Promise}
*/
ns.updateItem = function (handle , key , content,expire) {
// first we have to get the expiry time if needed
return (expire === 0 ? handle.ttl(key) : Promise.resolve (expire))
.then (function (e) {
// deal with errors retrieving the ttl (-1 no expiry, -2 no existing record)
var ttl = e > 0 ? e : undefined;
// stingify the data if needed
var data = typeof content === "object" ? JSON.stringify(content) : content;
// set and apply ttl if needed
return ttl ? handle.set (key, data , "EX", ttl) : handle.set (key,data);
});
};