Cet article vous apporte des connaissances pertinentes sur Redis, qui présente principalement les problèmes liés aux événements de fichier et aux événements temporels. Les événements de fichier sont l'abstraction des opérations de socket par le serveur, et les événements temporels sont le timing de ces opérations par le serveur. L'abstraction des opérations, j'espère qu'elle sera utile à tout le monde.
Apprentissage recommandé : Tutoriel Redis
Redis était mono-thread avant la version 6.0. Après la version 6.0, vous pouvez activer le multi-threading via le fichier de configuration. Le multi-threading après la version 6.0 fait référence à l'utilisation du multi-threading dans. io pour exécuter.
Le processeur d'événements de fichier est composé de quatre parties : le socket, le multiplexeur d'E/S, le répartiteur d'événements de fichier et le processeur d'événements.
Le multiplexeur d'E/S est chargé d'écouter plusieurs sockets et de transmettre les sockets qui ont généré des événements au répartiteur d'événements de fichier. Bien que plusieurs événements de fichier puissent se produire simultanément, un seul multiplexeur d'E/S placera toujours les sockets de tous les événements générés dans une file d'attente, puis utilisera cette file d'attente pour trier et synchroniser. Le socket de livraison est envoyé à l'événement de fichier, un socket à la fois. . Lorsque l'événement généré par le socket précédent est traité (le traitement des événements associé au socket est terminé), le multiplexeur d'E/S continue de transmettre le socket suivant au répartiteur d'événements de fichier. Le répartiteur d'événements de fichier reçoit le socket du I. /O multiplexeur et utilise le gestionnaire d'événements correspondant en fonction du type d'événement généré par le socket. Le serveur exécutera différentes associations de sockets pour différents gestionnaires d'événements, ces gestionnaires définissent les actions que le serveur doit effectuer lorsqu'un événement se produit.
Toutes les fonctions du programme de multiplexage de Redis sont implémentées en empaquetant des bibliothèques de fonctions de multiplexage d'E/S telles que select, epoll, evport et kqueue
événement AE_READABLE.
Lorsque le socket devient lisible (le client effectue une opération d'écriture ou de fermeture) ou lorsqu'un nouveau socket pouvant répondre apparaît, le socket générera un événement AE_READABLE.
Événement AE_WAITABLE
Lorsque le socket devient accessible en écriture (le client effectue une opération de lecture), l'événement AE_WAITABLE sera généré
Le multiplexeur d'E/S écoutera à la fois l'événement AE_READABLE et l'événement AE_WAITABLE Si un socket Si ceux-ci. deux événements se produisent en même temps, le répartiteur d'événements donnera la priorité à l'événement AE_READABLE, ce qui signifie que le serveur lira d'abord le socket puis écrira le socket.
Tout d'abord, le client Redis initie une connexion au serveur, puis le socket d'écoute générera un événement AE_READABEL, déclenchant l'exécution du processeur de réponse de connexion, et le processeur répondra à la connexion du client Répondez à la demande, puis créez un socket client et un statut client, et associez l'événement AE_REAADABEL du socket client au processeur de demande de commande afin que le client puisse envoyer une demande de commande au serveur principal.
Plus tard, en supposant que le client envoie une demande de commande au serveur principal, le socket client générera un événement AE_READABEL, déclenchant l'exécution du processeur de demande de commande. Le processeur lit la commande du client puis la transmet au programme associé pour exécution. .
L'exécution de la commande générera une réponse de commande correspondante. Afin de transmettre cette ligne de réponse de commande au client, le serveur associera l'événement AE_WAITABLE au processeur de réponse de commande. Lorsque le client essaie de lire la réponse à la commande, le client génère un événement AE_WAITABLE, déclenchant l'exécution du processeur de réponse à la commande. Une fois que le processeur de réponse à la commande écrit la réponse à la commande sur le socket dans l'ensemble du serveur, le serveur libère le client. socket L'événement AE_WAITABLE est associé à l'exécution du gestionnaire de réponse de commande.
Le fait qu'un événement temporel soit un événement chronométré ou un événement périodique dépend de la valeur de retour du processeur d'événements temporels. Si le processeur d'événements renvoie ae.h/AE_NOMORE, alors cet événement est un événement chronométré et l'événement sera. traité après son arrivée une fois, supprimé et ne plus jamais arriver. Si le gestionnaire d'événements renvoie une valeur entière autre que AE_NOMORE, alors l'événement est un événement périodique. Lorsqu'un événement temporel est atteint, le serveur mettra à jour l'attribut when de l'événement en fonction de la valeur de retour du gestionnaire d'événements, de sorte que le l'événement continuera pendant un certain temps. Il arrive à nouveau après un certain temps et est mis à jour et exécuté de cette manière.
Le serveur place tous les événements temporels dans une liste chaînée non ordonnée (Unordered ne fait pas référence au champ id, mais au champ when, donc toute la liste chaînée doit être parcourue à chaque fois. ), à chaque fois Lorsque le Lorsque l'exécuteur d'événements s'exécute, il parcourra toute la liste chaînée, trouvera tous les événements arrivés et appellera le gestionnaire d'événements correspondant.
Ce qu'il faut expliquer ici, c'est que bien qu'il s'agisse d'une liste chaînée non ordonnée, parce que la longueur de la liste chaînée n'est pas très longue, en mode normal, le serveur Redis n'utilise serverCron que comme événement temporel, donc cet endroit dégénérera en rôle des pointeurs, et en mode benchmark, le serveur n'utilise que deux événements temporels, de sorte que l'impact sur les performances d'une traversée complète est négligeable.
Un serveur Redis exécuté en continu doit vérifier et ajuster régulièrement ses propres ressources et son statut pour garantir que le serveur peut fonctionner à long terme et de manière stable. Ces opérations régulières sont effectuées par la fonction redis.c/serverCron. fonction principale Les emplois incluent :
Comme il existe deux types d'événements, les événements de fichier et les événements temporels, dans le serveur, le serveur doit planifier ces deux événements et décider quand l'événement de fichier doit être traité et quand l'heure doit être traitée. événements, et combien de temps est consacré à leur gestion, etc.
Le pseudo code du processus de traitement est le suivant :
def aeProcessEvents(): # 获取到达时间离当前最近的时间事件 tem_event = aeSearchNearestTimer() # 计算上一步获得到的事件 距离到达还有多少秒 remaind_ms = time_event.when - unix_ts_now() # 如果事件已经到达, 那么remaind_ms的值可能为负数,设置为0 remaind_ms = max(remaind_ms, 0) # 阻塞并等待文件事件产生,最大阻塞时间由timeval结构决定, # 如果remaind_ms的值为0,那么aeAPiPoll调用之后马上返回,不阻塞 aeApiPoll(timeval) # 处理所有已经产生的文件事件 processFileEvents() # 处理所有已经到达的时间事件 proccessTimeEvents()
Règles de planification et d'exécution des événements :
1) Le temps de blocage maximum de la fonction aeApiPoll est déterminé par l'événement temporel dont l'heure d'arrivée est la plus proche de l'heure actuelle. peut éviter que le serveur traite fréquemment des événements temporels. L'interrogation (attente occupée) peut également garantir que la fonction aeApiPoll ne se bloquera pas trop longtemps.
2) Étant donné que les événements de fichier apparaissent de manière aléatoire, si aucun événement temporel n'arrive après l'attente et le traitement d'un événement de fichier, le serveur attendra et traitera à nouveau l'événement de fichier. Au fur et à mesure que l'événement de fichier continue d'être exécuté, l'heure se rapprochera progressivement de l'heure d'arrivée définie par l'événement d'heure, et atteindra finalement l'heure d'arrivée. À ce moment, le serveur peut commencer à traiter l'événement d'heure d'arrivée.
3) Le traitement des événements de fichier et des événements temporels est exécuté de manière synchrone, ordonnée et atomique. Le serveur n'interrompra pas le traitement des événements à mi-chemin et ne préemptera pas les événements. Par conséquent, quel que soit le processeur des événements de fichier, ils sont également temporels. processeurs d'événements. Ils minimiseront le temps de blocage du programme et abandonneront activement les droits d'exécution lorsque cela est nécessaire, réduisant ainsi la possibilité de famine d'événements. Par exemple, lorsque le processeur de réponse de commande écrit une réponse de commande sur le socket client, si le nombre d'octets écrits dépasse une constante prédéfinie, le processeur de réponse de commande utilisera activement break pour sortir de la boucle d'écriture et laisser les données restantes en place. écrit la prochaine fois ; de plus, les événements temporels placeront également des opérations de persistance très chronophages dans des sous-threads ou des sous-processus pour exécution.
4) Étant donné que l'événement temporel est exécuté après l'événement fichier et qu'il n'y a pas de préemption entre les événements, le temps de traitement réel de l'événement temporel est généralement légèrement postérieur à l'heure d'arrivée définie par l'événement temporel.
Il existe une relation de coopération entre les événements de fichier et les événements temporels. Le serveur gérera ces deux événements tour à tour, et il n'y aura aucune préemption lors du traitement des événements. Le temps de traitement réel des événements temporels est généralement postérieur à l'heure d'arrivée définie.
Apprentissage recommandé : Tutoriel d'apprentissage 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!