【问题标题】:Why redis stream consumers should specify an individual name in the same consumer group?为什么redis流消费者应该在同一个消费者组中指定一个单独的名字?
【发布时间】:2021-11-29 02:13:45
【问题描述】:

下面的代码展示了我如何测试 Redis 流函数。

我发现具有相同消费者名称的不同进程正在竞争消费同一流中的消息。以我的理解,如果这个性能正常的话,Redis 不应该设计一个函数来指定消费者名称。

我的理解有问题吗?还是我用错了方法?

import asyncio
import aioredis

# consumer with name "a", subscribing two streams
async def consume_a():
    try:
        while True:
            redis = aioredis.from_url("redis://localhost:36379")
            res = await redis.xreadgroup(
                "test_consumer_group",
                "consumer_a",
                streams={"test_stream": ">", "test_stream_1": ">"},
                count=1,
                block=10000,
                noack=True,
            )
            print(res)
    finally:
        await redis.close()

名为“b”的消费者,订阅了两个流

async def consume_b():
    try:
        while True:
            redis = aioredis.from_url("redis://localhost:36379")
            res = await redis.xreadgroup(
                "test_consumer_group",
                "consumer_b",
                streams={"test_stream": ">", "test_stream_1": ">"},
                count=1,
                block=10000,
                noack=True,
            )
            print(res)
    finally:
        await redis.close()

在运行脚本之前创建组

async def config_group_0():
    try:
        redis = aioredis.from_url("redis://localhost:36379")
        res = await redis.xgroup_create("test_stream", "test_consumer_group")
        print(res)
    finally:
        await redis.close()

async def config_group_1():
    try:
        redis = aioredis.from_url("redis://localhost:36379")
        res = await redis.xgroup_create("test_stream_1", "test_consumer_group")
        print(res)
    finally:
        await redis.close()

生产者

async def produce_0():
    try:
        redis = aioredis.from_url("redis://localhost:36379")
        i = 0
        while i < 100:
            res = await redis.xadd(
                "test_stream",
                {"domain_name": "test_domain_name_0", "sid": 0},
                maxlen=5,
            )
            print(res)
            i += 1
    finally:
        await redis.close()

async def produce_1():
    try:
        redis = aioredis.from_url("redis://localhost:36379")
        i = 0
        while i < 100:
            res = await redis.xadd(
                "test_stream_1",
                {"domain_name": "test_domain_name_1", "sid": 1},
                maxlen=2,
            )
            print(res)
            i += 1
    finally:
        await redis.close()

测试代码

if __name__ == "__main__":
    # two coroutines consume messages from two streams with the same consumer name
    asyncio.run(asyncio.gather(consume_a(), consume_a(), produce_0(), produce_1()))

【问题讨论】:

    标签: python redis python-asyncio aioredis


    【解决方案1】:

    基于Redis文档:

    消费者组的一个保证是给定消费者只能看到传递给它的消息的历史记录,因此消息只有一个所有者。

    阅读这些文档了解更多信息:

    【讨论】:

    • 那么多个进程共享同一个消费者名正常吗?还是每个进程都有一个唯一的名称会更好?
    【解决方案2】:

    消费者获得自己的PEL,或竞争重复消费PEL

    【讨论】:

    猜你喜欢
    • 2021-12-31
    • 2016-04-12
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 2019-06-10
    • 1970-01-01
    • 2011-06-04
    • 2011-12-16
    相关资源
    最近更新 更多