Key-Valueストレージのアイテムを期限切れにするアルゴリズムは何ですか?


10

現在のKey-Valueストレージがアイテムの「有効期限」を実装する方法について考えていました。現在、私は私の心の中に2つのバリアントを持っています:

  1. それらは何もしません(期限切れのデータを保持します)。たとえば、何らかのキーでGETした場合にのみチェックします。ここでの問題は、メモリが限られている場合、期限切れのアイテムが削除されないことです。
  2. それらは、「期限切れが最も早い」ことを可能にするために追加のデータ構造を保持します。私はそれがこのようなものでできることがわかります:

    storage_data = dict(key -> [value, expire_timestamp])
    expire_tree = SomeBinaryLikeTree(expire_timestamp -> [keys])
    

回答:


6

キャッシュ内の期限切れのエントリを削除する問題は、ガベージコレクションとほぼ同じですが、参照カウントの複雑さ全体を差し引いたものです。

Nasza-Klasaの人々は、MemcacheのO(1)アルゴリズムを次のように提案しています。

何らかの理由で、期限切れのエントリを解放することはO(1)では実行できない、あるいはOmega(N)操作が必要であるとさえ信じているようです。ヒープまたは他の優先キューデータ構造を使用すると、明らかにO(log N)が得られますが、以下のパッチはO(1)を目的としています。これは、毎秒1つのバケットを持ち、有効期限を確認して各エントリを適切なバケットに配置することで実現されます。その後、毎秒、次のバケットから要素を解放します。これは明らかにO(1)の償却時間ですが、同時に期限が切れる要素が多数ある場合があるため、このパッチでは、1つのリクエストで実行する操作の数に一定の制限があります。ガベージコレクションの実行をスムーズにするため。

コードが添付された提案全体をご覧ください。


ありがとう。また、「バケット」ソリューションを1つの方法として考えました。また、「最後に取らなかったバケットを取り、完了したら元に戻す」アルゴリズムを使用できるため、「バケット内のアイテムが多すぎても」問題はありません。
Kostiantyn Rybnikov 2012年

@k_bx:そのため、二重リンクリストが提案されるので、以前のバケットに戻ることができます。
vartec 2012年

バケットが秒のようなものであれば、リンクリストはまったく必要ありません。前に進むには、キーを減らすだけです:)
Kostiantyn Rybnikov

@k_bx:キーをどれだけ減らしますか?一秒?以前の完全に空にされていないバケットが5分前である場合はどうなりますか?1秒ずつ300回減る?
vartec 2012年

サーバーの最初の起動時に、current_expire_bucketという変数を何らかの値に初期化します。次に、current_expire_bucketからクリーンアップを実行し、現在の秒で終了します。クリーンアップが終了したら、少しの間寝ます。サーバーが停止した場合、同じ「期限切れバケット」を再び通過しますが、サーバーの停止時にのみ発生します。
Kostiantyn Rybnikov 2012年

7

Key-Valueストレージが大きすぎて、すべてのkvペアを繰り返し処理して、期限切れになる可能性のあるものを見つけることができないと思います。また、各読み取りアクセスで有効期限のタイムスタンプが更新されるため、一定期間アクセスされなかったアイテムのみが期限切れになると想定しています。

課題は、有効期限が切れる可能性のあるすべてのレコードを効率的に見つけることです(クリーンアップの期限が来るたびに)。また、すべての読み取りアクセスで有効期限のタイムスタンプを効率的に更新します(したがって、有効期限に使用される構造でキーを見つける必要があります)。

私の提案:expiry_timestampsをバケットにグループ化します。たとえば、アイテムが8時間存続する場合は、1時間に1つのバケットを作成します。それらのバケットはリンクされたリストに保持されます。期限切れになると、最初のバケットが空になり、リストが減ります。バケットの数は、寿命/クリーンアップ間隔です。各バケットには、期限切れにする必要のあるすべてのキーのhashSetが含まれています。ハッシュセット内のすべてのキーの反復は十分に効率的です。

読み取りアクセス中に、プログラムは、キーが現在どのバケットにあり、どのバケットに現在属しているのかをチェックします。ほとんどの場合、同じバケットであるため、これ以上のアクションは必要ありません。それ以外の場合は、古いバケットからキーを削除し(ハッシュセットから削除すると効率的です)、新しいバケットに挿入します。

   +--------------+   +--------------+   +--------------+
-->+ Expiry 08:00 +-->+ Expiry 09:00 +-->+ Expiry 10:00 +
   | KeySet       |   | KeySet       |   | KeySet       |
   +--------------+   +--------------+   +--------------+
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.