web-dev-qa-db-ja.com

Redisのキーに有効期限はありません-Laravel、Predis

私は Laravel 5.4Predis および最新の Redis (または Redis for Windows )を使用しています。

キーは問題なく保存されています。だから、私はそれが設定の問題だとは思いません。

問題は、有効期限が切れていないことです。 キーは期限切れになるまで再利用されます...セッションがどのように機能するかと同様です

キーが存在しない場合は、一度作成します。同じロジックで、有効期限を設定します。

コントローラには、私が持っています

use Illuminate\Support\Facades\Redis;

関数の1つで、接続インスタンスを取得します

$redis = Redis::connection();

キーを作成する前に、存在を確認し(簡略化)、有効期限を作成して設定します。

if(!$redis->exists($some_unique_key))
{
   //set the key
   $redis->set($some_unique_key, 'Some Value'));
   //set the expiration
   //I understand this means expire in 60s.
   $redis->expire($some_unique_key,60); 
}

鍵の有効期限が切れないのはなぜですか?

私が述べたように、他のすべてが機能します。監視すると、キーの更新は問題なく表示され、クエリを実行できます。

記録のために、私は読んだ:

Laravelのドキュメントに有効期限はありません:

更新1

キーを設定(更新)して有効期限をリセットする可能性のある原因を調査する

更新2

(REDISコマンドで)@for_thestackの推論を使用して、ソリューションを考え出しました。コードで私の答えを見てください。 @for_thestackに自由に賛成投票してください:)

10
user919426

他のいくつかのプロセスがSETを呼び出してキーと値のペアを更新する場合があります。この場合、有効期限は削除されます。

// set expiration
EXPIRE key expiration_in_seconds
// update key-value pair with no expiration
SET key new_value
// now, expiration has been reset, and the key won't be expired any more

有効期限を維持するには、Key-Valueペアを更新するときに、有効期限パラメーターを指定してSETを呼び出す必要があります。

// get TTL, i.e. how much time left before the key will be expired
TTL key
// update with expiration parameter
SET key new_value EX ttl

2つのコマンドをluaスクリプトにラップして、アトミックにすることができます。また、TTLを呼び出すときにキーが存在しない場合にも注意する必要があります。詳細については、ドキュメントを参照してください。

6
for_stack

Laravelを使用するユーザーは、EX param(expire resolution)+ ttlを使用できます。

Redis::set($key, $val, 'EX', 35);

Predisでは同じことを使用できますが、実際にはLaravelは内部でpredisを使用します。

9
Arthur Kushman

@for_stackがロジック(REDISコマンドとロジック)を提供してくれたので、彼の貢献を答えとして受け入れました。

私の問題は、キーがsetであることを知らなかったことで、有効期限がリセットされました。したがって、@ for_stackで説明されているように機能させるには、

  1. キーが存在する場合はTTLを取得
  2. キーを更新した後、有効期限を(1)から取得したTTLに設定します

つまり、全体のTTLは正確ではありません。 (1)でTTL値を取得してから更新するまでに、ミリ秒またはマイクロ秒のマージンがあります。これは私には問題ありません。

Laravel(PHP)のPredisシナリオでは、次のようにします。

いくつかの関連するポイントで、コードの上位:

//get ttl - time left before expiry
$ttl = $redis->ttl($some_unique_key);

次に、値を更新する必要がある場合は常に、値を設定した後に有効期限を設定します。 (私の質問では)キーを作成するためのロジックは正しいままで変更されていません。

//***note that I am UPDATING a key. Checking if it exists then I update
if($redis->exists($some_unique_key))
{
   //set/up the key
   $redis->set($some_unique_key, 'Some New, Updated, Value'));

   //Do some work   

   //set the expiration with the TTL value from (1)
   $redis->expire($some_unique_key,$ttl); 
}

完璧に動作します!

4
user919426