Redis タイムアウト削除には 3 つの回答が考えられます。これらは 3 つの異なる削除戦略を表します。
時間指定削除: キーの有効期限を設定する際に、タイマーを作成します。 (タイマー) キーの有効期限が来ると、タイマーによってキーの削除が直ちに実行されます。 遅延削除: キーの有効期限を設定しますが、キー空間からキーを取得するたびに、取得したキーの有効期限が切れているかどうかを確認します。有効期限が切れている場合はキーを削除し、有効期限が切れていない場合はリターンします。キー 。 定期的な削除: プログラムは時々データベースをチェックし、期限切れのキーを削除します。削除する期限切れのキーの数とチェックするデータベースの数はアルゴリズムによって決まります。 これら 3 つの戦略のうち、1 つ目と 3 つ目は能動的削除戦略であり、2 つ目は受動的削除戦略です。スケジュールされた削除:
スケジュールされた削除戦略は最もメモリに優しいです。タイマーを使用することで、スケジュールされた削除戦略により、期限切れのキーはできるだけ早く削除され、期限切れのキーによって占有されていたメモリが解放されます。 一方、スケジュールされた削除戦略の欠点は、CPU 時間に最も優しくないことです。期限切れのキーが多数ある場合、期限切れのキーの削除が CPU 時間のかなりの部分を占める可能性があります。メモリが不足していなくても CPU 時間が非常に不足している場合、現在のタスクに関係のない期限切れのキーを削除するために CPU 時間を使用すると、間違いなくサーバーの応答時間とスループットに影響します。 たとえば、サーバーの処理を待機している大量のコマンド リクエストがあり、サーバーが現在メモリ不足ではない場合、サーバーは代わりに CPU 時間を優先してクライアントのコマンド リクエストを処理する必要があります。期限切れのキーの削除については上記を参照してください。 さらに、タイマーを作成するには、Redis サーバーで時間イベントを使用する必要があります。現在の時間イベントは、順序なしのリンク リストとして実装されます。イベントを見つける時間の計算量は O(N) です。大量の時間イベントを効率的に処理できません。 したがって、スケジュールされた削除戦略を実装するためにサーバーに多数のタイマーを作成するように要求するのは、現段階では現実的ではありません。遅延削除:
遅延削除戦略は、最も CPU 時間に優しい方法です。プログラムは、キーが削除された場合にのみキーを削除します。チェックが実行され、期限切れのキーの削除が必要な場合にのみ実行され、削除対象が現在処理されているキーに限定されることが保証されます。この戦略では、他の無関係な期限切れのキーの削除に CPU 時間を費やすことはありません。 遅延削除戦略の欠点は、メモリに最も優しくないことです。キーの有効期限が切れていて、そのキーがまだデータベースに保持されている場合、期限切れのキーが削除されない限り、メモリは占有されますが、解放されません。 遅延削除戦略を使用する場合、データベース内に期限切れのキーが多数あり、これらの期限切れのキーがたまたまアクセスされなかった場合、(ユーザーが手動で FLUSHDB を実行しない限り) それらのキーは削除されない可能性があります。この状況はメモリ リークとみなすこともできます。無駄なガベージ データが大量のメモリを占有していますが、サーバーはそれらを自動的に解放しません。これは、実行ステータスがメモリに大きく依存する Redis サーバーにとって問題です。これは間違いなく問題です。良いニュースではありません。 たとえば、ログなどの一部の時間関連データの場合、特定の時点を過ぎると、それらへのアクセスが大幅に減少するか、アクセスされなくなることさえあります。ユーザーはサーバーがそれらを自動的に削除したと考えていますが、実際にはこれらのキーはまだ存在しており、キーによって占有されていたメモリは解放されていません。結果は非常に深刻になるはずです。定期的な削除:
スケジュールされた削除と遅延削除に関する上記の説明から、これら 2 つの削除方法は、単独で使用する場合には個別に使用できます。すべてに明らかな欠陥があります: ·時間指定削除は CPU 時間を過剰に消費し、サーバーの応答時間とスループットに影響を与えます。 ·遅延削除はメモリを大量に浪費し、メモリ リークの危険性があります。 定期的な削除戦略は、最初の 2 つの戦略を統合して折衷したものです。 · 定期的な削除戦略は、期限切れのキーの削除を時々実行し、削除を制限することによって実行します。削除操作による CPU 時間への影響を軽減するための期間と頻度。 ###·さらに、期限切れのキーを定期的に削除することにより、定期的な削除戦略により、期限切れのキーによって引き起こされるメモリの無駄が効果的に削減されます。
定期的な削除戦略の難しさは、削除操作の長さと頻度を決定することです。
·削除操作の実行頻度が高すぎる場合、または実行時間が長すぎる場合、定期的な削除戦略は、期限切れのキーの削除に大量の CPU 時間を消費します。
·削除操作の実行時間が少なすぎる場合、または実行時間が短すぎる場合、通常の削除戦略は遅延削除戦略と同じになり、メモリが無駄に消費されます。
期限切れのキーの定期的な削除戦略は、redis.c/activeExpireCycle 関数によって実装されます。Redis サーバーが redis.c/serverCron 関数を定期的に実行するたびに、activeExpireCycle 関数が呼び出されます。指定された時間内に、サーバー内の各データベースが複数回走査され、一部のキーの有効期限がデータベースの有効期限ディクショナリからランダムにチェックされ、期限切れのキーが削除されます。
プロセス全体は、疑似コードで次のように記述できます。
# 默认每次检查的数据库数量 DEFAULT_DB_NUMBERS = 16 # 默认每个数据库检查的键数量 DEFAULT_KEY_NUMBERS = 20 # 全局变量,记录检查进度 current_db = 0 def activeExpireCycle(): # 初始化要检查的数据库数量 # 如果服务器的数据库数量比 DEFAULT_DB_NUMBERS 要小 # 那么以服务器的数据库数量为准 if server.dbnum < DEFAULT_DB_NUMBERS: db_numbers = server.dbnum else: db_numbers = DEFAULT_DB_NUMBERS # 遍历各个数据库 for i in range(db_numbers): # 如果current_db 的值等于服务器的数据库数量 # 这表示检查程序已经遍历了服务器的所有数据库一次 # 将current_db 重置为0 ,开始新的一轮遍历 if current_db == server.dbnum: current_db = 0 # 获取当前要处理的数据库 redisDb = server.db[current_db] # 将数据库索引增1 ,指向下一个要处理的数据库 current_db += 1 # 检查数据库键 for j in range(DEFAULT_KEY_NUMBERS): # 如果数据库中没有一个键带有过期时间,那么跳过这个数据库 if redisDb.expires.size() == 0: break # 随机获取一个带有过期时间的键 key_with_ttl = redisDb.expires.get_random_key() # 检查键是否过期,如果过期就删除它 if is_expired(key_with_ttl): delete_key(key_with_ttl) # 已达到时间上限,停止处理 if reach_time_limit(): return
activeExpireCycle 関数の動作モードは、次のように要約できます。
·関数が実行されるたび、一定数のデータベースから開始されます。一定数のランダムなキーが検査のために取り出され、期限切れのキーが削除されます。
·グローバル変数 current_db は、現在の activeExpireCycle 関数チェックの進行状況を記録し、次回 activeExpireCycle 関数が呼び出されたときに、以前の進行状況が処理されます。たとえば、現在の activeExpireCycle 関数がデータベース 10 番を走査したときに戻った場合、次回 activeExpireCycle 関数が実行されると、データベース 11 番から期限切れのキーが検索されて削除されます。
·activeExpireCycle 関数の実行が続くと、サーバー内のすべてのデータベースがチェックされます。この時点で、この関数は current_db 変数を 0 にリセットし、新しいラウンドのチェック作業を再度開始します。
Redis 関連の知識の詳細については、Redis 使用法チュートリアル 列をご覧ください。
以上がRedisにはスケジュール削除機能はありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。