Redis Pubsub et le Message Queueing
Ma question est: Utilisation de Redis pour PubSub, qu'advient-il des messages quand les éditeurs envoient des messages dans un canal plus vite que les abonnés sont en mesure de les lire?
Par exemple, disons que j'ai:
- Un simple éditeur de la publication des messages au taux de 2 msg/sec.
- Un simple abonné à la lecture des messages au taux de 1 msg/sec.
Mon hypothèse naïve serait l'abonné ne pourrait voir que 50% des messages publiés sur le Redis. Pour tester cette théorie, j'ai écrit deux scripts:
pub.py
queue = redis.StrictRedis(host='localhost', port=6379, db=0)
channel = queue.pubsub()
for i in range(10):
queue.publish("test", i)
time.sleep(0.5)
sub.py
r = redis.StrictRedis(host='localhost', port=6379, db=0)
p = r.pubsub()
p.subscribe('test')
while True:
message = p.get_message()
if message:
print "Subscriber: %s" % message['data']
time.sleep(1)
Résultats
- Quand j'ai couru
sub.py
d'abord, immédiatement suivie parpub.py
, j'ai trouvé quesub.py
affiche tous les messages (1-10), l'un après l'autre avec un délai de 1 seconde entre les deux. Mon hypothèse de départ était fausse, Redis est de files d'attente de messages. Plus de tests nécessaires. - Quand j'ai couru
pub.py
d'abord, puis attendu 5 secondes avant d'exécutersub.py
, j'ai trouvé quesub.py
ne s'affiche de la deuxième moitié des messages (5-10). J'aurais cru au départ, mais compte tenu de mes résultats précédents, j'aurais pensé que les messages ont été mis en file d'attente, ce qui m'a amené à la conclusion suivante...
Conclusions
- Redis serveur apparaît à la file d'attente de messages pour chaque client, pour chaque canal.
- Aussi longtemps que le client est à l'écoute, il n'a pas d'importance à quelle vitesse il lit les messages. Tant qu'il est connecté, les messages restent en file d'attente pour le client, pour ce canal.
Autres Questions
- Ces conclusions sont-elles valides?
- Si oui, combien de temps un client/canal de messages sont restés en file d'attente?
- Si oui, est-il
redis-cli info
de commande pour voir combien de messages sont mis en file d'attente (pour chaque client/canal)?
Vous devez vous connecter pour publier un commentaire.
Les tests sont valides, mais les conclusions sont partiellement faux.
Redis n'a pas de file d'attente de quoi que ce soit sur pub/sous-canaux. Au contraire, il a tendance à lire l'article à partir de l'éditeur de socket, et d'écrire l'article dans tous les abonnés sockets, idéalement dans la même itération de la boucle d'événements. Rien n'est conservé dans le Redis structures de données.
Maintenant, comme vous l'avez démontré, il y a toujours une sorte de mise en mémoire tampon. C'est en raison de l'utilisation de sockets TCP/IP, et Redis tampons de communication.
Les douilles sont des tampons, et bien sûr, le protocole TCP est livré avec des flux de mécanismes de contrôle. Il évite la perte de données lorsque les tampons sont pleins. Si un abonné n'est pas assez rapide, les données s'accumulent dans son support de la mémoire tampon. Quand il est plein, le protocole TCP bloquer la communication et empêche le Redis pour pousser plus d'informations dans le support.
Redis gère également la sortie tampons de communication (sur le dessus de ceux de l'sockets) pour générer des données de formaté avec le Redis protocole. Ainsi, lorsque la mémoire tampon de sortie de la prise est pleine, la boucle d'événement marquera le support non inscriptible, et les données restent dans le Redis tampons de sortie.
À condition que la connexion TCP est toujours valide, les données peuvent rester en mémoire pour un temps très long. Maintenant, à la fois le support et le Redis tampon de sortie sont liés. Si les abonnés sont vraiment trop lent, et beaucoup de données s'accumulent, Redis sera finalement de fermer la connexion avec les abonnés (comme un mécanisme de sécurité).
Par défaut, pour pub/sub, Redis a une limite à 8 MO, et une dure limite à 32 MO, par connexion de la mémoire tampon. Si la mémoire tampon de sortie atteint la limite, ou si il reste entre le soft et le hard limite pendant plus de 60 secondes, la connexion avec le ralentissement de l'abonné sera fermé.
Savoir le nombre de messages en attente n'est pas facile. Il peut être évalué en regardant la taille de l'attente des informations dans le support de tampons, et le Redis tampons de sortie.
Pour le Redis tampons de sortie, vous pouvez utiliser le CLIENT de commande de la LISTE (à partir de redis-cli). La taille de la mémoire tampon de sortie est retourné dans l'obl et oll champs (en octets).
Pour la prise de tampons, il n'y a pas de Redis commande. Cependant, sur Linux, il est possible de créer un script pour interpréter le contenu de /proc/net/tcp fichier. Voir un exemple ici. Ce script doit probablement être adapté à votre système.