How to Enable Concurrent Processing of Stream Messages #1854
-
|
I am using FastStream to process messages from a Redis stream. My expectation is that the subscriber function (handle) should process the messages concurrently. import asyncio
from faststream import FastStream, Logger
from faststream.redis import RedisBroker, StreamSub
broker = RedisBroker()
app = FastStream(broker)
@broker.subscriber(
stream=StreamSub("test-stream", group="test-group", consumer="1")
)
async def handle(msg: str, logger: Logger):
logger.info("start")
await asyncio.sleep(2) # Simulating an HTTP request
logger.info("end")LogsAs you can see from the logs, each message is processed one after the other, waiting for the previous task to finish before the next one starts. Key Points
Questions
Any guidance or suggestions on how to fix this issue would be appreciated! |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 4 replies
-
|
Hello @sandeep2rawat, By default FastStream consumes single message from the Redis Stream before consuming the next message. If you want to process multiple messages at once there are few ways to do it.
You can combine 1 and 2 to consume multiple messages at the same time. |
Beta Was this translation helpful? Give feedback.
-
|
@sandeep2rawat Redis Stream works the same way with Kafka - so it can't be scaled horizontally using the same group and consumer. |
Beta Was this translation helpful? Give feedback.
-
|
Should each process use a different consumer name? According to the Redis documentation, each consumer maintains its own PEL. If I use UUID to represent consumer names, then each time the service restarts, there will be consumers that cannot be found. Redis streams make it a heavy burden to use.😮💨 |
Beta Was this translation helpful? Give feedback.
-
|
Can add a feature to clean up consumers? 🤔 consumers_info = redis_conn.xinfo_consumers(REDIS_DOWNLOAD_STREAM, REDIS_CONSUMER_GROUP)
idle_threshold = 60 * 60 * 1000 # Over an hour free, clean up
for consumer in consumers_info:
name = consumer['name']
pending = consumer['pending']
idle = consumer['idle'] # ms
if pending == 0 and idle > idle_threshold and name != CONSUMER_NAME:
# Delete idle old consumer
try:
redis_conn.xgroup_delconsumer(REDIS_DOWNLOAD_STREAM, REDIS_CONSUMER_GROUP, name)
print(f"🗑️ Deleted idle old consumer: {name}")
except Exception as e:
import traceback
traceback.print_exc() |
Beta Was this translation helpful? Give feedback.
Hello @sandeep2rawat,
By default FastStream consumes single message from the Redis Stream before consuming the next message. If you want to process multiple messages at once there are few ways to do it.
--workersflag for scaling.You can combine 1 and 2 to consume multiple messages at the same time.