redisの期限切れ設定と期限切れ削除メカニズム

4235 ワード

一:有効期限の設定


redisには、キーの生存時間と有効期限を設定する4つのコマンドがあります.
    EXPIRE   :           ttl  
    PEXPIRE   :          ttl   
    EXPIREAT   :          timestamp          
    PEXPIREAT  :           timestamp           .

二:保存期限


ではredisの中でこれらのkeyの期限切れと生存時間の情報はどのように保存されていますか?答:データベース構造redisDbのexpires辞書には、データベース内のすべてのキーの期限切れが保存されています.expireという辞書を期限切れ辞書と呼びます.(1)期限切れ辞書は,キー空間のキーオブジェクトを指すポインタである.(2)期限切れ辞書の値は、キーが指すデータベース・キーの期限切れ時間であるミリ秒レベルのUNIXタイムスタンプを保存するlonglongタイプの整数です.
次の図は、期限切れ辞書を使用したデータベースの例です.
Paste_Image.png
期限切れ辞書はredisDbという構造に格納されています.
typedef struct redisDb {
    ...
    
    dict *dict;     //      ,            
    dict *expires      //     ,         
    ...
} redisDb;

以上の構造からexpire辞書(期限切れ辞書)とdict辞書(データベースキー空間、データベース内のすべてのキー値ペアが保存されている)が並列に表示されていることから、expire辞書の重要性が分かる.

3:期限切れの削除


PERSISTコマンドは、キーの有効期限を削除します.
127.0.0.1:6379> set message "hello"
OK
127.0.0.1:6379> expire message 60
(integer) 1
127.0.0.1:6379> ttl message
(integer) 54
127.0.0.1:6379> persist message
(integer) 1
127.0.0.1:6379> ttl message
(integer) -1

persistコマンドはexpireコマンドの逆コマンドで、この関数は期限切れ辞書で指定されたキーを検索し、期限切れ辞書から削除します.たとえば、上記の図のようにデータベースの現在の状態で、bookというkeyに期限切れを削除すると、次のようになります.
redis> persist book
(integer) 1

データベースは次の状態に更新されます.
Paste_Image.png
PERSIST bookコマンドが実行されると、期限切れ辞書のbookキーが消えていることが図からわかります.

四:残りの生存時間を計算して返す


ttlコマンドは、指定したキーの残りの生存時間を秒単位で返します.pttlはミリ秒で返されます.両方のコマンドは、現在の時間と有効期限の差を計算することによって、残りの生存期間を取得します.
127.0.0.1:6379> set minping shuxin
OK
127.0.0.1:6379> expire minping 60
(integer) 1
127.0.0.1:6379> ttl minping
(integer) 57
127.0.0.1:6379> ttl minping
(integer) 27
127.0.0.1:6379> pttl minping
(integer) 23839
127.0.0.1:6379>

redisソース:
void ttlCommand(redisClient *c) {
    ttlGenericCommand(c, 0);
}
void pttlCommand(redisClient *c) {
    ttlGenericCommand(c, 1);
}
void ttlGenericCommand(redisClient *c, int output_ms) {
    long long expire, ttl = -1;
    /*       ,  -2 */
    if (lookupKeyRead(c->db,c->argv[1]) == NULL) {
        addReplyLongLong(c,-2);
        return;
    }
    
    /*      */
    /*          ,   -1,            */
    expire = getExpire(c->db,c->argv[1]);
    if (expire != -1) {
        /*           ,        */
        ttl = expire-mstime();
        if (ttl < 0) ttl = 0;
    }
    if (ttl == -1) {
        addReplyLongLong(c,-1);
    } else {
         /*       */
        addReplyLongLong(c,output_ms ? ttl : ((ttl+500)/1000));
    }
}

五:期限切れキーの削除ポリシー


キーが期限切れの場合、期限切れになるとすぐにメモリから削除されますか?もしそうでなければ、期限が切れたらいったいいつ削除されますか??
実は3つの異なる削除ポリシーがあります:(1):すぐに削除します.キーの有効期限を設定すると、タイムプロセッサによってキーの削除操作が自動的に実行されるコールバックイベントが作成されます.(2):不活性削除.キーが期限切れになると期限切れになります.dict辞書からkeyを押すたびに、このkeyが期限切れであるかどうかを確認し、期限切れであれば削除しnilを返し、期限切れでなければキー値を返します.(3):タイミング削除.時間ごとにexpires辞書をチェックし、中の期限切れキーを削除します.2つ目はパッシブ削除であり,1つ目と3つ目はアクティブ削除であり,1つ目はリアルタイム性が高いことがわかる.この3つの削除ポリシーを具体的に分析します.

今すぐ削除


直ちに削除すると、メモリ内のデータの最大鮮度が保証されます.これは、期限切れキー値が期限切れ後すぐに削除されることを保証し、使用したメモリも解放されるためです.しかし、すぐに削除するのはcpuにとって最も友好的ではありません.削除操作にはcpuの時間がかかるため、ちょうどcpuが忙しいとき、例えば交差やソートなどの計算をしているときに、cpuに余分な圧力がかかります.
また、現在のredisイベントプロセッサの時間イベントの処理方法である無秩序チェーンテーブルは、keyを検索する時間の複雑さがO(n)であるため、大量の時間イベントを処理するのに適していない.

不活性削除


不活性削除とは、あるキー値が期限切れになった後、このキー値はすぐに削除されず、次回使用されるまで期限切れがチェックされ、削除されることを意味します.したがって、不活性な削除の欠点は明らかです.メモリの浪費です.dict辞書とexpires辞書は、このキー値の情報を保存します.
たとえば、logログなどの時間単位で更新されたデータについては、期限が切れた後も長い間アクセスできない可能性があります.これにより、この間、こんなに多くのメモリを無駄にしてlogを保存することになります.これは、メモリサイズに非常に依存するredisにとって致命的です.

タイミング削除


以上の解析から,直ちに削除すると短時間で大量のcpuが消費され,不活性削除は一定時間メモリを浪費するため,タイミング削除は折衷的な方法である.タイミング削除は、一定時間ごとに削除操作を実行し、削除操作の実行時間と頻度を制限することで、削除操作がcpuに与える影響を低減します.一方、タイミング削除は、不活性削除によるメモリの浪費を効果的に低減する.

六:redisが使用するポリシー


redisで使用される期限切れキー値削除ポリシーは、不活性削除と定期削除の両方を組み合わせて使用します.
作者:舒小贱链接:https://www.jianshu.com/p/9352d20fb2e0出典:簡書簡書の著作権は著者の所有であり、いかなる形式の転載も著者に連絡して授権を得て出典を明記してください.