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. java中string的replace和replace的区别

    乍一看,字面上理解好像replace只替换第一个出现的字符(受javascript的影响),replaceall替换所有的字符,其实大不然,只是替换的用途不一样,简而言之,replace用新串序列替换 ...

  2. WebLogic 数据源密码加密

    先启动域:

  3. <数据挖掘导论>读书笔记11异常检测

    异常检测的目标是发现与大部分其他对象不同的对象.通常,异常对象被称作离群点(Outlier). 异常检测也称偏差检测(Deviation detection),因为异常对象的属性值明显偏离期望的或者常 ...

  4. Greenplum表定义

    GP中的table和其它关系型数据表是一样的,除了数据被分布在不同的segment以外. 在建表的时候必须申明分布键distribution policy. 建表需定义下面几个方面: 1. 指定列和数 ...

  5. CodeIgniter 目录结构详解

    1. myshop 2. |-----system 框架程序目录 3. |-----core 框架的核心程序 4. |-----CodeIgniter.php 引导性文件 5. |-----Commo ...

  6. webstorm中es6语法报错,.vue文件中es6语法报错

    1.webstorm中es6语法报错,解决方法: 打开 Settings => Languages & Frameworks => Javascript把 Javascript L ...

  7. ef——存储过程

      数据库中存在存储过程GetCategory: ALTER proc [dbo].[GetCategory] @cid int as begin select * from Categories w ...

  8. RabbitMQ入门教程系列

    https://blog.csdn.net/column/details/18247.html

  9. JS 浮点数计算

    一.从String中解析浮点数 parseFloat(string) 语法说明 parseFloat是个全局函数,不属于任何对象. parseFloat将它的字符串参数解析成为浮点数并返回.如果在解析 ...

  10. HBase入门教程

    # 背景 最近看到公司一个项目用到hbase, 之前也一直想看下hbase.个人理解Hbase作为一个nosql数据库,逻辑模型感觉跟关系型数据库有点类似.一个table,有row即行,列.不过列是一 ...