如何为卡夫卡消费群生成唯一的ID?

时间:2019-11-30 20:24:05

标签: c# .net-core apache-kafka uniqueidentifier confluent-kafka

我有一个.NET Core Api,我希望能够接受HTTP请求并将请求者订阅多个Kafka主题。

阅读Kafka文档,我发现对于给定的主题,多个消费者接收相同数据(唯一的说一个分区/主题)的唯一方法是将每个消费者分配给一个消费者组。否则,我可能会遇到一个用户/分区超过1个的情况。

对于给定的主题,N个消费者想要读取相同的数据,我需要N个消费者群体。

现在进入Confluent Kafka Library了,在我的情况下(每个消费者组1个消费者),我是否不需要为每个主题都使用ConsumerConfig

我不确定图书馆是否可以处理这种情况并自动生成ID,或者我需要生成ID,那么什么是好的策略?

以下是尝试生成ID的尝试:

订阅所有主题的请求者

        List<IConsumer<Ignore,string>> consumersForRequester = new List<IConsumer<Ignore,string>>();
        foreach (string topic in KafkaConfig.Topics) {
            string consumerGroupId = IDGenerator.Instance.GetUniqueId(topic);
            if (consumerGroupId == string.Empty) {
                throw new NotSupportedException("Could not subscribe to kafka topic,consumer group id already used");
            }
            ConsumerConfig config = new ConsumerConfig {
                GroupId = consumerGroupId,
            };
            var iconsumer = new ConsumerBuilder<Ignore, string>(config).Build();
            iconsumer.Subscribe(topic);
            consumersForRequester.Add(iconsumer);
        }

IDGenerator

 class IDGenerator {
        private static IDGenerator instance;
        public static IDGenerator Instance {
            get {
                lock (@lock) {
                    if (instance == null) {
                        instance = new IDGenerator();
                    }
                    return instance;
                }
            }
        }
        private Dictionary<string,(Random,HashSet<int>)> uniqueIDMap = new Dictionary<string,(Random,HashSet<int>)>();
        private static readonly object @lock = new object();
        private int MAX_VALUE = 100_000;
        private const int MAX_ATTEMPTS = 3;

        public string Get_Unique_ConsumerGroupID_ForTopic(string topic) {
            //-- thread unsafe
            if (!uniqueIDMap.ContainsKey(topic)) {
                uniqueIDMap.Add(topic,(new Random(), new HashSet<int>()));
            }
            (Random randomForTopic, HashSet<int> hashForTopic) = uniqueIDMap[topic];
            //--
            if (hashForTopic.Count > MAX_VALUE) {
                throw new NotSupportedException($"Consumer Group Count for topic {topic} Reached");
            }
            lock (@lock) {
                int attemptsToGenerateUniqueID = 0;
                while (true) {
                    if (attemptsToGenerateUniqueID++ > MAX_ATTEMPTS) {
                        return string.Empty;
                    }
                    int id = randomForTopic.Next(0, MAX_VALUE);
                    if(hashForTopic.TryGetValue(id,out int actualval)) {
                        continue;
                    }
                    hashForTopic.Add(id);
                    return id.ToString();
                }
            }

        }

    }

PS IDGenerator是我的ASP NET Core应用程序的单例。 对于给定的主题,它尝试使用范围内的Random生成唯一的消费者组ID。所有生成的ID均存储在该特定主题的HashSet中。

0 个答案:

没有答案