原文地址: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提供了下面功能:

  1. 能够将多个消息缓存到本地队列里。然后异步的批量发送到broker,能够通过參数producer.type=async做到。缓存的大小能够通过一些參数指定:queue.timebatch.size。一个后台线程((kafka.producer.async.ProducerSendThread)从队列中取出数据并让kafka.producer.EventHandler将消息发送到broker,也能够通过參数event.handler定制handler。在producer端处理数据的不同的阶段注冊处理器,比方能够对这一过程进行日志追踪。或进行一些监控。仅仅需实现kafka.producer.async.CallbackHandler接口,并在callback.handler中配置。
  2. 自己编写Encoder来序列化消息,仅仅需实现以下这个接口。默认的Encoder是kafka.serializer.DefaultEncoder
    interface Encoder<T> {
    public Message toMessage(T data);
    }
  3. 提供了基于Zookeeper的broker自己主动感知能力,能够通过參数zk.connect实现。假设不使用Zookeeper。也能够使用broker.list參数指定一个静态的brokers列表,这样消息将被随机的发送到一个broker上,一旦选中的broker失败了,消息发送也就失败了。

  4. 通过分区函数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的更多相关文章

  1. 漫游Kafka实战篇之客户端API

    Kafka Producer APIs 旧版的Procuder API有两种:kafka.producer.SyncProducer和kafka.producer.async.AsyncProduce ...

  2. 漫游kafka实战篇之搭建Kafka开发环境

    上篇文章中我们搭建了kafka的服务器,并可以使用Kafka的命令行工具创建topic,发送和接收消息.下面我们来搭建kafka的开发环境.   添加依赖   搭建开发环境需要引入kafka的jar包 ...

  3. 漫游Kafka实战篇之搭建Kafka运行环境

    接下来一步一步搭建Kafka运行环境. Step 1: 下载Kafka 点击下载最新的版本并解压. > tar -xzf kafka_2.9.2-0.8.1.1.tgz > cd kafk ...

  4. 漫游Kafka实战篇之搭建Kafka运行环境(2)

    接下来一步一步搭建Kafka运行环境. Step 1: 下载Kafka 点击下载最新的版本并解压. > tar -xzf kafka_2.9.2-0.8.1.1.tgz > cd kafk ...

  5. 漫游kafka实战篇之搭建Kafka开发环境(3)

    上篇文章中我们搭建了kafka的服务器,并可以使用Kafka的命令行工具创建topic,发送和接收消息.下面我们来搭建kafka的开发环境.   添加依赖   搭建开发环境需要引入kafka的jar包 ...

  6. 漫游Kafka设计篇之性能优化

    Kafka在提高效率方面做了很大努力.Kafka的一个主要使用场景是处理网站活动日志,吞吐量是非常大的,每个页面都会产生好多次写操作.读方面,假设每个消息只被消费一次,读的量的也是很大的,Kafka也 ...

  7. 漫游Kafka设计篇之性能优化(7)

    Kafka在提高效率方面做了很大努力.Kafka的一个主要使用场景是处理网站活动日志,吞吐量是非常大的,每个页面都会产生好多次写操作.读方面,假设每个消息只被消费一次,读的量的也是很大的,Kafka也 ...

  8. 漫游Kafka实现篇之消息和日志

    消息格式 消息由一个固定长度的头部和可变长度的字节数组组成.头部包含了一个版本号和CRC32校验码. /** * 具有N个字节的消息的格式如下 * * 如果版本号是0 * * 1. 1个字节的 &qu ...

  9. 漫游Kafka设计篇之主从同步

    Kafka允许topic的分区拥有若干副本,这个数量是可以配置的,你可以为每个topci配置副本的数量.Kafka会自动在每个个副本上备份数据,所以当一个节点down掉时数据依然是可用的. Kafka ...

随机推荐

  1. Google Maps Android API v2 (3)- 地图添加到Android应用程序

    添加地图的基本步骤是: (一旦)按照以下步骤[入门] [开始],获得API,获取密钥所需的属性,并添加到您的Android清单. 添加一个碎片对象 要处理地图的活动.做到这一点最简单的方法是增加一个  ...

  2. CentOS 安装memcached

    一,安装libevent 安装位置 /usr/lib #tar -zxvf libevent-2.0.21-stable.tar.gz # cdlibevent-2.0.21 # ./configur ...

  3. freemarker里的分页--ftl文件的传值

    在上一篇<freemarker里的分页--ftl文件>中我们讨论了分页的逻辑,在这一篇文章中,我们開始看一下怎样进行ftl的传值 或许你在上一篇文章中已经发现了端倪.是的,不错,我们须要一 ...

  4. udacity android 学习笔记: lesson 4 part b

    udacity android 学习笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...

  5. 于Heroku平台部署maven webapp(java web)工程

    眼下,需要Heroku上述部署java web工程,该项目必须使用maven管理 一:新maven webapp工程 编者pom.xml档,增加下面的配置为例, <project xmlns=& ...

  6. Effective C++ 条款44

    本节条款的标题是:将与參数无关的代码抽离templates 学习本节条款首先须要明确一件事情,那就是模板实例化的过程会不会反复? 我们来举个样例: #include<iostream> u ...

  7. HSQLDB相关信息及用法汇总

    运行模式 说明 启动命令 JDBC例 内存(Memory-Only)模式 所有数据都在内存里操作.应用程序退出后则数据被销毁.无需另外启动HSQLDB Server 启动方式1:通过程序中首次调用Co ...

  8. 【IPC第二个进程间通信】管道Pipe

    IPC进程间通信+管道Pipe                IPC(Inter-Process Communication,进程间通信).         管道用于进程间共享数据,事实上质是共享内存 ...

  9. asm 盘头损失,破坏

    BUG 14693394 – ORA-15196: INVALID ASM BLOCK HEADER [KFC.C:26076] [ENDIAN_KFBH] BUG 14758001 – ORA-15 ...

  10. string 至 Color 转换演示示例:

    string colorstr = "#FF4D4D4D";string hex = colorstr.ToString().Replace("#", &quo ...