Quel est le processus de traitement des requêtes Redis ?
Présentation#
La première chose est d'enregistrer le processeur ;
Ouvrez le port d'écoute en boucle, et une Goroutine sera créée à chaque fois qu'une connexion est surveillée
Ensuite, la Goroutine attendra dans un boucle pour recevoir les données de la demande, puis faire correspondre le processeur correspondant dans la table de routage du processeur en fonction de l'adresse demandée, puis transmettre la demande au processeur pour traitement
exprimé en code est comme ceci :
func (srv *Server) Serve(l net.Listener) error { ... baseCtx := context.Background() ctx := context.WithValue(baseCtx, ServerContextKey, srv) for { // 接收 listener 过来的网络连接 rw, err := l.Accept() ... tempDelay = 0 c := srv.newConn(rw) c.setState(c.rwc, StateNew) // 创建协程处理连接 go c.serve(connCtx) } }
Il ; est un peu différent pour Redis, car il est monothread et ne peut pas utiliser le multithreading pour traiter les connexions, donc Redis choisit d'utiliser un pilote d'événement basé sur le mode Reactor pour implémenter le traitement simultané des événements.
Le mode dit Reactor dans Redis consiste à surveiller plusieurs fds via epoll Chaque fois que ces fds répondent, epoll sera notifié sous la forme d'événements pour les rappels. Chaque événement a un gestionnaire d'événements correspondant.
Par exemple : accept correspond au gestionnaire d'événements acceptTCPHandler, read & write correspond au gestionnaire d'événements readQueryFromClient, etc., puis l'événement est attribué au processeur d'événements pour être traité via la répartition de la boucle d'événements.
Donc, le mode Reactor ci-dessus est implémenté via epoll. Pour epoll, il existe principalement trois méthodes :
//创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大 int epoll_create(int size); /* * 可以理解为,增删改 fd 需要监听的事件 * epfd 是 epoll_create() 创建的句柄。 * op 表示 增删改 * epoll_event 表示需要监听的事件,Redis 只用到了可读,可写,错误,挂断 四个状态 */ int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); /* * 可以理解为查询符合条件的事件 * epfd 是 epoll_create() 创建的句柄。 * epoll_event 用来存放从内核得到事件的集合 * maxevents 获取的最大事件数 * timeout 等待超时时间 */ int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
Nous pouvons donc implémenter un serveur simple basé sur ces trois méthodes :
// 创建监听 int listenfd = ::socket(); // 绑定ip和端口 int r = ::bind(); // 创建 epoll 实例 int epollfd = epoll_create(xxx); // 添加epoll要监听的事件类型 int r = epoll_ctl(..., listenfd, ...); struct epoll_event* alive_events = static_cast<epoll_event*>(calloc(kMaxEvents, sizeof(epoll_event))); while (true) { // 等待事件 int num = epoll_wait(epollfd, alive_events, kMaxEvents, kEpollWaitTime); // 遍历事件,并进行事件处理 for (int i = 0; i < num; ++i) { int fd = alive_events[i].data.fd; // 获取事件 int events = alive_events[i].events; // 进行事件的分发 if ( (events & EPOLLERR) || (events & EPOLLHUP) ) { ... } else if (events & EPOLLRDHUP) { ... } ... } }
Processus d'appel #
Donc, basé sur ce qui précède. introduction, vous pouvez savoir que pour Redis, une boucle d'événements n'est rien de plus que quelques étapes :
Enregistrer les fonctions d'écoute et de rappel des événements
Boucle en attente pour obtenir les événements et les traiter ; fonction de rappel pour traiter la logique des données ;
Réécrire les données au client ;
Enregistrez fd sur epoll et définissez la fonction de rappel acceptTcpHandler. être appelé ;
Démarrez une boucle infinie pour appeler epoll_wait pour attendre et continuer à traiter l'événement. Plus tard, nous reviendrons à la fonction aeMain pour boucler la fonction aeProcessEvents
Lorsqu'un événement réseau survient, la fonction de rappel ; acceptTcpHandler sera appelé jusqu'au bout. readQueryFromClient traitera les données. readQueryFromClient analysera les données client et trouvera la fonction cmd correspondante à exécuter
Après avoir reçu la demande du client, l'instance Redis traitera la commande client et écrira les données renvoyées ; au tampon de sortie du client au lieu de revenir immédiatement ;
Ensuite, la fonction beforeSleep est appelée à chaque fois que la fonction aeMain boucle pour réécrire les données dans le tampon au client
L'ensemble du processus de boucle d'événement ci-dessus est ; en fait, le code Les étapes ont été écrites très clairement, et il existe de nombreux articles sur Internet à ce sujet, donc je n'entrerai pas dans les détails.
Processus d'exécution de commande et client de réécriture#
Exécution de commande#
Parlons maintenant de quelque chose que de nombreux articles sur Internet n'ont pas mentionné. Voyons comment Redis exécute la commande, puis la stocke dans le cache et écrit. les données du cache. Retour au processus Client.
Nous avons également mentionné dans la section précédente que si un événement réseau survient, la fonction readQueryFromClient sera appelée, c'est là que la commande est réellement exécutée. Nous allons suivre cette méthode et regarder en bas :readQueryFromClient appellera la fonction processInputBufferAndReplicate pour traiter la commande demandée ;
Dans la fonction processInputBufferAndReplicate sera appelée et déterminera s'il est nécessaire d'utiliser le mode cluster. la commande est copiée sur d'autres nœuds ; la fonction
processInputBuffer traitera la commande demandée dans une boucle et appellera la fonction processInlineBuffer selon le protocole demandé, puis appellera processCommand pour exécuter la commande après l'objet redisObject ;
processCommand passera lors de l'exécution de la commande. lookupCommand va dans la tableserver.commands
pour trouver la fonction d'exécution correspondante en fonction de la commande, puis après une série de vérifications, appelle la fonction correspondante pour exécuter la commande. et appelle addReply pour écrire les données renvoyées dans la zone de tampon de sortie du client ;server.commands
enregistrera toutes les commandes Redis dans la fonction populateCommandTable en tant que table qui obtient les fonctions de commande basées sur. le nom de la commande.- Par exemple, pour exécuter la commande get, la fonction getCommand sera appelée :
void getCommand(client *c) { getGenericCommand(c); } int getGenericCommand(client *c) { robj *o; // 查找数据 if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL) return C_OK; ... } robj *lookupKeyReadOrReply(client *c, robj *key, robj *reply) { //到db中查找数据 robj *o = lookupKeyRead(c->db, key); // 写入到缓存中 if (!o) addReply(c,reply); return o; }
Copier après la connexionserver.commands
表中根据命令查找对应的执行函数,然后经过一系列的校验之后,调用相应的函数执行命令,调用 addReply 将要返回的数据写入客户端输出缓冲区;server.commands
Recherchez les données dans la fonction getCommand, puis appelez addReply pour écrire les données renvoyées dans le tampon de sortie client.Réécriture des données sur le client#
Après avoir écrit la commande dans le tampon, les données doivent être retirées du tampon et renvoyées au client. Pour le processus de réécriture des données vers le client, il est en fait terminé dans la boucle d'événements du serveur.
Tout d'abord, Redis appellera la fonction aeSetBeforeSleepProc dans la fonction principale pour enregistrer la fonction beforeSleep du package writeback dans eventLoop
Ensuite, Redis déterminera si beforesleep existe lors de l'appel de la fonction aeMain pour ; la boucle d'événement. est définie, si elle existe, elle sera appelée ; la fonction
beforesleep appellera la fonction handleClientsWithPendingWrites, qui appellera writeToClient pour réécrire les données sur le client à partir du tampon.
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!

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

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

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)

Le mode Redis Cluster déploie les instances Redis sur plusieurs serveurs grâce à la rupture, à l'amélioration de l'évolutivité et de la disponibilité. Les étapes de construction sont les suivantes: Créez des instances de redis étranges avec différents ports; Créer 3 instances Sentinel, Moniteur Redis Instances et basculement; Configurer les fichiers de configuration Sentinel, ajouter des informations d'instance Redis de surveillance et des paramètres de basculement; Configurer les fichiers de configuration d'instance Redis, activer le mode de cluster et spécifier le chemin du fichier d'informations de cluster; Créer un fichier nœuds.conf, contenant des informations de chaque instance redis; Démarrez le cluster, exécutez la commande CREATE pour créer un cluster et spécifiez le nombre de répliques; Connectez-vous au cluster pour exécuter la commande d'informations de cluster pour vérifier l'état du cluster; faire

Comment effacer les données Redis: utilisez la commande flushall pour effacer toutes les valeurs de clé. Utilisez la commande flushdb pour effacer la valeur clé de la base de données actuellement sélectionnée. Utilisez SELECT pour commuter les bases de données, puis utilisez FlushDB pour effacer plusieurs bases de données. Utilisez la commande del pour supprimer une clé spécifique. Utilisez l'outil Redis-CLI pour effacer les données.

Pour lire une file d'attente à partir de Redis, vous devez obtenir le nom de la file d'attente, lire les éléments à l'aide de la commande LPOP et traiter la file d'attente vide. Les étapes spécifiques sont les suivantes: Obtenez le nom de la file d'attente: Nommez-le avec le préfixe de "Fitre:" tel que "Fitre: My-Quyue". Utilisez la commande LPOP: éjectez l'élément de la tête de la file d'attente et renvoyez sa valeur, telle que la file d'attente LPOP: My-Queue. Traitement des files d'attente vides: si la file d'attente est vide, LPOP renvoie NIL et vous pouvez vérifier si la file d'attente existe avant de lire l'élément.

L'utilisation de la directive Redis nécessite les étapes suivantes: Ouvrez le client Redis. Entrez la commande (Verbe Key Value). Fournit les paramètres requis (varie de l'instruction à l'instruction). Appuyez sur Entrée pour exécuter la commande. Redis renvoie une réponse indiquant le résultat de l'opération (généralement OK ou -err).

L'utilisation des opérations Redis pour verrouiller nécessite l'obtention du verrouillage via la commande setnx, puis en utilisant la commande Expire pour définir le temps d'expiration. Les étapes spécifiques sont les suivantes: (1) Utilisez la commande setnx pour essayer de définir une paire de valeurs de clé; (2) Utilisez la commande Expire pour définir le temps d'expiration du verrou; (3) Utilisez la commande del pour supprimer le verrouillage lorsque le verrouillage n'est plus nécessaire.

La meilleure façon de comprendre le code source redis est d'aller étape par étape: familiarisez-vous avec les bases de Redis. Sélectionnez un module ou une fonction spécifique comme point de départ. Commencez par le point d'entrée du module ou de la fonction et affichez le code ligne par ligne. Affichez le code via la chaîne d'appel de fonction. Familiez les structures de données sous-jacentes utilisées par Redis. Identifiez l'algorithme utilisé par Redis.

Les causes de la perte de données redis incluent les défaillances de mémoire, les pannes de courant, les erreurs humaines et les défaillances matérielles. Les solutions sont: 1. Stockez les données sur le disque avec RDB ou AOF Persistance; 2. Copiez sur plusieurs serveurs pour une haute disponibilité; 3. Ha avec Redis Sentinel ou Redis Cluster; 4. Créez des instantanés pour sauvegarder les données; 5. Mettre en œuvre les meilleures pratiques telles que la persistance, la réplication, les instantanés, la surveillance et les mesures de sécurité.

Utilisez l'outil de ligne de commande redis (Redis-CLI) pour gérer et utiliser Redis via les étapes suivantes: Connectez-vous au serveur, spécifiez l'adresse et le port. Envoyez des commandes au serveur à l'aide du nom et des paramètres de commande. Utilisez la commande d'aide pour afficher les informations d'aide pour une commande spécifique. Utilisez la commande QUIT pour quitter l'outil de ligne de commande.
