redis源代码分析16–阻塞式命令
redis现在只支持对list的阻塞式操作,相关的两个命令是brpop和blpop。 这两个命令在list中有元素时,跟普通的pop没有区别,弹出list的一个元素,然后返回。但在list没有元素时,会为redisClient设置REDIS_BLOCKED标志,然后client阻塞(设置REDIS_BLOCKED标
redis现在只支持对list的阻塞式操作,相关的两个命令是brpop和blpop。
这两个命令在list中有元素时,跟普通的pop没有区别,弹出list的一个元素,然后返回。但在list没有元素时,会为redisClient设置REDIS_BLOCKED标志,然后client阻塞(设置REDIS_BLOCKED标志的redisClient会一直阻塞,参考命令处理章节),一直到新元素加入时(push操作的处理函数pushGenericCommand),才会返回。
这两个命令设置的处理函数brpopCommand和blpopCommand都会调用blockingPopGenericCommand。该函数在检查list中有元素后,会调用非阻塞的popGenericCommand来弹出一个元素,否则调用blockForKeys来处理阻塞的情况。
/* Blocking RPOP/LPOP */ static void blockingPopGenericCommand(redisClient *c, int where) { robj *o; long long lltimeout; time_t timeout; int j; /* Make sure timeout is an integer value */ if (getLongLongFromObjectOrReply(c,c->argv[c->argc-1],&lltimeout, "timeout is not an integer") != REDIS_OK) return; /* Make sure the timeout is not negative */ if (lltimeout argc-1; j++) { o = lookupKeyWrite(c->db,c->argv[j]); if (o != NULL) { if (o->type != REDIS_LIST) { addReply(c,shared.wrongtypeerr); return; } else { list *list = o->ptr; if (listLength(list) != 0) { /* If the list contains elements fall back to the usual * non-blocking POP operation */ robj *argv[2], **orig_argv; int orig_argc; /* We need to alter the command arguments before to call * popGenericCommand() as the command takes a single key. */ orig_argv = c->argv; orig_argc = c->argc; argv[1] = c->argv[j]; c->argv = argv; c->argc = 2; /* Also the return value is different, we need to output * the multi bulk reply header and the key name. The * "real" command will add the last element (the value) * for us. If this souds like an hack to you it's just * because it is... */ addReplySds(c,sdsnew("*2\r\n")); addReplyBulk(c,argv[1]); popGenericCommand(c,where); /* Fix the client structure with the original stuff */ c->argv = orig_argv; c->argc = orig_argc; return; } } } } /* If we are inside a MULTI/EXEC and the list is empty the only thing * we can do is treating it as a timeout (even with timeout 0). */ if (c->flags & REDIS_MULTI) { addReply(c,shared.nullmultibulk); return; } /* If the list is empty or the key does not exists we must block */ timeout = lltimeout; if (timeout > 0) timeout += time(NULL); blockForKeys(c,c->argv+1,c->argc-2,timeout); }
blockForKeys会在db->blockingkeys记下client和等待的key的对应关系,然后给client设置REDIS_BLOCKED标志,这样client就一直阻塞了。
static void blockForKeys(redisClient *c, robj **keys, int numkeys, time_t timeout) { dictEntry *de; list *l; int j; --- if (c->fd blockingkeys = zmalloc(sizeof(robj*)*numkeys); c->blockingkeysnum = numkeys; c->blockingto = timeout; for (j = 0; j keys */ c->blockingkeys[j] = keys[j]; incrRefCount(keys[j]); /* And in the other "side", to map keys -> clients */ de = dictFind(c->db->blockingkeys,keys[j]); if (de == NULL) { int retval; /* For every key we take a list of clients blocked for it */ l = listCreate(); retval = dictAdd(c->db->blockingkeys,keys[j],l); incrRefCount(keys[j]); assert(retval == DICT_OK); } else { l = dictGetEntryVal(de); } listAddNodeTail(l,c); } /* Mark the client as a blocked client */ c->flags |= REDIS_BLOCKED; server.blpop_blocked_clients++; }
等待的client会一直阻塞,直到有push操作,此时会调用unblockClientWaitingData来解除client的阻塞。
/* Unblock a client that's waiting in a blocking operation such as BLPOP */ // 减少对所阻塞对象的引用 static void unblockClientWaitingData(redisClient *c) { dictEntry *de; list *l; int j; assert(c->blockingkeys != NULL); /* The client may wait for multiple keys, so unblock it for every key. */ for (j = 0; j blockingkeysnum; j++) { /* Remove this client from the list of clients waiting for this key. */ de = dictFind(c->db->blockingkeys,c->blockingkeys[j]); assert(de != NULL); l = dictGetEntryVal(de); listDelNode(l,listSearchKey(l,c)); /* If the list is empty we need to remove it to avoid wasting memory */ if (listLength(l) == 0) dictDelete(c->db->blockingkeys,c->blockingkeys[j]); decrRefCount(c->blockingkeys[j]); } /* Cleanup the client structure */ zfree(c->blockingkeys); c->blockingkeys = NULL; c->flags &= (~REDIS_BLOCKED); server.blpop_blocked_clients--; /* We want to process data if there is some command waiting * in the input buffer. Note that this is safe even if * unblockClientWaitingData() gets called from freeClient() because * freeClient() will be smart enough to call this function * *after* c->querybuf was set to NULL. */ if (c->querybuf && sdslen(c->querybuf) > 0) processInputBuffer(c); }
原文地址:redis源代码分析16–阻塞式命令, 感谢原作者分享。

Outils d'IA chauds

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

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

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

1. Démarrez le menu [Démarrer], entrez [cmd], cliquez avec le bouton droit sur [Invite de commandes] et sélectionnez Exécuter en tant qu'[Administrateur]. 2. Entrez les commandes suivantes dans l'ordre (copiez et collez soigneusement) : SCconfigwuauservstart=auto, appuyez sur Entrée SCconfigbitsstart=auto, appuyez sur Entrée SCconfigcryptsvcstart=auto, appuyez sur Entrée SCconfigtrustedinstallerstart=auto, appuyez sur Entrée SCconfigwuauservtype=share, appuyez sur Entrée netstopwuauserv , appuyez sur Entrée netstopcryptS.

Les goulots d'étranglement des fonctions PHP entraînent de faibles performances, qui peuvent être résolues en suivant les étapes suivantes : localisez la fonction de goulot d'étranglement et utilisez des outils d'analyse des performances. Mise en cache des résultats pour réduire les recalculs. Traitez les tâches en parallèle pour améliorer l’efficacité de l’exécution. Optimisez la concaténation des chaînes, utilisez plutôt les fonctions intégrées. Utilisez des fonctions intégrées au lieu de fonctions personnalisées.

La stratégie de mise en cache dans GolangAPI peut améliorer les performances et réduire la charge du serveur. Les stratégies couramment utilisées sont : LRU, LFU, FIFO et TTL. Les techniques d'optimisation incluent la sélection du stockage de cache approprié, la mise en cache hiérarchique, la gestion des invalidations, ainsi que la surveillance et le réglage. Dans le cas pratique, le cache LRU est utilisé pour optimiser l'API pour obtenir des informations utilisateur à partir de la base de données. Les données peuvent être rapidement récupérées du cache. Sinon, le cache peut être mis à jour après l'avoir obtenu à partir de la base de données.

Dans le développement PHP, le mécanisme de mise en cache améliore les performances en stockant temporairement les données fréquemment consultées en mémoire ou sur disque, réduisant ainsi le nombre d'accès à la base de données. Les types de cache incluent principalement le cache de mémoire, de fichiers et de bases de données. En PHP, vous pouvez utiliser des fonctions intégrées ou des bibliothèques tierces pour implémenter la mise en cache, telles que cache_get() et Memcache. Les applications pratiques courantes incluent la mise en cache des résultats des requêtes de base de données pour optimiser les performances des requêtes et la mise en cache de la sortie des pages pour accélérer le rendu. Le mécanisme de mise en cache améliore efficacement la vitesse de réponse du site Web, améliore l'expérience utilisateur et réduit la charge du serveur.

L'utilisation du cache Redis peut considérablement optimiser les performances de la pagination du tableau PHP. Cela peut être réalisé en suivant les étapes suivantes : Installez le client Redis. Connectez-vous au serveur Redis. Créez des données de cache et stockez chaque page de données dans un hachage Redis avec la clé « page : {page_number} ». Récupérez les données du cache et évitez les opérations coûteuses sur les grandes baies.

Vous devez d’abord définir la langue du système sur l’affichage chinois simplifié et redémarrer. Bien sûr, si vous avez déjà modifié la langue d'affichage en chinois simplifié, vous pouvez simplement ignorer cette étape. Ensuite, commencez à utiliser le registre, regedit.exe, accédez directement à HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlNlsLanguage dans la barre de navigation de gauche ou dans la barre d'adresse supérieure, puis modifiez la valeur de la clé InstallLanguage et la valeur de la clé par défaut sur 0804 (si vous souhaitez la changer en anglais en- nous, vous devez d'abord définir la langue d'affichage du système sur en-us, redémarrer le système, puis tout changer en 0409). Vous devez redémarrer le système à ce stade.

Oui, Navicat peut se connecter à Redis, ce qui permet aux utilisateurs de gérer les clés, d'afficher les valeurs, d'exécuter des commandes, de surveiller l'activité et de diagnostiquer les problèmes. Pour vous connecter à Redis, sélectionnez le type de connexion « Redis » dans Navicat et saisissez les détails du serveur.

1. Tout d'abord, double-cliquez sur l'icône [Ce PC] sur le bureau pour l'ouvrir. 2. Double-cliquez ensuite sur le bouton gauche de la souris pour accéder à [Lecteur C]. Les fichiers système seront généralement automatiquement stockés dans le lecteur C. 3. Recherchez ensuite le dossier [windows] dans le lecteur C et double-cliquez pour entrer. 4. Après avoir accédé au dossier [windows], recherchez le dossier [SoftwareDistribution]. 5. Après avoir entré, recherchez le dossier [télécharger], qui contient tous les fichiers de téléchargement et de mise à jour Win11. 6. Si nous souhaitons supprimer ces fichiers, supprimez-les simplement directement dans ce dossier.
