この記事は董澤潤氏が執筆したWeChat公開アカウント「董澤潤の技術ノート」から転載したものです。この記事を転載する場合は、Dong Zerun の Technical Notes 公開アカウントにご連絡ください。 すべての IT 実務者はキャッシュに触れたことがあり、その基本的な動作原理を理解している必要があります。業界では、「キャッシュは、問題があるところならどこにでも適用できる万能薬である」という有名な格言があります。では彼の本質とは何でしょうか? 上の図は、CPU からその下のハードディスクまで、さまざまなレベルのさまざまなモジュールの実行速度を示しています。上位レベルにもう 1 層のキャッシュを追加すると、下位レベルの速度が遅いという問題を解決できます。ここでの速度が遅いとは、IO が遅いことと、CPU が中間結果をキャッシュするために繰り返し計算することの 2 つの点を指します。 しかし、キャッシュのコスト制約により、キャッシュ サイズは一般的に固定されているため、データを削除する必要があり、キャッシュの一貫性、故障、雪崩、汚染など、一連の他の問題が発生します。この記事では、Redis のソース コードを読んで、主流の削除アルゴリズムを学習します。 LeetCode 146 LRU[1]問題がなかったら、誰も手作業でキャッシュを書くことはないと思います。単純な実装はエンジニアリングの実践とはかけ離れています。真に製品化可能なキャッシュライブラリは、細部のテストです。 Redis キャッシュ削除設定一般的に、redis をストレージとして使用することは推奨されていません。キャッシュとして使用し、max-memory を設定することのみが許可されています。メモリ使用量が最大値に達すると、redis-server はさまざまな設定に従ってキーの削除を開始します。Redis はバージョン 4.0 から LFU[2] (Least frequently used) を導入しました。4.0 より前は、Least Recently Used (LRU) がデフォルトで使用されていました。
デフォルトのポリシーは noeviction で、これは削除しないことを意味します。ディスクがいっぱいになると、システムはディスクに書き込むことができません。LFU 関連に設定することをお勧めします。 LRU は最近使用されていないキーを優先し、コールド データを処理できません。たとえば、ホット キーが短期間アクセスされない場合、一度しか使用されていないコールド データによってフラッシュされ、実際の使用状況を反映できません。 LFUは上記の状況を回避できますが、単純なLFU実装ではバーストトラフィックに対処できず、履歴ホットキーを削除できません。そのため、Redis LFU実装はW-TinyLFU[3]に似ています。ここで、Wはウィンドウを表し、つまり、一定の時間ウィンドウの後に頻度が半分になります。半分にならなければ、キャッシュはキャッシュではなく履歴データの統計になります。 上で述べたように、バースト トラフィックにはどのように対処すればよいでしょうか。その答えは、新しくアクセスされたキーに初期周波数値を与えて、初期値が 0 であるため周波数が更新されないようにすることです。 LRU実装
クライアント コマンドが処理されるたびに、freeMemoryIfNeeded が呼び出され、一部のキーを削除する必要があるかどうかが確認されます。Redis によって使用される実際のメモリが上限に達すると、メモリの削除が開始されます。ただし、Redis は非常に賢いので、すべてのキーに対して LRU キューを作成するわけではありません。代わりに、maxmemory_samples パラメータに従ってサンプリングします。システムのデフォルトは 5 つのキーです。 上記は非常に典型的なグラフです。キーが 10 個に達すると、効果は理論的な LRU アルゴリズムに近づきますが、CPU 消費量が高くなるため、システムのデフォルト値で十分です。 LFUの実装
lookupKey がキーにアクセスすると、LRU が更新されます。Redis 4.0 以降では、LFU アルゴリズムが徐々に導入されています。LRU フィールドは再利用されるため、24 ビットしか使用できません。
カウンターの下位 8 ビットは頻度をカウントするために使用され、値の範囲は 0 から 255 です。ただし、対数をとった後、大きなアクセス頻度を表すことができます。 ldt (最終減分時間) の上位 16 ビットは、最後のアクセス分のタイムスタンプを表し、カウンター値を減少させるために使用されます。カウンターが減少しない場合は、LFU ではなく、履歴キー アクセス数の統計になります。
ldtは16ビットのカウントのみを使用し、最大値は65535であるため、巻き戻しが発生することに注意してください。 LFU 既存のカウントを取得する
num_periodsは計算された減衰回数を表し、lfu_decay_timeは減衰係数を表します。デフォルト値は1です。lfu_decay_timeが1より大きい場合、減衰率は非常に遅くなります。 返される最終カウント値は減衰後の値であり、0になることもある。 LFUカウントの更新と対数
カウントが 255 を超える場合は、カウントせずに直接戻ります。 LFU_INIT_VALは初期値で、デフォルトは5です。 初期値を減算した後、baseval が 0 未満の場合、有効期限が近づいていることを意味するため、カウンター値を増やす可能性が高くなります。
この確率アルゴリズムでは、lfu_log_factor は対数の底であり、デフォルト値は 10 です。カウンター値が小さい場合、自己増加の確率は大きくなります。カウンターが大きい場合、何もしない傾向があります。 カウンター値の範囲は 0 ~ 255 で、十分なアクセス頻度を表すことができます。
この機能に基づいて、redis-cli --hotkeys コマンドを使用して、最近の期間のシステム内のホットキーを表示できます。これは非常に実用的です。この機能は旧バージョンでは利用できないため、手動で統計を行う必要があります。
キャッシュインジケーターについて上で説明した Redis LFU 実装は集中型キャッシュです。また、多くのプロセス用のローカル キャッシュもあります。キャッシュ実装の品質をどのように評価するか?指標は多数あり、詳細がより重要 スループット: QPS はよく言及されます。ベンチマーク バケット実装のハッシュマップの複雑さは O(1) です。キャッシュの複雑さはより高く、ロックの競合にも対処する必要があります。つまり、キャッシュ ライブラリ実装の効率はより高くなります。 キャッシュヒット率: スループットだけでは不十分です。キャッシュヒット率も非常に重要です。ヒット率が高ければ高いほど、キャッシュ導入の効果は大きくなります。 高度な機能: キャッシュ メトリック統計、キャッシュの内訳の処理方法など。 |
>>: コビオニクス、針を使わずにワクチンを投与する新しいロボットを開発
パンデミック中に本当に苦戦した業界の一つはレストランです。多くのレストランは社会的距離を保つ必要性か...
Docker ネットワーク管理は、コンテナをホストに接続し、Docker コンテナ環境での通信とネッ...
[[390356]]ポジティブなゲーム体験を生み出すために、ゲームデザイナーはゲーム内のバランスを繰...
データの共有と流通が厳格な要求になると、もともと孤立していたビジネス ネットワークは境界を打ち破り、...
自動運転車は未来を象徴しているが、運転手が全てを完全に機械に任せることはできないかもしれない。おそら...
10月30日、終了したばかりの李佳琦のライブ放送室で、オンラインショッピング客はアリババの音声ロボッ...
[[187490]] 2016 年末、Google DeepMind は機械学習プラットフォームであ...
近年、民間ドローン産業が急速に発展し、さまざまなコストが大幅に削減されたため、民生用ドローンの普及が...
AIは銀行の顧客サービスの性質を変える銀行やその他の金融機関は、コールセンターからチャットボット、よ...
最近、オーストラレーシア工科大学、マッセー大学、ロイヤルメルボルン工科大学などの研究機関の研究者が、...
クルーズ社の自動運転意思決定計画および制御部門の責任者であるブランドン・バッソ氏は、コロンビア大学で...