来源:https://www.zybuluo.com/jewes/note/63925

@jewes 2015-01-17 20:36 字数 1967 阅读 1093

Kafka Producer相关代码分析

kafka


Kafka Producer将用户的消息发送到Kafka集群(准确讲是发送到Broker)。本文将分析Producer相关的代码实现。

 

类kafka.producer.Producer

如果你自己实现Kafka客户端来发送消息的话,你就是用到这个类提供的接口来发送消息。(如果你对如何利用Producer API来发送消息还不是很熟悉的话,可以参看官方的例子)。这个类提供了同步和异步两种方式来发送消息。

异步发送消息是基于同步发送消息的接口来实现的。异步发送消息的实现很简单,客户端消息发送过来以后,先放入到一个队列中然后就返回了。Producer再开启一个线程(ProducerSendThread)不断从队列中取出消息,然后调用同步发送消息的接口将消息发送给Broker。

Producer发送同步消息是委托给EventHandler做的,EventHandler是个接口,具体实现为DefaultEventHandler。它们的简化类图如下: 

可以看到,Producer类中的成员producerSendThread和queue是为了发送异步消息的,eventHandler是为了发送同步消息的,当然异步消息也需要它。KeyedMessage是封装了用户发送的消息。Seq是Scala中的序列,可以看成是Java中的List。

KeyedMessage的简化类图如下: 

 

类DefaultEventHandler

DefaultEventHandler是接口EventHandler唯一的实现。从上一节可以看到Producer发送给EventHandler的消息格式为KeyedMessage。我们来看看在将KeyedMessage发送给Broker之前需要做哪些工作。

 

序列化

KeyedMessage中的KV是由用户指定的自定义类型,而在发送给broker的时候是以二进制流来发送,因此还需要将用户自定类型的数据转换为二进制流。在初始化Producer的时候需要配置serializer.class,它就是用来处理这个事情的。此外,还要把多条Message组合成MessageSet并按照用户指定的压缩方式进行压缩。

 

找到对应的broker

KeyedMessage中指定了该Message的topic,而一个topic可以有多个partition,每个partition有多个replica,由多个Broker来管理,这些Broker中有一个leader。只有leader broker能够响应客户端的读写请求。

由此可见,在将KeyedMessage发送给broker之前,必须找到该条Message对应的leader broker,具体步骤为: 
1. 找出该topic的所有partition, 
2. 找出该KeyedMessage应该发送到的那个partition,在初始化Producer的时候配置partitioner.class就是用来对Message进行分区的 
3. 找出对应partition所在的leader broker。

最后,DefaultEventHandler将序列化后的Message封装成ProducerRequest,它自身并没有将ProducerRequest发送给broker的逻辑,而是将其交给SyncProducer来继续后面发送的流程。

 

ProducerPool, SyncProducer和BlockingChannel

它们在一起是完成最后的数据发送任务。先来看它们的类图: 
 
ProducerPool中有一个HashMap,其key为brokerid,value为连接到这个broker的SyncProducer。因此ProducerPool的更准确名字应该为SyncProducerPool。

BlockingChannel可以看成是一个Socket客户端,它有两个成员变量分别是机器名和端口号。它的connect方法会打开到对应机器的socket。它的send方法可以发送RequestOrResponse,它是真正发送数据的地方。

SyncProducer提供了两个send方法,分别用来发送ProducerRequest和TopicMetadataRequest。它内部是调用了blockingChannel来发送数据的。

 

小结

Producer发送数据的简化序列图如下:
从图中可见,各个类的职责明确,BlockingChannel负责最底层的数据发送,SyncProducer负责将Request发送到一个指定的Broker那里,DefaultEventHandler负责数据转换和选择正确的Broker,直接给客户端使用的Producer则在此基础上提供了同步和异步两种发送方式。

Kafka Producer相关代码分析【转】的更多相关文章

  1. 线程相关代码分析->常见面试题(一、Thead类)

    As always,我们直接看jdk的代码切入: 首先是最简单的Runnable接口: public interface Runnable { public abstract void run(); ...

  2. AngularJS PhoneCat代码分析

    转载自:http://www.tuicool.com/articles/ym6Jfen AngularJS 官方网站提供了一个用于学习的示例项目:PhoneCat.这是一个Web应用,用户可以浏览一些 ...

  3. Spring AOP实现声明式事务代码分析

    众所周知,Spring的声明式事务是利用AOP手段实现的,所谓"深入一点,你会更快乐",本文试图给出相关代码分析. AOP联盟为增强定义了org.aopalliance.aop.A ...

  4. kafka C客户端librdkafka producer源码分析

    from:http://www.cnblogs.com/xhcqwl/p/3905412.html kafka C客户端librdkafka producer源码分析 简介 kafka网站上提供了C语 ...

  5. Linux内核启动代码分析二之开发板相关驱动程序加载分析

    Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c  start_ke ...

  6. 关于高并发下kafka producer send异步发送耗时问题的分析

    最近开发网关服务的过程当中,需要用到kafka转发消息与保存日志,在进行压测的过程中由于是多线程并发操作kafka producer 进行异步send,发现send耗时有时会达到几十毫秒的阻塞,很大程 ...

  7. 6张图为你分析Kafka Producer 消息缓存模型

    摘要:发送消息的时候, 当Broker挂掉了,消息体还能写入到消息缓存中吗? 本文分享自华为云社区<图解Kafka Producer 消息缓存模型>,作者:石臻臻的杂货铺. 在阅读本文之前 ...

  8. [window] 使用Pyhton轻便好用的spyder IDE进行代码分析时如何指定相关的配置文件

    spyder 使用pylint这个第三方库进行代码检查,其实pylint使用的代码规范默认也是pep8,不过该库还有 其它用途,在这里我专门写写在代码分析时,如何指定配置文件 一般来说,使用spyde ...

  9. ActiveMQ、RabbitMQ、RocketMQ、Kafka四种消息中间件分析介绍

    ActiveMQ.RabbitMQ.RocketMQ.Kafka四种消息中间件分析介绍 我们从四种消息中间件的介绍到基本使用,以及高可用,消息重复性,消息丢失,消息顺序性能方面进行分析介绍! 一.消息 ...

随机推荐

  1. 【BZOJ-1923】外星千足虫 高斯消元 + xor方程组

    1923: [Sdoi2010]外星千足虫 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 766  Solved: 485[Submit][Status ...

  2. 【BZOJ-1497】最大获利 最大流

    1497: [NOI2006]最大获利 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 3800  Solved: 1848[Submit][Status] ...

  3. [Noi2016十连测第五场]二进制的世界

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

  4. Python基础0:变量 赋值 表达式和运算符

    变量: 前面我们在使用print()输出内容的时候,如果内容很长,后面要再次输出的时候,就需重新在输入一遍. 如果给输出的内容起个简单的别名.这样我们用简短的别名来代替长内容,下次要输出的时候就直接使 ...

  5. hdu5187 奇怪题

    本来很水的,答案就是(2^n)-2,但是写坑了QAQ 因为原题要求答案要mod P,一开始我是这么干的: LL ans=pow_mod(,N,P); ans=(ans-)%P; ) ans=%P; p ...

  6. [NOIP2015] 提高组 洛谷P2661 信息传递

    题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...

  7. osquery An Operating System Instrumentation Framewor

    catalog . Getting Started . install guide for OS X and Linux . Features Overview . Logging . query e ...

  8. C# 字符串处理

     1.比较字符串 String 类提供了一系列的方法用于字符串的比较,如CompareTo 和 Equals方法等. ① CompareTo : 如果参数的值与此实例相等,则返回0:如果此实例大于参数 ...

  9. SampleDateFormat进行日期格式化

    我们生成的日期 ,可能不是我们想要的格式,这时候,就要用到SampleDateFormat类的format方法转换一下, SampleDateFormat是java.text包下的一个常用日期类 这个 ...

  10. 利用 Django REST framework 编写 RESTful API

    利用 Django REST framework 编写 RESTful API Updateat 2015/12/3: 增加 filter 最近在玩 Django,不得不说 rest_framewor ...