Maison >base de données >Redis >Un article expliquant en détail l'algorithme LRU dans Redis
Cet article vous présentera LRU (Least Récemment Utilisé) dans Redis J'espère qu'il vous sera utile !
Redis est une base de données clé-valeur basée sur le stockage en mémoire. Nous savons que même si la mémoire est rapide, elle dispose de peu d'espace lorsque la mémoire physique atteint la limite supérieure, car le système fonctionne très lentement. le mécanisme de swap stockera une partie de la mémoire. Les données sont transférées vers la partition de swap et l'échange avec swap garantit que le système continue de fonctionner. Toutefois, le swap est un stockage sur disque dur et sa vitesse est bien plus lente que celle de swap. mémoire Surtout pour un service avec un QPS très élevé comme Redis, il est impossible de le faire lorsqu'il est reçu. (Notez que si la mémoire de la partition de swap est également pleine, une erreur se produira dans le système !) [Recommandation associée : Tutoriel vidéo Redis]
Le système d'exploitation Linux peut vérifier la taille du swap via free -m:
Alors comment ? Il est très important d'éviter que cette situation ne se produise dans Redis (l'intervieweur ne pose presque jamais de questions sur ce point de connaissance lorsqu'il est interrogé sur Redis).
Redis fournit une configuration maxmemory pour résoudre les problèmes ci-dessus. Cette configuration peut spécifier l'ensemble de données maximum de stockage Redis, ou elle peut être configurée à l'aide du CONFIG SET. commande au moment de l’exécution.
Schéma schématique des éléments de configuration dans le fichier redis.conf :
Par défaut, l'élément de configuration maxmemory n'est pas activé Redis introduit officiellement que les systèmes d'exploitation 64 bits n'ont pas de limite de mémoire par défaut, et 32. Les systèmes d'exploitation -bit ont une configuration de mémoire implicite par défaut de 3 Go. Si maxmemory est 0, cela signifie que la mémoire est illimitée.
Ainsi, lorsque nous construisons une architecture de cache, nous devons effectuer des configurations de mémoire maximale appropriées en fonction des ressources matérielles et des besoins de l'entreprise.
, LFU sera décrit dans le prochain article), qui supprime les clés qui remplissent les conditions pour dire. au revoir aux anciens et bienvenue aux nouveaux. stratégie d'élimination de la politique de mémoire maximale :
Nous utilisons d'abord des conteneurs Java pour implémenter un algorithme LRU simple. Nous utilisons ConcurrentHashMap pour effectuer la relation de mappage des éléments de stockage des résultats clé-valeur et utilisons ConcurrentLinkedDeque pour maintenir la séquence d'accès aux clés.
package com.lizba.redis.lru; import java.util.Arrays; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedDeque; /** * <p> * LRU简单实现 * </p> * * @Author: Liziba * @Date: 2021/9/17 23:47 */ public class SimpleLru { /** 数据缓存 */ private ConcurrentHashMap<string> cacheData; /** 访问顺序记录 */ private ConcurrentLinkedDeque<string> sequence; /** 缓存容量 */ private int capacity; public SimpleLru(int capacity) { this.capacity = capacity; cacheData = new ConcurrentHashMap(capacity); sequence = new ConcurrentLinkedDeque(); } /** * 设置值 * * @param key * @param value * @return */ public Object setValue(String key, Object value) { // 判断是否需要进行LRU淘汰 this.maxMemoryHandle(); // 包含则移除元素,新访问的元素一直保存在队列最前面 if (sequence.contains(key)) { sequence.remove(); } sequence.addFirst(key); cacheData.put(key, value); return value; } /** * 达到最大内存,淘汰最近最少使用的key */ private void maxMemoryHandle() { while (sequence.size() >= capacity) { String lruKey = sequence.removeLast(); cacheData.remove(lruKey); System.out.println("key: " + lruKey + "被淘汰!"); } } /** * 获取访问LRU顺序 * * @return */ public List<string> getAll() { return Arrays.asList(sequence.toArray(new String[] {})); } }复制代码</string></string></string>
Code de test :
package com.lizba.redis.lru; /** * <p> * 测试最近最少使用 * </p> * * @Author: Liziba * @Date: 2021/9/18 0:00 */ public class TestSimpleLru { public static void main(String[] args) { SimpleLru lru = new SimpleLru(8); for (int i = 0; i <p>Résultats des tests : <strong></strong></p><p><strong></strong>Comme le montrent les résultats des tests ci-dessus, key0 et key1 qui ont été ajoutées en premier ont été éliminées et ont été ajouté en dernier La clé est également la dernière clé stockée en tête de la séquence. </p>Avec cette solution, l'algorithme LRU peut être facilement implémenté ; mais les inconvénients sont également très évidents. La solution nécessite l'utilisation de structures de données supplémentaires pour enregistrer la séquence d'accès aux clés, ce qui augmentera la consommation de mémoire Redis. optimiser la mémoire Mais cela consomme beaucoup de mémoire, ce qui n'est évidemment pas possible. <p><img src="https://img.php.cn/upload/image/775/594/750/163409191823487Un%20article%20expliquant%20en%20d%C3%A9tail%20lalgorithme%20LRU%20dans%20Redis" title="163409191823487Un article expliquant en détail lalgorithme LRU dans Redis" alt="Un article expliquant en détail lalgorithme LRU dans Redis"></p><h2 data-id="heading-4">5. LRU approximatif de Redis</h2><p>En réponse à cette situation, Redis utilise l'algorithme LRU approximatif, qui n'est pas complètement précis pour éliminer les clés les moins fréquemment utilisées récemment, mais la précision globale peut être garantie. <br>L'algorithme LRU approximatif est très simple. Dans l'objet clé Redis, 24 bits sont ajoutés pour stocker l'horodatage système du dernier accès Lorsque le client envoie une requête liée à l'écriture de clé au serveur Redis, il s'avère que la mémoire. atteint la mémoire maximale À ce moment-là, déclenchez la suppression paresseuse ; le service Redis sélectionne 5 clés qui remplissent les conditions par échantillonnage aléatoire (notez que cet échantillonnage aléatoire <strong>allkeys-lru</strong> est échantillonné de manière aléatoire à partir de toutes les clés, <strong>volatile-lru</strong> est à partir de toutes les clés. avec le délai d'expiration défini Échantillonnage aléatoire), comparez le dernier horodatage d'accès enregistré dans l'objet clé et éliminez la clé la plus ancienne parmi les cinq clés si la mémoire n'est toujours pas suffisante, continuez à répéter cette étape ; <br></p><p><strong>Notez que 5 est la taille de valeur d'échantillonnage aléatoire par défaut de Redis, qui peut être configurée via maxmemory_samples dans redis.conf : </strong></p><p><img src="https://img.php.cn/upload/image/866/655/134/163409192913128Un%20article%20expliquant%20en%20d%C3%A9tail%20lalgorithme%20LRU%20dans%20Redis" title="163409192913128Un article expliquant en détail lalgorithme LRU dans Redis" alt="Un article expliquant en détail lalgorithme LRU dans Redis"></p><p><strong>Pour l'algorithme LRU aléatoire ci-dessus, le responsable de Redis a donné un tableau de données de précision de test : </strong></p>
Dans Redis 3.0, lorsque maxmemory_samples est défini sur 10, l'algorithme LRU approximatif de Redis est très proche du véritable algorithme LRU, mais définir évidemment maxmemory_samples sur 10 consomme plus de CPU que le paramètre maxmemory_samples à 5 Temps de calcul, étant donné que les données d'échantillonnage échantillonnées à chaque fois augmentent, le temps de calcul augmentera également.
L'algorithme LRU de Redis3.0 est plus précis que l'algorithme LRU de Redis2.8
, car Redis3.0 ajoute un pool d'élimination de la même taille que maxmemory_samples. Chaque fois qu'une clé est éliminée, elle est d'abord comparée à la clé. pool d'élimination en attente d'élimination. Les clés sont comparées, et la clé la plus ancienne est finalement éliminée. En fait, les clés sélectionnées pour l'élimination sont rassemblées et comparées à nouveau, et la clé la plus ancienne est éliminée. 6. Il y a des problèmes
Pour plus de connaissances liées à la programmation, veuillez visiter :
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!