如果我们在分区中使用多个消息流(createMessageStreams),如何在kafka使用者中实现排序

时间:2019-12-26 06:04:42

标签: java apache-kafka parallel-processing

技术堆栈:

  1. Kafka ConsumerConnector 2.10
  2. kafka客户端0.8.2.2

我们想跟踪包裹的旅程。当前,我们正在2个tomcat服务器上发布有关主题 Topic1 的事件,并将唯一键(trackingNumber)作为ProducerRecord键。

发布者:

KafkaProducer<String, TrackingEvent> producer = kafkaProducer.getKafkaProducerForTrackingEvent();
ProducerRecord<String, TrackingEvent> record = new ProducerRecord<>("Topic1",TrackingEvent.getTrackingNumber(), TrackingEvent);
producer.send(record);

跟踪编号为 TrackingPackage1 的事件旅程示例,供您参考:

打开->跨内->进入->出->跨内->删除

我们知道,在单个主题上,如果我们使用 n个分区,则n个服务器可以连接,并且有序数据消耗在每台服务器上开始,但是我们想通过Kafka消息流实现有序并行处理,最大化吞吐量。

场景:

在我们的方案中,我们有2个tomcat服务器,在单个主题 Topic1 上具有2个分区。对于 TrackingPackage1 ,假设 P1 分配, TrackingPackage2 ,假设 P2 分配,对于 TrackingPackage4 P1 分区分配。

如果我们使用单个消息流,则可以保证时间戳基础上的订单使用量。 https://www.oreilly.com/library/view/kafka-the-definitive/9781491936153/assets/ktdg_04in03.png 但是,当我们在该分区上使用多个流时,将无法保证。有什么方法可以实现订单保证?

订户:

   private ConsumerConnector consumer;
private ExecutorService   executor;

@Autowired
private IService service;

Properties props = new Properties();
        props.put("zookeeper.connect", zookeeper_connect);
        props.put("group.id", group_id);
        props.put("consumer.id", getHostName());
        props.put("enable.auto.commit", "true");
        props.put("zookeeper.session.timeout.ms", timeout);
        props.put("kafka.topic", topics);

            this.consumer = Consumer.createJavaConsumerConnector(createConsumerConfig(props));

 Map<String, Integer> topicCountMap = new HashMap<>();
 List<String> topicList = StringUtils.split(topics);
 for (String topic : topicList) {
      topicCountMap.put(topic, Integer.parseInt(noOfThreadPerTopics));
}
Map<String, List<KafkaStream<byte[], byte[]>>> consumerMap = consumer.createMessageStreams(topicCountMap);
executor = Executors.newFixedThreadPool(topicList.size() * Integer.parseInt(noOfThreadPerTopics));
for (String topic : topicList) {
List<KafkaStream<byte[], byte[]>> streams = consumerMap.get(topic);
for (final KafkaStream<byte[], byte[]> stream : streams) {
    executor.submit(new TrackingPackageKafkaStreamProcessor(stream, service));
    }
}

0 个答案:

没有答案