Heim  >  Artikel  >  Datenbank  >  So richten Sie den LRU-Algorithmus in Redis ein

So richten Sie den LRU-Algorithmus in Redis ein

尚
nach vorne
2020-05-23 08:58:154183Durchsuche

So richten Sie den LRU-Algorithmus in Redis ein

1. Stellen Sie Redis so ein, dass es den LRU-Algorithmus verwendet

LRU (Least Latest Used) ist einer der vielen Ersatzalgorithmen A irgendwie.
In Redis gibt es ein Maxmemory-Konzept, das hauptsächlich darin besteht, den verwendeten Speicher auf eine feste Größe zu begrenzen. Der von Redis verwendete LRU-Algorithmus ist ein ungefährer LRU-Algorithmus.

(1) Legen Sie maxmemory fest

Wie oben erwähnt, dient maxmemory dazu, die maximale Speichernutzung von Redis zu begrenzen. Es gibt mehrere Möglichkeiten, die Größe festzulegen. Eine Methode besteht darin, es über CONFIG SET wie folgt festzulegen:

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"

Die andere Methode besteht darin, die Konfigurationsdatei redis.conf zu ändern:

maxmemory 100mb

Beachten Sie, dass bei 64-Bit-Systemen maxmemory auf eingestellt ist 0 Gibt an, dass die Redis-Speichernutzung nicht begrenzt ist. Unter 32-Bit-Systemen darf maxmemory implizit 3 GB nicht überschreiten.
Wenn die Redis-Speichernutzung den angegebenen Grenzwert erreicht, müssen Sie eine Ersatzstrategie wählen.

(2) Ersetzungsstrategie

Wenn die Redis-Speichernutzung maxmemory erreicht, müssen Sie die festgelegte maxmemory-policy auswählen, um die alten Daten zu ersetzen.
Die folgenden Ersetzungsstrategien können ausgewählt werden:

  • noeviction: Keine Ersetzung, was bedeutet, dass keine Ersetzung durchgeführt wird, selbst wenn der Speicher die Obergrenze erreicht. Alle Befehle, die kann zu einer Speichervergrößerung führen, die einen Fehler zurückgibt

  • allkeys-lru: Priorisieren Sie das Löschen der Schlüssel, die in letzter Zeit am seltensten verwendet wurden, um neue Daten zu speichern

  • flüchtig -lru: Nur aus den Einstellungen. Wählen Sie den am seltensten verwendeten Schlüssel unter den abgelaufenen Schlüsseln zum Löschen aus, um neue Daten zu speichern.

  • allkeys-random: Wählen Sie zufällig einige Schlüssel aus allen Schlüsseln zum Speichern aus neue Daten

  • volatile-random: Wählen Sie nur einige Schlüssel aus den abgelaufenen Satzschlüsseln zum Löschen aus, um neue Daten zu speichern

  • volatile-ttl: Aus den abgelaufenen Schlüsseln wird nur der Schlüssel mit der kürzesten Überlebenszeit (TTL) zum Löschen ausgewählt, um neue Daten zu speichern

Es ist zu beachten, dass:

(1 ) Die Methode zum Festlegen von maxmemory-policy ähnelt der Methode zum Festlegen von maxmemory, die dynamisch über redis.conf oder CONFIG SET geändert werden kann.

(2) Wenn kein Schlüssel übereinstimmt, der gelöscht werden kann, sind die Strategien volatile-lru, volatile-random und volatile-ttl dieselben wie die Noeviction-Ersetzungsstrategie – es werden keine Schlüssel ersetzt.

(3) Es ist sehr wichtig, die geeignete Ersetzungsstrategie auszuwählen, die hauptsächlich vom Zugriffsmodus Ihrer Anwendung abhängt. Natürlich können Sie die Ersetzungsstrategie auch dynamisch ändern und mithilfe des Redis-Befehls ausgeben - INFO Die Cache-Trefferrate kann dann zur Optimierung der Ersetzungsstrategie verwendet werden.

Im Allgemeinen gibt es einige häufige Erfahrungen wie diese:

  • Wenn alle Tasten in letzter Zeit am häufigsten verwendet wurden, müssen Sie allkeys-lru auswählen, um sie am häufigsten zu ersetzen Aktuelle. Der am seltensten verwendete Schlüssel. Wenn Sie nicht sicher sind, welche Strategie Sie verwenden sollen, wird die Verwendung von allkeys-lru empfohlen.

  • Wenn die Zugriffswahrscheinlichkeiten aller Schlüssel ähnlich sind, kann die Allkeys-Random-Strategie zum Ersetzen der Daten verwendet werden.

  • Wenn Sie die Daten ausreichend verstehen und einen Hinweis für den Schlüssel angeben können (angegeben durch expire/ttl), können Sie volatile-ttl als Ersatz wählen.

volatile-lru und volatile-random werden häufig verwendet, wenn eine Redis-Instanz sowohl für das Caching als auch für die Persistenz verwendet wird. Es ist jedoch besser, zwei Redis-Instanzen zu verwenden, um das Problem zu lösen Frage.

Das Festlegen der Ablaufzeit „expire“ belegt etwas Speicher, aber mit allkeys-lru ist es nicht nötig, die Ablaufzeit festzulegen, wodurch der Speicher effizienter genutzt wird.

(3) Wie die Ersetzungsstrategie funktioniert

Es ist sehr wichtig zu verstehen, wie die Ersetzungsstrategie ausgeführt wird, wie zum Beispiel:

  1. Der Client führt einen neuen Befehl aus, wodurch die Datenbank Daten hinzufügen muss (z. B. Schlüsselwert festlegen)

  2. Redis überprüft die Speichernutzung, wenn die Speichernutzung überschritten wird maxmemory, es wird gemäß der Ersetzungsstrategie einige Schlüssel gelöscht

  3. Der neue Befehl wurde erfolgreich ausgeführt

Unser kontinuierliches Schreiben von Daten führt dazu Der Speicher erreicht oder überschreitet die Obergrenze von maxmemory, die Ersetzungsstrategie führt jedoch dazu, dass die Speichernutzung unter die Obergrenze fällt.

Wenn viel Speicher gleichzeitig verwendet werden muss (z. B. beim Schreiben eines großen Satzes auf einmal), kann die Speichernutzung von Redis für einen bestimmten Zeitraum das maximale Speicherlimit überschreiten.

(4) Ungefährer LRU-Algorithmus

LRU in Redis ist keine strikte LRU-Algorithmusimplementierung, sondern eine ungefähre LRU-Implementierung, hauptsächlich um Speicher zu sparen und die Leistung zu verbessern. Redis verfügt über eine solche Konfiguration: Die LRU von maxmemory-samples besteht darin, die konfigurierte Anzahl von Schlüsseln herauszunehmen und dann einen Schlüssel auszuwählen, der in letzter Zeit am wenigsten verwendet wurde, wie folgt:

maxmemory-samples 5

OK Profitieren Sie von Geschwindigkeits- oder Genauigkeitsvorteilen des LRU-Ersetzungsalgorithmus, indem Sie die Anzahl der Proben anpassen.

Der Grund, warum Redis keine echte LRU-Implementierung verwendet, besteht darin, Speicherverbrauch zu sparen. Obwohl es sich nicht um eine echte LRU-Implementierung handelt, sind sie in der Anwendung nahezu gleichwertig. Die folgende Abbildung ist ein Vergleich zwischen der ungefähren LRU-Implementierung von Redis und der theoretischen LRU-Implementierung:

So richten Sie den LRU-Algorithmus in Redis ein

测试开始首先在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入门教程栏目。

Das obige ist der detaillierte Inhalt vonSo richten Sie den LRU-Algorithmus in Redis ein. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:cnblogs.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen
Vorheriger Artikel:rdb-aof Hybrid-PersistenzNächster Artikel:rdb-aof Hybrid-Persistenz