recherche
Maisonbase de donnéesRedisExplication détaillée de la stratégie d'élimination des données Redis

Explication détaillée de la stratégie d'élimination des données Redis

Ce dont parle cet article, c'est qu'après que Redis ait défini la mémoire maximale, la taille de l'ensemble de données dans le cache dépasse une certaine proportion et la stratégie d'élimination mise en œuvre n'est pas la stratégie de suppression des clés expirées Bien que les deux soient très similaires. (Recommandé : Tutoriel vidéo Redis)

Dans Redis, les utilisateurs sont autorisés à définir la taille maximale de la mémoire En configurant la valeur maxmemory dans redis.conf, la fonction d'élimination de la mémoire est activée. la limite de mémoire, c'est très utile dans les situations.

La définition de la taille maximale de la mémoire peut garantir que Redis fournit des services stables au monde extérieur.

Lorsque la taille de l'ensemble de données de la mémoire Redis augmente jusqu'à une certaine taille, la stratégie d'élimination des données sera mise en œuvre. Redis propose 6 stratégies d'élimination de données via la stratégie de définition de stratégie maxmemory :

volatile-lru : sélectionnez les données les moins récemment utilisées dans l'ensemble de données (server.db[i].expires) avec un délai d'expiration défini pour l'élimination.

volatile-ttl : sélectionnez les données à expirer dans l'ensemble de données (server.db[i].expires) avec un délai d'expiration défini et éliminez-les

volatile-random : éliminez le données avec un délai d'expiration défini Sélectionnez toutes les données de l'ensemble de données (server.db[i].expires) pour élimination

allkeys-lru : sélectionnez les données les moins récemment utilisées de l'ensemble de données (server.db[ i].dict) pour élimination

allkeys-random : sélectionner arbitrairement des données dans l'ensemble de données (server.db[i].dict) pour éliminer

no-enviction (eviction) : interdire l'expulsion des données

redis Une fois qu'il est déterminé à expulser une paire clé-valeur, les données seront supprimées et le message de modification des données sera publié sur le local (persistance AOF) et l'esclave (connexion maître-esclave )

Mécanisme d'élimination des données LRU

Le compteur lru server.lrulock est enregistré dans la configuration du serveur et sera mis à jour régulièrement (programme de minuterie redis serverCorn()). la valeur de server.lrulock est calculée en fonction de server.unixtime.

De plus, on peut trouver à partir de struct redisObject que chaque objet redis définira le lru correspondant. Il est concevable que redisObject.lru soit mis à jour à chaque accès aux données.

Le mécanisme d'élimination des données LRU est le suivant : sélectionnez au hasard plusieurs paires clé-valeur dans l'ensemble de données, retirez la paire clé-valeur avec le plus grand lru et éliminez-les. Par conséquent, vous constaterez que redis ne garantit pas l'obtention des paires clé-valeur les moins récemment utilisées (LRU) dans tous les ensembles de données, mais seulement quelques paires clé-valeur sélectionnées au hasard.

// redisServer 保存了 lru 计数器
struct redisServer {
...
unsigned lruclock:22; /* Clock incrementing every minute, for LRU */
...
};
// 每一个 redis 对象都保存了 lru
#define REDIS_LRU_CLOCK_MAX ((1<<21)-1) /* Max value of obj->lru */
#define REDIS_LRU_CLOCK_RESOLUTION 10 /* LRU clock resolution in seconds */
typedef struct redisObject {
// 刚刚好 32 bits
// 对象的类型,字符串/列表/集合/哈希表
unsigned type:4;
// 未使用的两个位
unsigned notused:2; /* Not used */
// 编码的方式,redis 为了节省空间,提供多种方式来保存一个数据
// 譬如:“123456789” 会被存储为整数 123456789
unsigned encoding:4;
unsigned lru:22; /* lru time (relative to server.lruclock) */
// 引用数
int refcount;
// 数据指针
void *ptr;

} robj;
// redis 定时执行程序。联想:linux cron
int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
......
/* We have just 22 bits per object for LRU information.
* So we use an (eventually wrapping) LRU clock with 10 seconds resolution.
* 2^22 bits with 10 seconds resolution is more or less 1.5 years.
*
* Note that even if this will wrap after 1.5 years it&#39;s not a problem,
* everything will still work but just some object will appear younger
* to Redis. But for this to happen a given object should never be touched
* for 1.5 years.
*
* Note that you can change the resolution altering the
* REDIS_LRU_CLOCK_RESOLUTION define.

*/
updateLRUClock();
......
}
// 更新服务器的 lru 计数器
void updateLRUClock(void) {
server.lruclock = (server.unixtime/REDIS_LRU_CLOCK_RESOLUTION) &
REDIS_LRU_CLOCK_MAX;
}

Mécanisme d'élimination des données TTL

La structure de données de l'ensemble de données Redis stocke la table de délai d'expiration de la paire clé-valeur, c'est-à-dire redisDb.expires. Semblable au mécanisme d'élimination des données LRU, le mécanisme d'élimination des données TTL est le suivant : sélectionnez au hasard plusieurs paires clé-valeur dans le tableau des délais d'expiration, supprimez la paire clé-valeur avec le ttl le plus grand et éliminez-les.

De même, vous constaterez que redis n'est pas garanti d'obtenir les paires clé-valeur expirant le plus rapidement dans tous les tableaux de délais d'expiration, mais seulement quelques paires clé-valeur sélectionnées au hasard.

Résumé

Lorsque redis exécute une commande sur le client de service, il détectera si la mémoire utilisée est excessive. Si elle dépasse la limite, les données seront éliminées.

// 执行命令
int processCommand(redisClient *c) {
......
// 内存超额
/* Handle the maxmemory directive.
*
* First we try to free some memory if possible (if there are volatile
* keys in the dataset). If there are not the only thing we can do
* is returning an error. */
if (server.maxmemory) {
int retval = freeMemoryIfNeeded();
if ((c->cmd->flags & REDIS_CMD_DENYOOM) && retval == REDIS_ERR) {
flagTransaction(c);
addReply(c, shared.oomerr);
return REDIS_OK;
}
}
......
}
// 如果需要,是否一些内存
int freeMemoryIfNeeded(void) {
size_t mem_used, mem_tofree, mem_freed;
int slaves = listLength(server.slaves);
// redis 从机回复空间和 AOF 内存大小不计算入 redis 内存大小
/* Remove the size of slaves output buffers and AOF buffer from the
* count of used memory. */
mem_used = zmalloc_used_memory();
// 从机回复空间大小
if (slaves) {
listIter li;
listNode *ln;
listRewind(server.slaves,&li);
while((ln = listNext(&li))) {
redisClient *slave = listNodeValue(ln);
unsigned long obuf_bytes = getClientOutputBufferMemoryUsage(slave);
if (obuf_bytes > mem_used)
mem_used = 0;
else
mem_used -= obuf_bytes;
}
}
// server.aof_buf && server.aof_rewrite_buf_blocks
if (server.aof_state != REDIS_AOF_OFF) {
mem_used -= sdslen(server.aof_buf);
mem_used -= aofRewriteBufferSize();
}
// 内存是否超过设置大小
/* Check if we are over the memory limit. */
if (mem_used <= server.maxmemory) return REDIS_OK;
// redis 中可以设置内存超额策略
if (server.maxmemory_policy == REDIS_MAXMEMORY_NO_EVICTION)
return REDIS_ERR; /* We need to free memory, but policy forbids. */
/* Compute how much memory we need to free. */
mem_tofree = mem_used - server.maxmemory;
mem_freed = 0;
while (mem_freed < mem_tofree) {
int j, k, keys_freed = 0;
// 遍历所有数据集
for (j = 0; j < server.dbnum; j++) {
long bestval = 0; /* just to prevent warning */
sds bestkey = NULL;
struct dictEntry *de;
redisDb *db = server.db+j;
dict *dict;
// 不同的策略,选择的数据集不一样
if (server.maxmemory_policy == REDIS_MAXMEMORY_ALLKEYS_LRU ||
server.maxmemory_policy == REDIS_MAXMEMORY_ALLKEYS_RANDOM
{
dict = server.db[j].dict;
} else {
dict = server.db[j].expires;
}
// 数据集为空,继续下一个数据集
if (dictSize(dict) == 0) continue;
// 随机淘汰随机策略:随机挑选
/* volatile-random and allkeys-random policy */
if (server.maxmemory_policy == REDIS_MAXMEMORY_ALLKEYS_RANDOM ||
server.maxmemory_policy == REDIS_MAXMEMORY_VOLATILE_RANDOM)
{
de = dictGetRandomKey(dict);
bestkey = dictGetKey(de);
}
// LRU 策略:挑选最近最少使用的数据
/* volatile-lru and allkeys-lru policy */
else if (server.maxmemory_policy == REDIS_MAXMEMORY_ALLKEYS_LRU ||
server.maxmemory_policy == REDIS_MAXMEMORY_VOLATILE_LRU)
{
// server.maxmemory_samples 为随机挑选键值对次数
// 随机挑选 server.maxmemory_samples个键值对,驱逐最近最少使用的数据
for (k = 0; k < server.maxmemory_samples; k++) {
sds thiskey;
long thisval;
robj *o;
// 随机挑选键值对
de = dictGetRandomKey(dict); 
// 获取键
thiskey = dictGetKey(de); 
/* When policy is volatile-lru we need an additional lookup
* to locate the real key, as dict is set to db->expires. */
if (server.maxmemory_policy == REDIS_MAXMEMORY_VOLATILE_LRU)
de = dictFind(db->dict, thiskey);
o = dictGetVal(de); 
// 计算数据的空闲时间
thisval = estimateObjectIdleTime(o);
// 当前键值空闲时间更长,则记录
/* Higher idle time is better candidate for deletion */
if (bestkey == NULL || thisval > bestval) {
bestkey = thiskey;
bestval = thisval;
}
}
} 
// TTL 策略:挑选将要过期的数据
/* volatile-ttl */
else if (server.maxmemory_policy == REDIS_MAXMEMORY_VOLATILE_TTL) {
// server.maxmemory_samples 为随机挑选键值对次数
// 随机挑选 server.maxmemory_samples个键值对,驱逐最快要过期的数据
for (k = 0; k < server.maxmemory_samples; k++) {
sds thiskey;
long thisval;
de = dictGetRandomKey(dict);
thiskey = dictGetKey(de);
thisval = (long) dictGetVal(de);
/* Expire sooner (minor expire unix timestamp) is better
* candidate for deletion */
if (bestkey == NULL || thisval < bestval) {
bestkey = thiskey;
bestval = thisval;
}
}
}
// 删除选定的键值对
/* Finally remove the selected key. */
if (bestkey) {
long long delta;
robj *keyobj = createStringObject(bestkey,sdslen(bestkey));
// 发布数据更新消息,主要是 AOF 持久化和从机
propagateExpire(db,keyobj);
// 注意, propagateExpire() 可能会导致内存的分配, propagateExpire()
提前执行就是因为 redis 只计算 dbDelete() 释放的内存大小。倘若同时计算 dbDelete() 释放的内存
和 propagateExpire() 分配空间的大小,与此同时假设分配空间大于释放空间,就有可能永远退不出这个循环。
// 下面的代码会同时计算 dbDelete() 释放的内存和 propagateExpire() 分配空间的大小:
// propagateExpire(db,keyobj);
// delta = (long long) zmalloc_used_memory();
// dbDelete(db,keyobj);
// delta -= (long long) zmalloc_used_memory();
// mem_freed += delta;
/////////////////////////////////////////
/* We compute the amount of memory freed by dbDelete() alone.
* It is possible that actually the memory needed to propagate
* the DEL in AOF and replication link is greater than the one
* we are freeing removing the key, but we can&#39;t account for
* that otherwise we would never exit the loop.
*
* AOF and Output buffer memory will be freed eventually so
* we only care about memory used by the key space. */
// 只计算 dbDelete() 释放内存的大小
delta = (long long) zmalloc_used_memory();
dbDelete(db,keyobj);
delta -= (long long) zmalloc_used_memory();
mem_freed += delta;
server.stat_evictedkeys++;
// 将数据的删除通知所有的订阅客户端
notifyKeyspaceEvent(REDIS_NOTIFY_EVICTED, "evicted",
keyobj, db->id);
decrRefCount(keyobj);
keys_freed++; 
// 将从机回复空间中的数据及时发送给从机
/* When the memory to free starts to be big enough, we may
* start spending so much time here that is impossible to
* deliver data to the slaves fast enough, so we force the
* transmission here inside the loop. */
if (slaves) flushSlavesOutputBuffers();
}
} 
// 未能释放空间,且此时 redis 使用的内存大小依旧超额,失败返回
if (!keys_freed) return REDIS_ERR; /* nothing to free... */
}
return REDIS_OK;
}

Scénarios applicables

Jetons un coup d'œil aux scénarios applicables de plusieurs stratégies :

1. allkeys-lru : Si l'accès de notre application au cache est conforme à un pouvoir. loi de distribution (c'est-à-dire qu'il y a des données relativement chaudes), ou si nous ne sommes pas très clairs sur la distribution d'accès au cache de notre application, nous pouvons choisir la stratégie allkeys-lru.

2. allkeys-random : Si notre application a une probabilité d'accès égale aux clés de cache, nous pouvons utiliser cette stratégie.

3. volatile-ttl : Cette stratégie nous permet d'indiquer à Redis quelles clés sont les plus adaptées à l'expulsion.

De plus, la stratégie volatile-lru et la stratégie volatile-random conviennent lorsque nous utilisons une instance Redis à la fois pour le cache et le stockage persistant. Cependant, nous pouvons également obtenir le même résultat en utilisant deux instances Redis. Il convient de mentionner que la définition du délai d'expiration de la clé consommera en fait plus de mémoire, nous vous recommandons donc d'utiliser la stratégie allkeys-lru pour utiliser la mémoire plus efficacement.

Pour plus de connaissances sur Redis, veuillez faire attention à la colonne Tutoriel d'introduction à 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!

Déclaration
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer
Redis est-il une base de données SQL ou NOSQL? La réponse expliquéeRedis est-il une base de données SQL ou NOSQL? La réponse expliquéeApr 18, 2025 am 12:11 AM

RedisservisifiedasanosqldatabaseBecauseiSeSakey-ValuedatamodelinSteadoftraDtionalrelationDatabasEmodel.itofferseSpeedAndFlexibibit

Redis: améliorer les performances et l'évolutivité des applicationsRedis: améliorer les performances et l'évolutivité des applicationsApr 17, 2025 am 12:16 AM

Redis améliore les performances et l'évolutivité des applications en mettant en cache des données, implémentant le verrouillage distribué et la persistance des données. 1) Données de cache: utilisez Redis pour mettre en cache les données fréquemment accessibles pour améliorer la vitesse d'accès aux données. 2) Verrouillage distribué: utilisez Redis pour implémenter les verrous distribués pour assurer la sécurité du fonctionnement dans un environnement distribué. 3) Persistance des données: assurer la sécurité des données via les mécanismes RDB et AOF pour éviter la perte de données.

Redis: explorer son modèle de données et sa structureRedis: explorer son modèle de données et sa structureApr 16, 2025 am 12:09 AM

Le modèle et la structure de données de Redis incluent cinq types principaux: 1. String: Utilisé pour stocker des données de texte ou binaires et prend en charge les opérations atomiques. 2. Liste: collection d'éléments commandés, adapté aux files d'attente et aux piles. 3. Ensemble: Éléments uniques non ordonnés Ensemble, soutenant le fonctionnement de l'ensemble. 4. Ensemble ordonné (triset): un ensemble unique d'éléments avec des scores, adaptés aux classements. 5. Table du hachage (hachage): une collection de paires de valeurs clés, adaptées au stockage d'objets.

Redis: classifier son approche de base de donnéesRedis: classifier son approche de base de donnéesApr 15, 2025 am 12:06 AM

Les méthodes de base de données de Redis incluent les bases de données en mémoire et le stockage de valeurs de clé. 1) Redis stocke les données en mémoire, lit et écrit rapidement. 2) Il utilise des paires de valeurs clés pour stocker des données, prend en charge des structures de données complexes telles que les listes, les collections, les tables de hachage et les collections ordonnées, adaptées aux caches et aux bases de données NoSQL.

Pourquoi utiliser Redis? Avantages et avantagesPourquoi utiliser Redis? Avantages et avantagesApr 14, 2025 am 12:07 AM

Redis est une puissante solution de base de données car elle offre des performances rapides, de riches structures de données, une haute disponibilité et une évolutivité, des capacités de persistance et un large éventail de support écosystémique. 1) Performances extrêmement rapides: les données de Redis sont stockées en mémoire et ont des vitesses de lecture et d'écriture extrêmement rapides, adaptées aux applications élevées de concurrence et de latence faible. 2) Rich Structure de données: prend en charge plusieurs types de données, tels que des listes, des collections, etc., qui conviennent à une variété de scénarios. 3) Haute disponibilité et évolutivité: prend en charge la réplication maître-esclave et le mode de cluster pour atteindre la haute disponibilité et l'évolutivité horizontale. 4) Persistance et sécurité des données: la persistance des données est obtenue via RDB et AOF pour garantir l'intégrité et la fiabilité des données. 5) Support d'écosystème et communautaire large: avec un énorme écosystème et une communauté active,

Comprendre le nosql: caractéristiques clés de RedisComprendre le nosql: caractéristiques clés de RedisApr 13, 2025 am 12:17 AM

Les caractéristiques clés de Redis incluent la vitesse, la flexibilité et le support de structure de données riche. 1) Speed: Redis est une base de données en mémoire, et les opérations de lecture et d'écriture sont presque instantanées, adaptées à la gestion du cache et de la session. 2) Flexibilité: prend en charge plusieurs structures de données, telles que des chaînes, des listes, des collections, etc., qui conviennent au traitement des données complexes. 3) Prise en charge de la structure des données: fournit des chaînes, des listes, des collections, des tables de hachage, etc., qui conviennent aux différents besoins commerciaux.

Redis: identifier sa fonction principaleRedis: identifier sa fonction principaleApr 12, 2025 am 12:01 AM

La fonction centrale de Redis est un système de stockage et de traitement de données en mémoire haute performance. 1) Accès aux données à grande vitesse: Redis stocke les données en mémoire et fournit une vitesse de lecture et d'écriture au niveau microseconde. 2) Rich Structure de données: prend en charge les chaînes, les listes, les collections, etc., et s'adapte à une variété de scénarios d'application. 3) Persistance: Persister les données sur le disque via RDB et AOF. 4) Publier l'abonnement: peut être utilisé dans les files d'attente de messages ou les systèmes de communication en temps réel.

Redis: un guide des structures de données populairesRedis: un guide des structures de données populairesApr 11, 2025 am 12:04 AM

Redis prend en charge une variété de structures de données, notamment: 1. String, adapté au stockage des données à valeur unique; 2. Liste, adaptée aux files d'attente et aux piles; 3. SET, utilisé pour stocker des données non dégonflées; 4. Ensemble ordonné, adapté aux listes de classement et aux files d'attente de priorité; 5. Table du hachage, adapté au stockage des données d'objet ou structurées.

See all articles

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques moisBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
1 Il y a quelques moisBy尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Vous avez un jeu croisé?
1 Il y a quelques moisBy尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Version Mac de WebStorm

Version Mac de WebStorm

Outils de développement JavaScript utiles

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

Télécharger la version Mac de l'éditeur Atom

Télécharger la version Mac de l'éditeur Atom

L'éditeur open source le plus populaire

DVWA

DVWA

Damn Vulnerable Web App (DVWA) est une application Web PHP/MySQL très vulnérable. Ses principaux objectifs sont d'aider les professionnels de la sécurité à tester leurs compétences et leurs outils dans un environnement juridique, d'aider les développeurs Web à mieux comprendre le processus de sécurisation des applications Web et d'aider les enseignants/étudiants à enseigner/apprendre dans un environnement de classe. Application Web sécurité. L'objectif de DVWA est de mettre en pratique certaines des vulnérabilités Web les plus courantes via une interface simple et directe, avec différents degrés de difficulté. Veuillez noter que ce logiciel

Navigateur d'examen sécurisé

Navigateur d'examen sécurisé

Safe Exam Browser est un environnement de navigation sécurisé permettant de passer des examens en ligne en toute sécurité. Ce logiciel transforme n'importe quel ordinateur en poste de travail sécurisé. Il contrôle l'accès à n'importe quel utilitaire et empêche les étudiants d'utiliser des ressources non autorisées.