web-dev-qa-db-ja.com

残りのTTLに影響を与えずにredis値を更新するにはどうすればよいですか?

既存のttlを削除せずにキーをSET redisすることは可能ですか?現時点で私が知っている唯一の方法は、TTLを見つけてSETEXを実行することですが、正確性は低くなります。

15
paulkon

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」

12
fgasparini

INCRINCRBYDECRなどが役立つ場合があります。彼らはTTLを変更しません。

> setex test 3600 13
OK

> incr test
(integer) 14

> ttl test
(integer) 3554

http://redis.io/commands/INCR

6

[〜#〜] setbit [〜#〜]を使用して新しい値に応じて値ビットを1つずつ変更することで、キーにTTLのキーに影響を与えずに値を変更できます

ただし、この方法の欠点は、特に値が非常に大きい場合は、明らかにパフォーマンスに影響することです。

[〜#〜]注[〜#〜]:これをトランザクション(マルチexec)ブロックで実行することをお勧めします

TTLを自分で保守する

  • 現在のTTLを取得しています
  • 新しい値を設定
  • 復元TTL値を設定した後

    実行されるコマンドの持続性が不明であるため、明らかに推奨されません。

別の方法は、データ型としてリストを使用し、 [〜#〜] lpush [〜#〜] を使用してリストに新しい値を追加した後、使用 [〜#〜] ltrim [〜# 〜] リストのサイズを単一の要素に維持します。これはキーのTTLを変更しません。

1
Jaric85

これは、既存の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);
        });
      };
0
bruce