漫游Kafka实战篇clientAPI
原文地址:http://blog.csdn.net/honglei915/article/details/37697655
Kafka Producer APIs
旧版的Procuder API有两种:kafka.producer.SyncProducer和kafka.producer.async.AsyncProducer.它们都实现了同一个接口:
class Producer { /* 将消息发送到指定分区 */
public void send(kafka.javaapi.producer.ProducerData<K,V> producerData); /* 批量发送一批消息 */
public void send(java.util.List<kafka.javaapi.producer.ProducerData<K,V>> producerData); /* 关闭producer */
public void close(); }
新版的Producer API提供了下面功能:
- 能够将多个消息缓存到本地队列里。然后异步的批量发送到broker,能够通过參数
producer.type=async做到。
缓存的大小能够通过一些參数指定:queue.time
和batch.size
。一个后台线程((kafka.producer.async.ProducerSendThread
)从队列中取出数据并让kafka.producer.EventHandler
将消息发送到broker,也能够通过參数event.handler定制
handler。在producer端处理数据的不同的阶段注冊处理器,比方能够对这一过程进行日志追踪。或进行一些监控。仅仅需实现kafka.producer.async.CallbackHandler
接口,并在callback.handler
中配置。 - 自己编写Encoder来序列化消息,仅仅需实现以下这个接口。默认的Encoder是
kafka.serializer.DefaultEncoder
。interface Encoder<T> {
public Message toMessage(T data);
} - 提供了基于Zookeeper的broker自己主动感知能力,能够通过參数
zk.connect
实现。假设不使用Zookeeper。也能够使用broker.list
參数指定一个静态的brokers列表,这样消息将被随机的发送到一个broker上,一旦选中的broker失败了,消息发送也就失败了。 - 通过分区函数
kafka.producer.Partitioner类对消息分区
。interface Partitioner<T> {
int partition(T key, int numPartitions);
}分区函数有两个參数:key和可用的分区数量。从分区列表中选择一个分区并返回id。默认的分区策略是
hash(key)%numPartitions
.假设key是null,就随机的选择一个。能够通过參数
partitioner.class
定制分区函数。
新的api完整实比例如以下:
import java.util.*; import kafka.javaapi.producer.Producer;
import kafka.producer.KeyedMessage;
import kafka.producer.ProducerConfig; public class TestProducer {
public static void main(String[] args) {
long events = Long.parseLong(args[0]);
Random rnd = new Random(); Properties props = new Properties();
props.put("metadata.broker.list", "broker1:9092,broker2:9092 ");
props.put("serializer.class", "kafka.serializer.StringEncoder");
props.put("partitioner.class", "example.producer.SimplePartitioner");
props.put("request.required.acks", "1"); ProducerConfig config = new ProducerConfig(props); Producer<String, String> producer = new Producer<String, String>(config); for (long nEvents = 0; nEvents < events; nEvents++) {
long runtime = new Date().getTime();
String ip = “192.168.2.” + rnd.nextInt(255);
String msg = runtime + “,www.example.com,” + ip;
KeyedMessage<String, String> data = new KeyedMessage<String, String>("page_visits", ip, msg);
producer.send(data);
}
producer.close();
}
}
以下这个是用到的分区函数:
import kafka.producer.Partitioner;
import kafka.utils.VerifiableProperties; public class SimplePartitioner implements Partitioner<String> {
public SimplePartitioner (VerifiableProperties props) { } public int partition(String key, int a_numPartitions) {
int partition = 0;
int offset = key.lastIndexOf('.');
if (offset > 0) {
partition = Integer.parseInt( key.substring(offset+1)) % a_numPartitions;
}
return partition;
} }
KafKa Consumer APIs
Consumer API有两个级别。低级别的和一个指定的broker保持连接。并在接收完消息后关闭连接,这个级别是无状态的,每次读取消息都带着offset。
高级别的API隐藏了和brokers连接的细节,在不必关心服务端架构的情况下和服务端通信。还能够自己维护消费状态。并能够通过一些条件指定订阅特定的topic,比方白名单黑名单或者正則表達式。
低级别的API
class SimpleConsumer { /*向一个broker发送读取请求并得到消息集 */
public ByteBufferMessageSet fetch(FetchRequest request); /*向一个broker发送读取请求并得到一个对应集 */
public MultiFetchResponse multifetch(List<FetchRequest> fetches); /**
* 得到指定时间之前的offsets
* 返回值是offsets列表。以倒序排序
* @param time: 时间,毫秒,
* 假设指定为OffsetRequest$.MODULE$.LATIEST_TIME(), 得到最新的offset.
* 假设指定为OffsetRequest$.MODULE$.EARLIEST_TIME(),得到最老的offset.
*/
public long[] getOffsetsBefore(String topic, int partition, long time, int maxNumOffsets);
}
低级别的API是高级别API实现的基础,也是为了一些对维持消费状态有特殊需求的场景,比方Hadoop consumer这种离线consumer。
高级别的API
/* 创建连接 */
ConsumerConnector connector = Consumer.create(consumerConfig); interface ConsumerConnector { /**
* 这种方法能够得到一个流的列表。每一个流都是MessageAndMetadata的迭代,通过MessageAndMetadata能够拿到消息和其它的元数据(眼下之后topic)
* Input: a map of <topic, #streams>
* Output: a map of <topic, list of message streams>
*/
public Map<String,List<KafkaStream>> createMessageStreams(Map<String,Int> topicCountMap); /**
* 你也能够得到一个流的列表,它包括了符合TopicFiler的消息的迭代,
* 一个TopicFilter是一个封装了白名单或黑名单的正則表達式。
*/
public List<KafkaStream> createMessageStreamsByFilter(
TopicFilter topicFilter, int numStreams); /* 提交眼下消费到的offset */
public commitOffsets() /* 关闭连接 */
public shutdown()
}
这个API环绕着由KafkaStream实现的迭代器展开,每一个流代表一系列从一个或多个分区多和broker上汇聚来的消息。每一个流由一个线程处理。所以client能够在创建的时候通过參数指定想要几个流。一个流是多个分区多个broker的合并。可是每一个分区的消息仅仅会流向一流。
每次通话createMessageStreams会consumer注册到topic上,此consumer和brokers负载平衡将之间调节。
API每次调用创建激励许多人topic流动,以减少这种调整。createMessageStreamsByFilter方法来注册监听器可以感知一个新雅阁filter的tipic。
漫游Kafka实战篇clientAPI的更多相关文章
- 漫游Kafka实战篇之客户端API
Kafka Producer APIs 旧版的Procuder API有两种:kafka.producer.SyncProducer和kafka.producer.async.AsyncProduce ...
- 漫游kafka实战篇之搭建Kafka开发环境
上篇文章中我们搭建了kafka的服务器,并可以使用Kafka的命令行工具创建topic,发送和接收消息.下面我们来搭建kafka的开发环境. 添加依赖 搭建开发环境需要引入kafka的jar包 ...
- 漫游Kafka实战篇之搭建Kafka运行环境
接下来一步一步搭建Kafka运行环境. Step 1: 下载Kafka 点击下载最新的版本并解压. > tar -xzf kafka_2.9.2-0.8.1.1.tgz > cd kafk ...
- 漫游Kafka实战篇之搭建Kafka运行环境(2)
接下来一步一步搭建Kafka运行环境. Step 1: 下载Kafka 点击下载最新的版本并解压. > tar -xzf kafka_2.9.2-0.8.1.1.tgz > cd kafk ...
- 漫游kafka实战篇之搭建Kafka开发环境(3)
上篇文章中我们搭建了kafka的服务器,并可以使用Kafka的命令行工具创建topic,发送和接收消息.下面我们来搭建kafka的开发环境. 添加依赖 搭建开发环境需要引入kafka的jar包 ...
- 漫游Kafka设计篇之性能优化
Kafka在提高效率方面做了很大努力.Kafka的一个主要使用场景是处理网站活动日志,吞吐量是非常大的,每个页面都会产生好多次写操作.读方面,假设每个消息只被消费一次,读的量的也是很大的,Kafka也 ...
- 漫游Kafka设计篇之性能优化(7)
Kafka在提高效率方面做了很大努力.Kafka的一个主要使用场景是处理网站活动日志,吞吐量是非常大的,每个页面都会产生好多次写操作.读方面,假设每个消息只被消费一次,读的量的也是很大的,Kafka也 ...
- 漫游Kafka实现篇之消息和日志
消息格式 消息由一个固定长度的头部和可变长度的字节数组组成.头部包含了一个版本号和CRC32校验码. /** * 具有N个字节的消息的格式如下 * * 如果版本号是0 * * 1. 1个字节的 &qu ...
- 漫游Kafka设计篇之主从同步
Kafka允许topic的分区拥有若干副本,这个数量是可以配置的,你可以为每个topci配置副本的数量.Kafka会自动在每个个副本上备份数据,所以当一个节点down掉时数据依然是可用的. Kafka ...
随机推荐
- OpenCV在MFC图像控件内显示图像
1.依照文章<OpenCV+MFC显示图像>,完毕配置. 2.创建对应的图像控件,button控件. 3.进行类型转换. 在当前OpenCV2版本号内,图像格式为cv::Mat ,而该格式 ...
- 深度this指针
深入探讨this指针 为了写这篇文章.准备了好长时间,翻遍了箱底的书籍.可是如今还是不敢放开手来写,战战兢兢. 不是操心自己写错.而是唯恐自己错误误导别人.同一时候也希望这篇文章能给你一点收获.既 ...
- 【Web探索之旅】第四部分:Web程序员
内容简介 1.第四部分第一课:什么是Web程序员? 2.第四部分第二课:如何成为Web程序员? 3.第四部分第三课:成为优秀Web程序员的秘诀 第四部分:Web程序员(完结篇) 大家好.终于来到了[W ...
- PowerDesigner创建物理模型
原文:PowerDesigner创建物理模型 Using PowerDesigner Create PDM 1.打开PowerDesigner 按Ctrl+N 创建物理模型 2.创建后修改名称,并在工 ...
- 【C语言探索之旅】 第二部分第二课:进击的指针,C语言的王牌!
内容简介 1.课程大纲 2.第二部分第二课: 进击的指针,C语言的王牌 3.第二部分第三课预告: 数组 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言 ...
- DisplayContent、StackBox、TaskStack笔记
文章仅零散记录自己的一点理解,仅供自己參考. 每一个显示设备,都有一个Display对象,DisplayManagerService专门管理这些Display. 1.DisplayContent() ...
- UVA 12206 - Stammering Aliens(后缀数组)
UVA 12206 - Stammering Aliens 题目链接 题意:给定一个序列,求出出现次数大于m,长度最长的子串的最大下标 思路:后缀数组.搞出height数组后,利用二分去查找就可以 这 ...
- 【剑指offer】面试题39:深度二叉树
def TreeDepth1(root): if None == root: return 0 if None == root.left and None == root.right: return ...
- SVM算法实现(一)
关键字(keywords):SVM 支持向量机 SMO算法 实现 机器学习 假设对SVM原理不是非常懂的,能够先看一下入门的视频,对帮助理解非常实用的,然后再深入一点能够看看这几篇入门文章,作者写得挺 ...
- java main方法背后的故事?(转)
jvm java 看似一种语言,实则一个巨大的体系的王国,开发这么多年了,还是没有搞懂,我以为我懂了,可是过了一段时间又忘了,所以说还是没懂 1.main方法说起 编译完我们的java文件后,需要有个 ...