1. Configurez Redis pour qu'il utilise l'algorithme LRU
LRU (Least Récemment Utilisé) est l'un des nombreux algorithmes de remplacement A. sorte de.
Il existe un concept maxmemory dans Redis, qui consiste principalement à limiter la mémoire utilisée à une taille fixe. L'algorithme LRU utilisé par Redis est un algorithme LRU approximatif.
(1) Définir maxmemory
Comme mentionné ci-dessus, maxmemory consiste à limiter l'utilisation maximale de la mémoire de Redis. Il existe plusieurs façons de définir sa taille. Une méthode consiste à le définir via CONFIG SET, comme suit :
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"
L'autre méthode consiste à modifier le fichier de configuration redis.conf :
maxmemory 100mb
Notez que sous les systèmes 64 bits, maxmemory est défini sur 0 Indique que l'utilisation de la mémoire Redis n'est pas limitée sous les systèmes 32 bits, la mémoire maximale ne peut implicitement pas dépasser 3 Go.
Lorsque l'utilisation de la mémoire Redis atteint la limite spécifiée, vous devez choisir une stratégie de remplacement.
(2) Stratégie de remplacement
Lorsque l'utilisation de la mémoire Redis atteint la mémoire maximale, vous devez sélectionner la stratégie de mémoire maximale définie pour remplacer les anciennes données.
Voici les stratégies de remplacement qui peuvent être sélectionnées :
noeviction : Aucun remplacement, ce qui signifie qu'aucun remplacement ne sera effectué même si la mémoire atteint la limite supérieure de toutes les commandes. peut provoquer une augmentation de la mémoire et renverra une erreur
allkeys-lru : donner la priorité à la suppression des clés les moins fréquemment utilisées récemment pour enregistrer de nouvelles données
volatiles -lru : uniquement à partir des paramètres. Sélectionnez la clé la moins fréquemment utilisée parmi les clés expirées à supprimer pour enregistrer de nouvelles données.
allkeys-random : sélectionnez au hasard certaines clés parmi toutes les clés Supprimer, pour enregistrer. nouvelles données
volatile-random : sélectionnez uniquement certaines clés parmi les clés définies expirées à supprimer, pour enregistrer de nouvelles données
volatile-ttl : Sélectionnez uniquement la clé avec le temps de survie (TTL) le plus court parmi les clés expirées pour la supprimer afin d'enregistrer de nouvelles données
Il est à noter que :
(1) La méthode de définition de maxmemory-policy est similaire à la méthode de définition de maxmemory, qui peut être modifiée dynamiquement via redis.conf ou CONFIG SET.
(2) Si aucune clé pouvant être supprimée ne correspond, alors les stratégies volatile-lru, volatile-random et volatile-ttl sont les mêmes que la stratégie de remplacement par noeviction - aucune clé ne sera remplacée.
(3) Il est très important de choisir la stratégie de remplacement appropriée, qui dépend principalement du mode d'accès de votre application. Bien entendu, vous pouvez également modifier dynamiquement la stratégie de remplacement et la sortir en utilisant la commande Redis. - INFO Le taux de réussite du cache peut ensuite être utilisé pour affiner la stratégie de remplacement.
De manière générale, il existe des expériences courantes comme celle-ci :
Si toutes les clés sont les plus fréquemment utilisées récemment, vous devez alors sélectionner allkeys-lru pour remplacer le plus les plus récentes. La clé la moins fréquemment utilisée. Si vous ne savez pas quelle stratégie utiliser, il est recommandé d'utiliser allkeys-lru.
Si les probabilités d'accès de toutes les clés sont similaires, vous pouvez utiliser la stratégie allkeys-random pour remplacer les données.
Si vous comprenez suffisamment les données et pouvez spécifier un indice pour la clé (spécifiée via expire/ttl), vous pouvez choisir volatile-ttl pour le remplacement.
volatile-lru et volatile-random sont souvent utilisés lorsqu'une instance Redis est utilisée à la fois pour la mise en cache et la persistance. Cependant, il est préférable d'utiliser deux instances Redis pour résoudre ce problème. question.
Définir le délai d'expiration occupera de la mémoire, mais avec allkeys-lru, il n'est pas nécessaire de définir le délai d'expiration, ce qui permet une utilisation plus efficace de la mémoire.
(3) Comment fonctionne la stratégie de remplacement
Il est très important de comprendre comment la stratégie de remplacement est exécutée, comme :
Le client exécute une nouvelle commande, ce qui oblige la base de données à ajouter des données (telles que définir la valeur de la clé)
Redis vérifiera l'utilisation de la mémoire si l'utilisation de la mémoire dépasse. maxmemory, elle sera supprimée selon la stratégie de remplacement Certaines clés
La nouvelle commande est exécutée avec succès
Notre écriture continue des données entraînera la mémoire pour atteindre ou dépasser la limite supérieure maxmemory, mais la stratégie de remplacement fera en sorte que l'utilisation de la mémoire tombe en dessous de la limite supérieure.
Si une grande quantité de mémoire doit être utilisée en même temps (par exemple, pour écrire un grand ensemble à la fois), l'utilisation de la mémoire de Redis peut dépasser la limite de mémoire maximale pendant un certain temps.
(4) Algorithme LRU approximatif
LRU dans Redis n'est pas une implémentation stricte de l'algorithme LRU, mais une implémentation LRU approximative, principalement pour économiser de la mémoire et améliorer les performances. Redis a une telle configuration - maxmemory-samples. Le LRU de Redis consiste à supprimer le nombre configuré de clés, puis à sélectionner la clé la moins fréquemment utilisée parmi elles pour la remplacer. La valeur par défaut est 5, comme suit :
maxmemory-samples 5
. Oui Bénéficiez d'avantages en termes de rapidité ou de précision de l'algorithme de remplacement LRU en ajustant le nombre d'échantillons.
La raison pour laquelle Redis n'utilise pas de véritable implémentation LRU est d'économiser l'utilisation de la mémoire. Bien qu’il ne s’agisse pas d’une véritable implémentation LRU, leur application est presque équivalente. La figure suivante est une comparaison entre l'implémentation LRU approximative de Redis et l'implémentation théorique LRU :
测试开始首先在Redis中导入一定数目的key,然后从第一个key依次访问到最后一个key,因此根据LRU算法第一个被访问的key应该最新被置换,之后再增加50%数目的key,导致50%的老的key被替换出去。
在上图中你可以看到三种类型的点,组成三种不同的区域:
淡灰色的是被置换出去的key
灰色的是没有被置换出去的key
绿色的是新增加的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入门教程栏目。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!