public void TopicMetadataRequestWithNoSegmentMetadataCreation()
        {
            var topics = new List <string> {
                "topic1", "topic2"
            };

            var request = TopicMetadataRequest.Create(topics, 1, 1, "test");

            Assert.IsNotNull(request);
            Assert.AreEqual(topics.Count, request.Topics.Count());

            for (int i = 0; i < topics.Count; i++)
            {
                var expectedTopic = topics[i];
                var actualTopic   = request.Topics.ElementAt(i);

                Assert.AreEqual(expectedTopic, actualTopic);
            }

            Assert.AreEqual(DetailedMetadataRequest.NoSegmentMetadata, request.DetailedMetadata);
        }
        /// <summary>
        /// KafkaClientHelperWrapper produces or consumes messages to/from a particular partition of a topic
        /// </summary>
        /// <param name="topic">target topic</param>
        /// <param name="helperConfiguration"></param>
        public KafkaClientHelperWrapper(string topic, KafkaClientHelperConfiguration helperConfiguration)
        {
            if (string.IsNullOrEmpty(topic))
            {
                throw new System.ArgumentNullException("topicParam");
            }

            if (helperConfiguration == null)
            {
                throw new System.ArgumentNullException("helperConfiguration");
            }

            if (helperConfiguration.LeaderConfig == null && string.IsNullOrEmpty(helperConfiguration.KafkaBrokerList) && helperConfiguration.ZookeeperConfig == null)
            {
                throw new System.ArgumentException("Leader and KafkaBrokerList and Zookeepr connection string are missing");
            }

            Logger.DebugFormat("KafkaClientHelperWrapper constructor start,topicParam={0},kafkaBrokerList={1},zookeeper={2}",
                               topic, helperConfiguration.KafkaBrokerList, helperConfiguration.ZookeeperConfig);

            ServicePointManager.DefaultConnectionLimit = 5000;
            ServicePointManager.UseNagleAlgorithm      = false;
            this.topic = topic;
            this.HelperConfiguration = helperConfiguration;

            if (this.HelperConfiguration.LeaderConfig != null)
            {
                this.leaders.Add(this.HelperConfiguration.LeaderPartition, this.HelperConfiguration.LeaderConfig);
                this.lastTimeLeaderFound = DateTime.Now;
            }

            this.topicMetaRequest = TopicMetadataRequest.Create(
                new string[] { this.topic },                                    // topic
                0,                                                              // API version id
                this.random.Next(int.MinValue, int.MaxValue),                   // correlation id
                Assembly.GetExecutingAssembly().ManifestModule.ToString());     // client id
        }
        public KafkaClientHelper(string topicParam, int partitionIndex, KafkaClientHelperConfiguration helperConfiguration)
        {
            ServicePointManager.DefaultConnectionLimit = 5000;
            ServicePointManager.UseNagleAlgorithm      = false;

            this.partitionIndex      = partitionIndex;
            this.helperConfiguration = helperConfiguration;
            this.MaxMessageSize      = helperConfiguration.MaxMessageSize;
            this.MaxMessagePerSet    = helperConfiguration.MaxMessagePerSet;
            this.ConsumerMaxWait     = helperConfiguration.MaxWaitTime;
            this.Offset     = helperConfiguration.Offset;
            this.OffsetType = helperConfiguration.OffsetType;

            // Logger.Debug(string.Format("KafkaClientHelper constructor start,topicParam={0},partitionIndex={1},kafkaBrokerList={2}", topicParam, partitionIndex, kafkaBrokerList));

            if (string.IsNullOrEmpty(this.helperConfiguration.KafkaBrokerList))
            {
                throw new System.ArgumentNullException("kafkaBrokerList");
            }

            if (string.IsNullOrEmpty(topicParam))
            {
                throw new System.ArgumentNullException("topicParam");
            }

            this.topic = topicParam;

            // assemble brokerConfig list
            this.brokerConfList = new List <BrokerConfiguration>(5);

            string[] brokers = this.helperConfiguration.KafkaBrokerList.Split(new char[] { ',' });

            int i = 1;

            foreach (string v in brokers)
            {
                string[] brokerParams = v.Split(new char[] { ':' });
                int      port         = 0;
                if (brokerParams.Count() == 2 &&
                    !string.IsNullOrEmpty(brokerParams[0]) &&
                    int.TryParse(brokerParams[1], out port))
                {
                    this.brokerConfList.Add(new BrokerConfiguration()
                    {
                        BrokerId = i, Host = brokerParams[0], Port = port
                    });
                }

                i++;
            }

            // prepare SyncProducer list
            i = 0;
            syncProducerPool = new SyncProducer[this.brokerConfList.Count];
            this.RoundRobinSyncProducer();

            topicMetaRequest = TopicMetadataRequest.Create(
                new string[] { this.topic },                                    // topic
                0,                                                              // API version id
                this.random.Next(int.MinValue, int.MaxValue),                   // correlation id
                Assembly.GetExecutingAssembly().ManifestModule.ToString());     // client id
        }
        /// <summary>
        /// Force get topic metadata and update
        /// </summary>
        public void UpdateInfo(short versionId, int correlationId, string clientId, string topic)
        {
            Logger.InfoFormat("Will update metadata for topic:{0}", topic);
            Guard.NotNullNorEmpty(topic, "topic");
            var shuffledBrokers = this.syncProducerPool.GetShuffledProducers();
            var i = 0;
            var hasFetchedInfo = false;

            while (i < shuffledBrokers.Count && !hasFetchedInfo)
            {
                ISyncProducer producer = shuffledBrokers[i++];

                try
                {
                    var topicMetadataRequest = TopicMetadataRequest.Create(new List <string>()
                    {
                        topic
                    }, versionId,
                                                                           correlationId, clientId);
                    var topicMetadataList = producer.Send(topicMetadataRequest);
                    var topicMetadata     = topicMetadataList.Any() ? topicMetadataList.First() : null;
                    if (topicMetadata != null)
                    {
                        if (topicMetadata.Error != ErrorMapping.NoError)
                        {
                            Logger.WarnFormat("Try get metadata of topic {0} from {1}({2}) . Got error: {3}", topic, producer.Config.BrokerId, producer.Config.Host, topicMetadata.Error.ToString());
                        }
                        else
                        {
                            this.topicPartitionInfo[topic] = topicMetadata;
                            this.topicPartitionInfoLastUpdateTime[topic] = DateTime.UtcNow;
                            Logger.InfoFormat("Will  Update  metadata info, topic {0} ", topic);

                            //TODO:  For all partitions which has metadata, here return the sorted list.
                            //But sometimes kafka didn't return metadata for all topics.
                            this.topicPartitionInfoList[topic] = topicMetadata.PartitionsMetadata.Select(m =>
                            {
                                Partition partition = new Partition(topic, m.PartitionId);
                                if (m.Leader != null)
                                {
                                    var leaderReplica = new Replica(m.Leader.Id, topic);
                                    partition.Leader  = leaderReplica;
                                    Logger.InfoFormat("Topic {0} partition {1} has leader {2}", topic,
                                                      m.PartitionId, m.Leader.Id);

                                    return(partition);
                                }

                                Logger.WarnFormat("Topic {0} partition {1} does not have a leader yet", topic,
                                                  m.PartitionId);

                                return(partition);
                            }
                                                                                                         ).OrderBy(x => x.PartId).ToList();;
                            hasFetchedInfo = true;
                            Logger.InfoFormat("Finish  Update  metadata info, topic {0}  Partitions:{1}  No leader:{2}", topic, this.topicPartitionInfoList[topic].Count, this.topicPartitionInfoList[topic].Where(r => r.Leader == null).Count());

                            //In very weired case, the kafka broker didn't return metadata of all broker. need break and retry.  https://issues.apache.org/jira/browse/KAFKA-1998
                            // http://qnalist.com/questions/5899394/topicmetadata-response-miss-some-partitions-information-sometimes
                            if (zkClient != null)
                            {
                                Dictionary <int, int[]> topicMetaDataInZookeeper = ZkUtils.GetTopicMetadataInzookeeper(this.zkClient, topic);
                                if (topicMetaDataInZookeeper != null && topicMetaDataInZookeeper.Any())
                                {
                                    topicDataInZookeeper[topic] = topicMetaDataInZookeeper;
                                    if (this.topicPartitionInfoList[topic].Count != topicMetaDataInZookeeper.Count)
                                    {
                                        Logger.ErrorFormat("NOT all partition has metadata.  Topic partition in zookeeper :{0} topics has partition metadata: {1}", topicMetaDataInZookeeper.Count, this.topicPartitionInfoList[topic].Count);
                                        throw new UnavailableProducerException(string.Format("Please make sure every partition at least has one broker running and retry again.   NOT all partition has metadata.  Topic partition in zookeeper :{0} topics has partition metadata: {1}", topicMetaDataInZookeeper.Count, this.topicPartitionInfoList[topic].Count));
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Logger.ErrorFormat("Try get metadata of topic {0} from {1}({2}) . Got error: {3}", topic, producer.Config.BrokerId, producer.Config.Host, e.FormatException());
                }
            }
        }
Ejemplo n.º 5
0
        public void Start()
        {
            while (!_stop)
            {
                try
                {
                    if (_partitionsNeedingLeader.IsEmpty)
                    {
                        Thread.Sleep(_config.ConsumeGroupFindNewLeaderSleepIntervalMs);
                        continue;
                    }

                    PartitionTopicInfo partition;
                    if (_partitionsNeedingLeader.TryDequeue(out partition))
                    {
                        Logger.DebugFormat("Finding new leader for topic {0}, partition {1}", partition.Topic, partition.PartitionId);
                        Broker newLeader = null;
                        foreach (KeyValuePair <int, Broker> broker in _brokers.Brokers)
                        {
                            var consumer = new Consumer(_config, broker.Value.Host, broker.Value.Port);
                            try
                            {
                                IEnumerable <TopicMetadata> metaData = consumer.GetMetaData(TopicMetadataRequest.Create(new[] { partition.Topic }, 1, 0, clientId));
                                if (metaData != null && metaData.Any())
                                {
                                    PartitionMetadata newPartitionData = metaData.First().PartitionsMetadata.FirstOrDefault(p => p.PartitionId == partition.PartitionId);
                                    if (newPartitionData != null)
                                    {
                                        Logger.DebugFormat("New leader for {0} ({1}) is broker {2}", partition.Topic, partition.PartitionId, newPartitionData.Leader.Id);
                                        newLeader = newPartitionData.Leader;
                                        break;
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                Logger.WarnFormat("Error retrieving meta data from broker {0}: {1}", broker.Value.Id, ex.FormatException());
                            }
                        }

                        if (newLeader == null)
                        {
                            Logger.ErrorFormat("New leader information could not be retrieved for {0} ({1})", partition.Topic, partition.PartitionId);
                        }
                        else
                        {
                            _createNewFetcher(partition, newLeader);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.ErrorFormat("PartitionLeaderFinder encountered an error: {0}", ex.FormatException());
                    Thread.Sleep(FailureRetryDelayMs);
                }
            }

            Logger.Info("Partition leader finder thread shutting down.");
        }
        public void TopicMetadataRequestShouldThrowExceptionWhenListOfTopicsIsEmpty()
        {
            IList <string> topics = new List <string>();

            TopicMetadataRequest.Create(topics, 1, 1, "test");
        }