Kafka producer在设计上要比consumer简单,不涉及复杂的组管理操作,每个producer都是独立进行工作的,与其他producer实例之间没有关联。Producer的主要功能就是向某个topic的某个分区发送消息,所以首先要确认向topic的哪个分区写入消息——即分区器(partitioner)的功能。Kafka producer提供了一个默认的分区器。对于每条待发送的消息而言,如果该消息指定了key,则partitioner会根据key的哈希值来选择目标分区,将具有相同key的所有消息都路由到相同的分区中;若该消息未指定key,则partitioner使用轮询的方式确认目标分区。另外producer的API赋予了用户自行指定目标分区的权力,即用户可以在消息发送时跳过partitioner直接指定到要发送到的分区。

另外producer也允许用户实现自定义的分区策略而非使用默认的partitioner。

确认分区后,producer要做的第二件事是寻找该分区对应的leader,也就是该分区leader副本所在的Kafka broker。每个topic分区都由若干个副本组成,其中一个副本充当leader角色,只有leader能响应clients发送的请求,剩下的副本中有一部分副本会与leader副本保持同步,即所谓的ISR(In-Sync Replicas, 副本同步队列)。因此,在发送消息时,producer可以有多种选择来实现消息发送,例如不等待任何副本的响应便返回成功,或者只是等待leader副本响应写入操作后再返回成功。

补充副本概念:

副本(Replication)

同一个partition可能会有多个replication(对应server.properties 配置中的 default.replication.factor=N)。没有replication的情况下,一旦broker 宕机,其上所有 patition 的数据都不可被消费,同时producer也不能再将数据存于其上的patition。引入replication之后,同一个partition可能会有多个replication,而这时需要在这些replication之间选出一个leader,producer和consumer只与这个leader交互,其它replication作为follower从leader 中复制数据。

Producer写入流程

1)producer先从zookeeper的 “/brokers/…/state”节点找到该partition的leader

2)producer将消息发送给该leader

3)leader将消息写入本地log

4)followers从leader pull消息,写入本地log后向leader发送ACK

5)leader收到所有ISR中的replication的ACK后,增加HW(high watermark,最后commit 的offset)并向producer发送ACK

Producer发送消息

在Java版代码中,producer首先使用一个线程(用户主线程,也就是用户启动producer的线程)将待发送的消息封装进一个ProducerRecord类实例,然后将其序列化之后发送给partitioner,再由后者确定了目标分区后一同发送到位于producer程序中的一块内存缓冲池中。而producer的另一个工作线程(I/O发送线程,也称Sender线程)则负责实时地从该缓冲区中提取准备就绪的消息封装进一个批次(batch),统一发送给对应的broker。

Kafka producer发送消息的主方法是send方法,producer在底层完全实现了异步化发送,并且通过Java提供的Future同时实现了同步发送和异步发送+回调(Callback)(默认异步)两种发送方式。最后producer程序结束时需要关闭producer。

acks参数(用来平衡吞吐量与可靠性):

producers可以一步的并行向kafka发送消息,但是通常producer在发送完消息之后会得到一个响应,返回的是offset值(metadata)或者发送过程中遇到的错误(exception)。这其中有个非常重要的参数“request.required.acks”,这个参数决定了producer要求leader partition收到确认的副本个数:

如果acks设置为0,表示producer不会等待broker的响应,所以,producer无法知道消息是否发生成功,这样有可能导致数据丢失,但同时,acks值为0会得到最大的系统吞吐量。一般这种情况下允许消息丢失,如统计服务器日志等;

若acks设置为1,表示producer会在leader partition收到消息时得到broker的一个确认,这样会有更好的可靠性,因为客户端会等待知道broker确认收到消息。此时,当发送消息时,leader broker仅将该消息写入本地日志,然后便发送响应结果给producer,而无需等待ISR中其他副本写入该消息;

若设置为-1或者all,producer会在所有备份的partition收到消息时得到broker的确认,这个设置可以得到最高的可靠性保证。此时,当发送消息时,leader broker不仅会将消息写入本地日志,同时还会等待ISR中所有其他副本都成功写入它们各自的本地日志后,才发送响应结果给producer。

buffer.memory参数:

指定producer端用于缓存消息的缓冲区的大小,单位是字节,默认32M,采用异步发送消息的架构,Java版Producer启动时会首先创建一块内存缓冲区用于保存待发送消息,然后由另一个专属线程负责从缓冲区中读取消息执行真正的发送,这部分内存空间的大小就是由buffer.memory参数指定。该参数指定的内存大小几乎可以认为是producer程序使用的内存大小,若producer程序要给很多分区发送消息,那么就需要仔细设置该参数防止过小的内存缓冲区降低了producer程序整体的吞吐量。

batch.size参数:

batch.size是producer调优吞吐量与延时性能最重要的参数之一,producer会将发往同一分区的多条消息封装进一个batch中,当batch满了或者batch没满(linger.ms参数=0,默认消息立即发送)producer会发送该batch。

Batch小,吞吐量低,延时低,Batch大,吞吐量高,延时高

Batch.size默认为16KB。

request.timeout.ms参数:

当producer发送请求给broker后,broker需要在规定时间范围内将处理结果返回给producer。超时时间默认30s。

自定义分区机制

  1. 在producer程序中创建一个类,实现org.apache.kafka.clients.producer.Partitioner接口,主要分区逻辑在Partitioner.partition中实现。入参(topic, key, keyBytes, value, valueBytes, Cluster);
  2. 在用于构造KafkaProducer的Properties对象中设置partitioner.class参数。

序列化

网络上发送数据都是以字节的形式,kafka也不例外,Apache Kafka支持用户给broker发送各种类型消息,如字符串、整数、数组或任意对象类型,序列化器serializer负责在producer发送前将消息转换成字节数组;解序列化器deserializer则用于将consumer接收到的字节数组转换成相应的对象。

Kafka生产者producer简要总结的更多相关文章

  1. 【转】 详解Kafka生产者Producer配置

    粘贴一下这个配置,与我自己的程序做对比,看看能不能完善我的异步带代码:   -----------------------------------------    详解Kafka生产者Produce ...

  2. kafka 0.8.2 消息生产者 producer

    package com.hashleaf.kafka; import java.util.Properties; import kafka.javaapi.producer.Producer; imp ...

  3. kafka 0.10.2 消息生产者(producer)

    package cn.xiaojf.kafka.producer; import org.apache.kafka.clients.producer.*; import org.apache.kafk ...

  4. kafka集群搭建和使用Java写kafka生产者消费者

    1 kafka集群搭建 1.zookeeper集群  搭建在110, 111,112 2.kafka使用3个节点110, 111,112 修改配置文件config/server.properties ...

  5. Kafka的Producer和Consumer源码学习

    先解释下两个概念: high watermark (HW) 它表示已经被commited的最后一个message offset(所谓commited, 应该是ISR中所有replica都已写入),HW ...

  6. Kafka学习-Producer和Customer

    在上一篇kafka入门的基础之上,本篇主要介绍Kafka的生产者和消费者. Kafka 生产者 kafka Producer发布消息记录到Kakfa集群.生产者是线程安全的,可以在多个线程之间共享生产 ...

  7. Kafka生产者-向Kafka中写入数据

    (1)生产者概览 (1)不同的应用场景对消息有不同的需求,即是否允许消息丢失.重复.延迟以及吞吐量的要求.不同场景对Kafka生产者的API使用和配置会有直接的影响. 例子1:信用卡事务处理系统,不允 ...

  8. Python 使用python-kafka类库开发kafka生产者&消费者&客户端

    使用python-kafka类库开发kafka生产者&消费者&客户端   By: 授客 QQ:1033553122       1.测试环境 python 3.4 zookeeper- ...

  9. Kafka遇到30042ms has passed since batch creation plus linger time at org.apache.kafka.clients.producer.internals.FutureRecordMetadata.valueOrError(FutureRecordMetadata.java:94)

    问题描述: 运行生产者线程的时候显示如下错误信息: Expiring 1 record(s) for XXX-0: 30042 ms has passed since batch creation p ...

随机推荐

  1. [Mysql 查询语句]——集合函数

    count() 统计记录条数 select count(*) from student; +----------+ | count(*) | +----------+ | +----------+ s ...

  2. 如何将本地文件通过终端上传到linux服务器或从linux主机下载文件到本地

    第一种方式: SecureCRT下上传文件只需在shell终端仿真器中输入命令“rz”,即可从弹出的对话框中选择本地磁盘上的文件,利用Zmodem上传到服务器当前路径下.下载文件只需在shell终端仿 ...

  3. 四大CPU体系结构:ARM、X86/Atom、MIPS、PowerPC

    补充介绍一下RISC:RISC(reduced instruction set computer,精简指令集计算机)是一种执行较少类型计算机指令的微处理器,起源于80年代的MIPS主机(即RISC机) ...

  4. 【C#】RGB转CMYK

    由于目前印兔项目中的在线设计功能设计出来的产品颜色模式不确定,但是客户设计出来的产品需要发送到印厂的客户端去下载并且印刷,只有CMYK颜色模式的产品才能正确印刷,所以需要判断产品的颜色模式是否为CMY ...

  5. 关于UI回调Invoker的实现(二)

    上篇我说到,光有一个IOperation*的指针,是无法记录这么多事件的.由于无法确定要把回调绑定到哪个事件上,因此,我们需要引入一个中间的传递机制. 没有看到前面的请先查阅上一篇 关于UI回调Inv ...

  6. SpringBoot Mybatis的驼峰命名

    开启驼峰命名的方法 第一种方式: 可以在配置类中进行配置.配置的Demo如下: @Bean(name="sqlSessionFactory") public SqlSessionF ...

  7. SpringMVC学习笔记:SpringMVC框架的执行流程

    一.MVC设计模式 二.SpringMVC框架介绍 三.SpringMVC环境搭建 四.SpringMVC框架的请求处理流程及体系结构

  8. mybatis之typehandles

    mybatis之typehandles 无论是Mybatis在预处理语句PreparedStatement中设置一个参数时,还是从结果集中取出一个值时,都会用类型处理器将获取的值以合适的方式转换成ja ...

  9. Spring入门(三)— AOP注解、jdbc模板、事务

    一.AOP注解开发 导入jar包 aop联盟包. aspectJ实现包 . spring-aop-xxx.jar . spring-aspect-xxx.jar 导入约束 aop约束 托管扩展类和被扩 ...

  10. js图片跟随鼠标移动

    <div id="wrapper"><img src="http://images.cnblogs.com/cnblogs_com/rain-null/ ...