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. 搭建Eclipse和MyEclipse的开发环境

    主要步骤: 下载并配置Eclipse 建立并运行一个简单的javaSE项目 下载并破解MyEclipse 整合Eclipse和MyEclipse 开发环境和Tomcat结合 关于这个配置也可以参考:h ...

  2. JS实现一位数显示为两位

    使用js脚本实现页面一位数字显示为两位,不足两位前面加“0”. function fix(num, length) { return ('' + num).length < length ? ( ...

  3. SpringBoot 初体验

    1.Spring Boot 简介 简化Spring应用开发的一个框架 整个Spring技术栈的一个大整合 J2EE开发的一站式解决方案 2.微服务 2014, martin fowler 微服务:架构 ...

  4. [LeetCode]Delete and Earn题解(动态规划)

    Delete and Earn Given an array nums of integers, you can perform operations on the array. In each op ...

  5. git杂记-分支简介

    分支创建 //只创建分支不切换: $ git branch testing //创建并切换分支$ git checkout -b iss53 查看各个分支的指向对象 $ git log --oneli ...

  6. 关于StringBuffe()长度和初始化长度的问题归纳

    晚上做一个习题,发现了一个关于StringBuffer()长度的问题 根据理解大致可以归为以下知识. 直接上代码分析吧 public class StringBuffer_length_capacit ...

  7. C# 注释&SQL注释

    SQL注释: 1.单行注释:--单行注释 2.多行注释:/*多行 注释*/ C#注释: 1.单行注释://单行注释 2.多行注释:/*多行 注释*/ 3.说明注释:///<summary> ...

  8. Hibernate详讲

    一 概述 1.JPA Java Persistence API,是Java EE为ORM框架定义的规范,任何使用java语言的ORM框架都必须实现该规范.Hibernate/Mybatis都是是JPA ...

  9. MongoDB 安装成为Windows服务

    使用以下命令将MongoDB安装成为Windows服务. mongod --logpath d:\data\logs.txt --dbpath d:\data --directoryperdb --s ...

  10. 转:问题解决:The project cannot be built until build path errors are resolved

    转自:http://blog.csdn.net/marty_zhu/article/details/2566299 今天在eclipse里遇到这个问题,之前也遇到过,不过,通过clean一下项目,或者 ...