原文:https://cwiki.apache.org/confluence/display/KAFKA/Consumer+Group+Example

为什么使用High Level Consumer

  1. 在某些应用场景,我们希望通过多线程读取消息,而我们并不关心从Kafka消费消息的顺序,我们只关心数据能被消费即可。High Level 就是用于抽象这类消费动作的。

  2. 消息消费已Consumer Group为单位,每一个Consumer Group中能够有多个consumer。每一个consumer是一个线程,topic的每一个partition同一时候仅仅能被某一个consumer读 取,Consumer Group相应的每一个partition都有一个最新的offset的值,存储在zookeeper上的。所以不会出现反复消费的情况。

  3. 由于consumer的offerset并非实时的传送到zookeeper(通过配置来制定更新周期)。所以Consumer假设突然Crash,有可能会读取反复的信息

设计High Level Consumer

High Level Consumer 能够而且应该被使用在多线程的环境。线程模型中线程的数量(也代表group中consumer的数量)和topic的partition数量有关。以下列举一些规则:

  1. 当提供的线程数量多于partition的数量,则部分线程将不会接收到消息。
  2. 当提供的线程数量少于partition的数量,则部分线程将从多个partition接收消息。
  3. 当某个线程从多个partition接收消息时,不保证接收消息的顺序;可能出现从partition3接收5条消息。从partition4接收6条消息。接着又从partition3接收10条消息;
  4. 当加入很多其它线程时。会引起kafka做re-balance, 可能改变partition和线程的相应关系。
  5. 由于突然停止Consumer以及Broker会导致消息反复读的情况,为了避免这样的情况在shutdown之前通过Thread.sleep(10000)让Consumer有时间将offset同步到zookeeper

样例

Maven依赖

      <!--Kafka 消息依赖-->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka_2.10</artifactId>
<version>0.8.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>0.8.2.0</version>
</dependency>

Consumer 线程


import kafka.consumer.ConsumerIterator;
import kafka.consumer.KafkaStream;
import kafka.message.MessageAndMetadata; public class ConsumerThread implements Runnable {
private KafkaStream kafkaStream;
//线程编号
private int threadNumber;
public ConsumerThread(KafkaStream kafkaStream, int threadNumber) {
this.threadNumber = threadNumber;
this.kafkaStream = kafkaStream;
}
public void run() {
ConsumerIterator<byte[], byte[]> it = kafkaStream.iterator();
StringBuffer sb = new StringBuffer();
//该循环会持续从Kafka读取数据,直到手工的将进程进行中断
while (it.hasNext()) {
MessageAndMetadata metaData = it.next();
sb.append("Thread: " + threadNumber + " ");
sb.append("Part: " + metaData.partition() + " ");
sb.append("Key: " + metaData.key() + " ");
sb.append("Message: " + metaData.message() + " ");
sb.append("\n");
System.out.println(sb.toString());
}
System.out.println("Shutting down Thread: " + threadNumber);
}
}

其余程序


import kafka.consumer.ConsumerConfig;
import kafka.consumer.KafkaStream;
import kafka.javaapi.consumer.ConsumerConnector; import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class ConsumerGroupExample {
private final ConsumerConnector consumer;
private final String topic;
private ExecutorService executor; public ConsumerGroupExample(String a_zookeeper, String a_groupId, String a_topic) {
consumer = kafka.consumer.Consumer.createJavaConsumerConnector(
createConsumerConfig(a_zookeeper, a_groupId));
this.topic = a_topic;
} public void shutdown() {
if (consumer != null) consumer.shutdown();
if (executor != null) executor.shutdown();
} public void run(int a_numThreads) {
Map<String, Integer> topicCountMap = new HashMap<String, Integer>();
topicCountMap.put(topic, new Integer(a_numThreads));
//返回的Map包括全部的Topic以及相应的KafkaStream
Map<String, List<KafkaStream<byte[], byte[]>>> consumerMap = consumer.createMessageStreams(topicCountMap);
List<KafkaStream<byte[], byte[]>> streams = consumerMap.get(topic); //创建Java线程池
executor = Executors.newFixedThreadPool(a_numThreads); // 创建 consume 线程消费messages
int threadNumber = 0;
for (final KafkaStream stream : streams) {
executor.submit(new ConsumerTest(stream, threadNumber));
threadNumber++;
}
} private static ConsumerConfig createConsumerConfig(String a_zookeeper, String a_groupId) {
Properties props = new Properties();
//指定连接的Zookeeper集群。通过该集群来存储连接到某个Partition的Consumer的Offerset
props.put("zookeeper.connect", a_zookeeper);
//consumer group 的ID
props.put("group.id", a_groupId);
//Kafka等待Zookeeper的响应时间(毫秒)
props.put("zookeeper.session.timeout.ms", "400");
//ZooKeeper 的‘follower’能够落后Master多少毫秒
props.put("zookeeper.sync.time.ms", "200");
//consumer更新offerset到Zookeeper的时间
props.put("auto.commit.interval.ms", "1000"); return new ConsumerConfig(props);
} public static void main(String[] args) {
String zooKeeper = args[0];
String groupId = args[1];
String topic = args[2];
int threads = Integer.parseInt(args[3]); ConsumerGroupExample example = new ConsumerGroupExample(zooKeeper, groupId, topic);
example.run(threads);
//由于consumer的offerset并非实时的传送到zookeeper(通过配置来制定更新周期),所以shutdown Consumer的线程,有可能会读取反复的信息
//添加sleep时间,让consumer把offset同步到zookeeper
try {
Thread.sleep(10000);
} catch (InterruptedException ie) { }
example.shutdown();
}
}

设计Kafka的High Level Consumer的更多相关文章

  1. Consumer设计-high/low Level Consumer

    1 Producer和Consumer的数据推送拉取方式   Producer Producer通过主动Push的方式将消息发布到Broker n Consumer Consumer通过Pull从Br ...

  2. Kafka 学习笔记之 High Level Consumer相关参数

    High Level Consumer相关参数 自动管理offset auto.commit.enable = true auto.commit.interval.ms = 60*1000 手动管理o ...

  3. .net Kafka.Client多个Consumer Group对Topic消费不能完全覆盖研究总结(一)

    我们知道Kafka支持Consumer Group的功能,但是最近在应用Consumer Group时发现了一个Topic 的Partition不能100%覆盖的问题. 程序部署后,发现Kafka在p ...

  4. Kafka 学习笔记之 Consumer API

    Kafka提供了两种Consumer API High Level Consumer API Low Level Consumer API(Kafka诡异的称之为Simple Consumer API ...

  5. .net Kafka.Client多个Consumer Group对Topic消费不能完全覆盖研究总结(二)

    依据Partition和Consumer的Rebalance策略,找到Kafka.Client Rebalance代码块,还原本地环境,跟踪调试,发现自定义Consumer Group 的Consum ...

  6. Kafka客户端Producer与Consumer

    Kafka客户端Producer与Consumer 一.pom.xml 二.相关配置文件 producer.properties log4j.properties base.properties 三. ...

  7. 漫游Kafka设计篇之Producer和Consumer

    Kafka Producer 消息发送 producer直接将数据发送到broker的leader(主节点),不需要在多个节点进行分发.为了帮助producer做到这点,所有的Kafka节点都可以及时 ...

  8. 漫游Kafka设计篇之Producer和Consumer(4)

    Kafka Producer 消息发送 producer直接将数据发送到broker的leader(主节点),不需要在多个节点进行分发.为了帮助producer做到这点,所有的Kafka节点都可以及时 ...

  9. 如何设计Kafka?

    著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:Sugar Su链接:http://zhuanlan.zhihu.com/ms15213/20545422来源:知乎 此文稿来 ...

随机推荐

  1. Cocos2d-x中父节点scale对子节点的影响

    背景:在前几天,刚接触cocos2d-x,随便找了一张图,作为一个CCSprite,而且设置了scale属性,然后在这个sprite上创建了一个CCLabelTTF,并用sprite->addC ...

  2. VS2010 TFS

    在本文的两个部分中,我将介绍Team Foundation Server的一些核心特征,重点介绍在本产品的日常应用中是怎样将这些特性结合在一起使用的. 作为一名软件开发者,在我的职业生涯中,我常常会用 ...

  3. 从零开始学Xamarin.Forms(二) 环境搭建、创建项目

    原文:从零开始学Xamarin.Forms(二) 环境搭建.创建项目 一.环境搭建 Windows下环境搭建:     1.下载并安装jdk.Android SDK和NDK,当然还需要 VS2013 ...

  4. Windows Phone开发(3):棋子未动,先观全局

    原文:Windows Phone开发(3):棋子未动,先观全局 在进行WP开发之前,与其它开发技术一样,我们需要简单了解一个WP应用序的生命周期,我们不一定要深入了解,但至少要知道在应用程序生命周期内 ...

  5. Excel阅读器NPOI

    什么是NPOI? NPOI 它是 POI 项目的 .NET 版本号. POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. 使用 NPOI 你就能够在没有安装 Office ...

  6. ASP.NET MVC源码分析

    MVC4 源码分析(Visual studio 2012/2013) HttpModule中重要的UrlRoutingModule 9:this.OnApplicationPostResolveReq ...

  7. 在SQLAlter在现场一定的价值

    update AA set aa = replace(aa,'1234','规范') where aa like '%1234%'

  8. Linux 编程学习笔记----ANSI C 文件I/O管理

    转载请注明出处:http://blog.csdn.net/suool/article/details/38129201 问题引入 文件的种类 依据数据存储的方式不同,能够将文件分为文本文件和二进制文件 ...

  9. JAVA程序生成XML标准化的文件格式,缩进,美化。

    //他开始Document映射到文件 TransformerFactory transFactory = TransformerFactory.newInstance(); Transformer t ...

  10. Blend4精选案例图解教程(一):丰富的形状(Shape)资源

    原文:Blend4精选案例图解教程(一):丰富的形状(Shape)资源 Blend4资源面板中内置了丰富的形状素材,为我们在构建程序时提供极大的方便.系统默认内置18种常用形状,通过其属性设置可以自定 ...