ホームページ > データベース > Redis > Redis で LRU アルゴリズムを設定する方法

Redis で LRU アルゴリズムを設定する方法

リリース: 2020-05-23 08:58:15
転載
4205 人が閲覧しました

Redis で LRU アルゴリズムを設定する方法

1. LRU アルゴリズムを使用するように Redis を設定します。

LRU (最も最近使用されていない) アルゴリズムは、数多くあるアルゴリズムの 1 つです。置換アルゴリズムの一種。
Redis には maxmemory の概念があり、主に使用されるメモリを固定サイズに制限します。 Redis で使用される LRU アルゴリズムは近似 LRU アルゴリズムです。

(1) maxmemory の設定

上記の通り、maxmemory は Redis の最大メモリ使用量を制限するためのものです。サイズを設定するにはいくつかの方法があります。 1 つの方法は、次のように CONFIG SET を通じて設定することです:

127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "0"
127.0.0.1:6379> CONFIG SET maxmemory 100MB
OK
127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "104857600"
ログイン後にコピー

もう 1 つの方法は、構成ファイル redis.conf を変更することです:

maxmemory 100mb
ログイン後にコピー

64 ビット システムでは、maxmemory が次のように設定されることに注意してください。 0 Redis のメモリ使用量が制限されていないことを示します。32 ビット システムでは、maxmemory は暗黙的に 3GB を超えることができません。
Redis のメモリ使用量が指定された制限に達した場合は、交換戦略を選択する必要があります。

(2) 置換ポリシー

Redis のメモリ使用量が maxmemory に達した場合、設定された maxmemory-policy を選択して古いデータを置き換える必要があります。
選択できる置換方法は次のとおりです:

  • noeviction: 置換なし、つまりメモリが上限に達しても置換は実行されません。メモリ増加を引き起こす可能性のあるコマンドはエラーを返します

  • allkeys-lru: 新しいデータを保存するために、最近使用頻度が最も低いキーを優先的に削除します

  • volatile-lru: 新しいデータを保存するために削除する期限切れのキーの中で最も使用頻度の低いキーを選択するのみを設定します

  • allkeys-random: すべてのキーからいくつかのキーをランダムに選択します。新しいデータを保存するには

  • #volatile-random: 期限切れのセット キーから一部のキーのみを選択して削除し、新しいデータを保存します

  • volatile-ttl : 有効期限が切れた設定キーの中から生存時間 (TTL) が最も短いキーのみを選択して削除し、新しいデータを保存します

なお、次の点に注意してください:

( 1) maxmemory-policy の設定方法は、maxmemory の設定方法と似ており、redis.conf または CONFIG SET を通じて動的に変更できます。

(2) 削除できる一致するキーがない場合、volatile-lru、volatile-random、および volatile-ttl 戦略は noeviction 置換戦略と同じであり、キーは置き換えられません。

(3) 適切な置換戦略を選択することは非常に重要であり、主にアプリケーションのアクセス モードに依存します。もちろん、Redis コマンドを使用して置換戦略を動的に変更し、出力することもできます。 - INFO キャッシュ ヒット率を使用して、置換戦略を調整できます。

一般的に、いくつかの一般的な経験があります:

  • すべてのキーが最近最も頻繁に使用されている場合は、allkeys-lru を選択して最新のキーを置き換える必要があります。最も頻繁に使用されないキー。どの戦略を使用すればよいかわからない場合は、allkeys-lru を使用することをお勧めします。

  • すべてのキーのアクセス確率が類似している場合は、allkeys-random 戦略を使用してデータを置き換えることができます。

  • データを十分に理解しており、キーのヒント (expire/ttl で指定) を指定できる場合は、置換用に volatile-ttl を選択できます。

volatile-lru と volatile-random は、1 つの Redis インスタンスがキャッシュと永続化の両方に使用される場合によく使用されますが、問題を解決するには 2 つの Redis インスタンスを使用することをお勧めします。問題。

有効期限を設定するとメモリを占有しますが、allkeys-lru を使用すると有効期限を設定する必要がないため、メモリをより効率的に使用できます。

#(3) 置換戦略の仕組み

次のような置換戦略がどのように実行されるかを理解することが非常に重要です。

#クライアントが新しいコマンドを実行すると、データベースはデータを追加する必要があります (キー値の設定など)

  1. Redis はメモリ使用量をチェックします。メモリ使用量が超過した場合は、 maxmemory、置換戦略に従って削除されます。いくつかのキー

  2. 新しいコマンドは正常に実行されました

  3. データの継続的な書き込みは、メモリが上限 maxmemory に達するかそれを超える原因になりますが、交換戦略によりメモリ使用量は上限を下回ります。

    一度に大量のメモリを使用する必要がある場合 (大規模なセットを一度に書き込むなど)、Redis のメモリ使用量が一定期間最大メモリ制限を超える可能性があります。

(4) 近似 LRU アルゴリズム

Redis の LRU は、厳密な LRU アルゴリズム実装ではなく、主にメモリ占有量の節約とパフォーマンスの向上を目的とした近似 LRU 実装です。 Redis には maxmemory-samples という構成があります。Redis の LRU は、構成された数のキーを取り出し、その中で最も使用頻度の低いキーを選択して置き換えます。デフォルトは次のように 5 です:

maxmemory-samples 5
ログイン後にコピー
はい サンプル数を調整することで、LRU 置換アルゴリズムの速度または精度において利点が得られます。

Redis が実際の LRU 実装を使用しない理由は、メモリ使用量を節約するためです。真の LRU 実装ではありませんが、アプリケーションではほぼ同等です。次の図は、Redis のおおよその LRU 実装と理論上の LRU 実装の比較です。

Redis で LRU アルゴリズムを設定する方法

测试开始首先在Redis中导入一定数目的key,然后从第一个key依次访问到最后一个key,因此根据LRU算法第一个被访问的key应该最新被置换,之后再增加50%数目的key,导致50%的老的key被替换出去。

在上图中你可以看到三种类型的点,组成三种不同的区域:

  1. 淡灰色的是被置换出去的key

  2. 灰色的是没有被置换出去的key

  3. 绿色的是新增加的key

理论LRU实现就像我们期待的那样,最旧的50%数目的key被置换出去,Redis的LRU将一定比例的旧key置换出去。

可以看到在样本数为5的情况下,Redis3.0要比Redis2.8做的好很多,Redis2.8中有很多应该被置换出去的数据没有置换出去。在样本数为10的情况下,Redis3.0很接近真正的LRU实现。

LRU是一个预测未来我们会访问哪些数据的模型,如果我们访问数据的形式接近我们预想——幂律,那么近似LRU算法实现将能处理的很好。

在模拟测试中我们可以发现,在幂律访问模式下,理论LRU和Redis近似LRU的差距很小或者就不存在差距。

如果你将maxmemory-samples设置为10,那么Redis将会增加额外的CPU开销以保证接近真正的LRU性能,可以通过检查命中率来查看有什么不同。

通过CONFIG SET maxmemory-samples 动态调整样本数大小,做一些测试验证你的猜想。

2、LRU的实现

<?php
/**
 * LRU是最近最少使用页面置换算法(Least Recently Used),也就是首先淘汰最长时间未被使用的页面
 */
class LRU_Cache
{

    private $array_lru = array();
    private $max_size = 0;

    function __construct($size)
    {
        // 缓存最大存储
        $this->max_size = $size;
    }

    public function set_value($key, $value)
    {
        // 如果存在,则向队尾移动,先删除,后追加
        // array_key_exists() 函数检查某个数组中是否存在指定的键名,如果键名存在则返回true,如果键名不存在则返回false。
        if (array_key_exists($key, $this->array_lru)) {
            // unset() 销毁指定的变量。
            unset($this->array_lru[$key]);
        }
        // 长度检查,超长则删除首元素
        if (count($this->array_lru) > $this->max_size) {
            // array_shift() 函数删除数组中第一个元素,并返回被删除元素的值。
            array_shift($this->array_lru);
        }
        // 队尾追加元素
        $this->array_lru[$key] = $value;
    }

    public function get_value($key)
    {
        $ret_value = false;

        if (array_key_exists($key, $this->array_lru)) {
            $ret_value = $this->array_lru[$key];
            // 移动到队尾
            unset($this->array_lru[$key]);
            $this->array_lru[$key] = $ret_value;
        }

        return $ret_value;
    }

    public function vardump_cache()
    {
        echo "<br>";
        var_dump($this->array_lru);
    }
}

$cache = new LRU_Cache(5);                          // 指定了最大空间 6
$cache->set_value("01", "01");
$cache->set_value("02", "02");
$cache->set_value("03", "03");
$cache->set_value("04", "04");
$cache->set_value("05", "05");
$cache->vardump_cache();
echo "<br>";

$cache->set_value("06", "06");
$cache->vardump_cache();
echo "<br>";

$cache->set_value("03", "03");
$cache->vardump_cache();
echo "<br>";

$cache->set_value("07", "07");
$cache->vardump_cache();
echo "<br>";

$cache->set_value("01", "01");
$cache->vardump_cache();
echo "<br>";

$cache->get_value("04");
$cache->vardump_cache();
echo "<br>";

$cache->get_value("05");
$cache->vardump_cache();
echo "<br>";

$cache->get_value("10");
$cache->vardump_cache();
echo "<br>";
ログイン後にコピー

更多redis知识请关注redis入门教程栏目。

以上がRedis で LRU アルゴリズムを設定する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:cnblogs.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート