exist - redis python example
Redis Pubsub y Message Queuing (1)
Las pruebas son válidas, pero las conclusiones son parcialmente incorrectas.
Redis no pone nada en cola en los canales pub / sub. Por el contrario, tiende a leer el elemento desde el zócalo editorial y a escribir el elemento en todos los zócalos de suscriptor, idealmente en la misma iteración del bucle de evento. No se guarda nada en las estructuras de datos de Redis.
Ahora, como demostraste, todavía hay algún tipo de amortiguación. Se debe al uso de sockets TCP / IP y búferes de comunicación Redis.
Los zócalos tienen búferes y, por supuesto, TCP incluye algunos mecanismos de control de flujo. Evita la pérdida de datos cuando los almacenamientos intermedios están llenos. Si un suscriptor no es lo suficientemente rápido, los datos se acumularán en su búfer de socket. Cuando está lleno, TCP bloqueará la comunicación e impedirá que Redis introduzca más información en el socket.
Redis también administra buffers de comunicación de salida (además de los sockets) para generar datos formateados con el protocolo Redis. Por lo tanto, cuando el búfer de salida del zócalo está lleno, el bucle de evento marcará el zócalo como no modificable, y los datos permanecerán en los búferes de salida Redis.
Si la conexión TCP sigue siendo válida, los datos pueden permanecer en los búferes durante mucho tiempo. Ahora, tanto el socket como el buffer de salida Redis están vinculados. Si los suscriptores son muy lentos y se acumulan muchos datos, Redis finalmente cerrará la conexión con los suscriptores (como mecanismo de seguridad).
De forma predeterminada, para pub / sub, Redis tiene un límite de software de 8 MB y un límite de 32 MB por buffer de conexión. Si el búfer de salida alcanza el límite estricto, o si permanece entre el límite suave y el límite duro durante más de 60 segundos, la conexión con el suscriptor lento se cerrará.
Conocer la cantidad de mensajes pendientes no es fácil. Puede evaluarse observando el tamaño de la información pendiente en los búferes de socket y los buffers de salida de Redis.
Para los buffers de salida de Redis, puede usar el comando CLIENT LIST (de redis-cli). El tamaño del buffer de salida se devuelve en los campos obl y oll (en bytes).
Para buffers de socket, no hay ningún comando Redis. Sin embargo, en Linux, es posible construir una secuencia de comandos para interpretar el contenido del archivo / proc / net / tcp. Vea un ejemplo here . Es probable que esta secuencia de comandos deba adaptarse a su sistema.
Mi pregunta general es: al usar Redis para PubSub, ¿qué sucede con los mensajes cuando los editores envían mensajes a un canal más rápido de lo que los suscriptores pueden leerlos?
Por ejemplo, digamos que tengo:
- Un editor sencillo que publica mensajes a una velocidad de 2 msg / seg.
- Un simple suscriptor lee mensajes a una velocidad de 1 msg / seg.
Mi suposición ingenua sería que el suscriptor solo vería el 50% de los mensajes publicados en Redis. Para probar esta teoría, escribí dos guiones:
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)
Resultados
- Cuando ejecuté
sub.py
primero, inmediatamente seguido depub.py
, encontré quesub.py
realmente muestra todos los mensajes (1-10), uno tras otro con un retraso de 1 segundo entre ellos. Mi suposición inicial era incorrecta, Redis está poniendo mensajes en cola. Se necesitan más pruebas. - Cuando ejecuté
pub.py
primero, luego esperé 5 segundos antes de ejecutarsub.py
, encontré quesub.py
solo mostraba la segunda mitad de los mensajes (5-10). Lo habría asumido originalmente, pero dados mis resultados anteriores, habría pensado que los mensajes estaban en cola, lo que me llevó a la siguiente conclusión ...
Conclusiones
- Parece que el servidor Redis pone en cola mensajes para cada cliente, para cada canal.
- Mientras un cliente esté escuchando, no importa qué tan rápido lea los mensajes. Mientras esté conectado, los mensajes permanecerán en cola para ese cliente, para ese canal.
Preguntas restantes
- ¿Son válidas estas conclusiones?
- De ser así, ¿cuánto tiempo permanecerán en cola los mensajes del cliente / canal?
- Si es así, ¿hay un
redis-cli info
para ver cuántos mensajes están en cola (para cada cliente / canal)?