キャッシュ除去アルゴリズムLRU実装原理についてお話しましょう

キャッシュ除去アルゴリズムLRU実装原理についてお話しましょう

[[315530]]

01. はじめに

データのクエリ速度を向上させるために、キャッシュがよく使用されます。キャッシュ容量には制限があるため、キャッシュ容量が上限に達すると、新しいデータを追加できるように、一部のデータを削除してスペースを確保する必要があります。キャッシュされたデータはランダムに削除することはできません。一般的に、特定のアルゴリズムに基づいてキャッシュされたデータを削除する必要があります。一般的な除去アルゴリズムには、LRU、LFU、FIFO などがあります。この記事では、LRU アルゴリズムについて説明します。

02. LRUの紹介

LRU  これは Least Recently Used の略です。このアルゴリズムは、最も最近使用されたデータをホット データと見なし、次回も高い確率で再び使用されるようにします。最近ほとんど使用されていないデータは、次回も使用されなくなる可能性があります。キャッシュ容量がいっぱいになると、最近あまり使用されていないデータが最初に削除されます。

キャッシュの内部データが以下のようになっていると仮定します。

ここでは、リストの最初のノードをヘッド ノード、最後のノードをテール ノードと呼びます。

キャッシュを呼び出してキー = 1 のデータを取得する場合、図に示すように、LRU アルゴリズムはノード 1 をヘッド ノードに移動する必要があり、他のノードは変更されません。

次にkey=8のノードを挿入します。このときキャッシュ容量が上限に達しているため、追加する前にデータを削除する必要があります。各クエリはデータをヘッド ノードに移動するため、クエリされていないデータはテール ノードに移動します。テールのデータは最もアクセスが少ないデータであると考えられるため、テール ノードのデータは削除されます。

次に、データをヘッドノードに直接追加します。

LRU アルゴリズムの具体的な手順の概要は次のとおりです。

  • 新しいデータはリストの先頭に直接挿入されます
  • キャッシュデータがヒットし、データがリストの先頭に移動される
  • キャッシュがいっぱいになったら、リストの末尾にあるデータを削除します。

03. LRUアルゴリズムの実装

上記の例からわかるように、LRU アルゴリズムではヘッド ノードを追加し、テール ノードを削除する必要があります。リンクリスト内のノードの追加/削除の時間計算量は O(1) であるため、ストレージ キャッシュ データ コンテナーとして非常に適しています。ただし、通常の一方向リンク リストは使用できません。一方向リンク リストには、いくつかの欠点があります。

  1. 任意のノードからデータを取得するたびに、最初のノードからトラバースする必要があり、その結果、ノードを取得する複雑さは O(N) になります。
  2. 中間ノードをヘッドノードに移動するには、中間ノードの前のノードの情報を知る必要があるため、一方向リンクリストを再度走査して情報を取得する必要があります。

上記の問題は、他のデータ構造を組み合わせることで解決できます。

ハッシュテーブルを使用してノードを格納すると、ノードを取得する複雑さは O(1) に削減されます。ノード移動の問題は、前のノード情報を記録するための先行ポインタをノードに追加することで解決できます。これにより、リンク リストが一方向リンク リストから双方向リンク リストに変更されます。

要約すると、図に二重リンクリストとハッシュテーブルの組み合わせを使用したデータ構造が示されています。

2 つの「センチネル」ノードは双方向リンク リストに意図的に追加されており、データの保存には使用されません。センチネル ノードを使用すると、ノードを追加/削除するときに境界ノードが存在しないかどうかを考慮する必要がなくなり、プログラミングの難易度が軽減され、コードの複雑さが軽減されます。

LRU アルゴリズムの実装コードは次のとおりです。簡略化のため、key と val は両方とも int 型とみなされます。

 public class LRUCache { Entry head, tail; int capacity; int size; Map<Integer, Entry> cache; public LRUCache(int capacity) { this.capacity = capacity; // 初始化链表initLinkedList(); size = 0; cache = new HashMap<>(capacity + 2); } /** * 如果节点不存在,返回-1.如果存在,将节点移动到头结点,并返回节点的数据。 * * @param key * @return */ public int get(int key) { Entry node = cache.get(key); if (node == null) { return -1; } // 存在移动节点moveToHead(node); return node.value; } /** * 将节点加入到头结点,如果容量已满,将会删除尾结点* * @param key * @param value */ public void put(int key, int value) { Entry node = cache.get(key); if (node != null) { node.value = value; moveToHead(node); return; } // 不存在。先加进去,再移除尾结点// 此时容量已满删除尾结点if (size == capacity) { Entry lastNode = tail.pre; deleteNode(lastNode); cache.remove(lastNode.key); size--; } // 加入头结点Entry newNode = new Entry(); newNode.key = key; newNode.value = value; addNode(newNode); cache.put(key, newNode); size++; } private void moveToHead(Entry node) { // 首先删除原来节点的关系deleteNode(node); addNode(node); } private void addNode(Entry node) { head.next.pre = node; node.next = head.next; node.pre = head; head.next = node; } private void deleteNode(Entry node) { node.pre.next = node.next; node.next.pre = node.pre; } public static class Entry { public Entry pre; public Entry next; public int key; public int value; public Entry(int key, int value) { this.key = key; this.value = value; } public Entry() { } } private void initLinkedList() { head = new Entry(); tail = new Entry(); head.next = tail; tail.pre = head; } public static void main(String[] args) { LRUCache cache = new LRUCache(2); cache.put(1, 1); cache.put(2, 2); System.out.println(cache.get(1)); cache.put(3, 3); System.out.println(cache.get(2)); }}

04. LRUアルゴリズムの分析

キャッシュ ヒット率は、キャッシュ システムの非常に重要な指標です。キャッシュ システムのキャッシュ ヒット率が低すぎると、クエリがデータベースに逆流し、データベースにかかる負荷が増加します。

上記の分析と組み合わせると、LRU アルゴリズムの長所と短所がわかります。

LRU アルゴリズムの利点は、実装が難しくなく、ホット データの場合、LRU 効率が非常に優れていることです。

LRU アルゴリズムの欠点は、履歴データのバッチ クエリなどの不定期のバッチ操作では、キャッシュ内の人気データがこれらの履歴データに置き換えられ、キャッシュ汚染が発生し、キャッシュ ヒット率が低下し、通常のデータ クエリが遅くなる可能性があることです。

05. LRUアルゴリズムの改善

以下のソリューションはMySQL InnoDB LRU改善アルゴリズムから派生したものです。

図に示すように、リンク リストをホット データ領域とコールド データ領域の 2 つの部分に分割します。

改善後、アルゴリズムのフローは次のようになります。

  1. アクセスされたデータがホット データ領域にある場合、以前の LRU アルゴリズムと同様に、ホット データ領域のヘッド ノードに移動されます。
  2. データを挿入するときに、キャッシュがいっぱいの場合は、末尾のノードにあるデータを削除します。次に 、データをコールド データ領域のヘッド ノードに挿入します
  3. コールド データ領域のデータにアクセスするたびに、データが 1 秒などの指定された時間以上キャッシュ内に存在していた場合は、ホット データ領域のヘッド ノードに移動されるという判断を行う必要があります。データが指定された時間より前の時間に存在する場合、位置は変更されません。

時々実行されるバッチ クエリの場合、データは単にコールド データ領域に送られ、すぐに削除されます。よく使用されるデータ領域のデータは影響を受けないため、LRU アルゴリズムのキャッシュ ヒット率が低下する問題が解決されます。

その他の改良された方法には、LRU-K、2Q、LIRS アルゴリズムなどがあります。興味のある学生はぜひチェックしてみてください。

<<:  AI技術は製薬業界の発展をどのように促進するのでしょうか?

>>:  流行中にどのようなホットなテクノロジーが使用されていますか? AI、5G、RTC、ビッグデータが登場

推薦する

1 行のコードで AI モデルの推論速度が 10 倍に向上します。 Reddit の技術共有は「恥知らずな自己宣伝」として揶揄される

Reddit フォーラムでは、さまざまな AI テクノロジーについて頻繁に議論されています。最近、あ...

人工知能によってどの産業が繁栄し、どの産業が消滅するのでしょうか?

[[264320]]人工知能の概念は最近非常に人気があります。BAT(百度、テンセント、アリババ)...

機械学習アルゴリズムを使用して配信リンクを最適化する方法

【51CTO.comオリジナル記事】 1. 背景紹介---VODソース配信の問題点オンデマンドビデオ...

DeepMindの論文がNatureに掲載されました。大規模なモデルが、数学者を何十年も悩ませてきた問題に新たな解決策を発見しました。

今年の AI 界のトップトレンドである大規模言語モデル (LLM) は概念を組み合わせるのが得意で、...

人工知能時代の教師の役割の再構築への道

データとアルゴリズムに基づく人工知能技術は、教師の教育活動と専門能力開発を厳格な手順構造の中に簡単に...

...

中国のAI麻雀が新たな高みに到達!テンセントの「Jueyi」が本物のプロプレイヤーを破り新記録を樹立

中国のAIは予想通り、麻雀のプレイでは「楽々と」トップに立った。テンセントの最新ニュースによると、同...

認知マップの科学的インベントリ: グローバルな第3世代AIの「大きな」機会

近年、人工知能 (AI) は、ディープラーニング、コンピューター ビジョン、自然言語処理などの技術革...

...

...

推奨に値する 7 つの優れたオープンソース AI ライブラリ

[[406029]] [51CTO.com クイック翻訳]人工知能 (AI) 研究の分野では、Ten...

...

パスワード危機: ディープラーニングがパスワードクラッキングを加速!

情報セキュリティの専門家は、「生成的敵対ネットワーク」(GAN)がオンラインセキュリティをどのように...

ドローンは都市の発展を助け、6つの側面でインテリジェントな変化をもたらす

近年、国民の高品質・高水準の都市生活への絶え間ない追求に応えるため、スマートシティ建設が大きな注目を...

人工知能では顔と性格の違いは分からない

中国の研究チームは、女性の外見だけに基づいてその性格特性を予測できる人工知能プログラムを立ち上げたと...