一、Kafka消费者源码介绍

1.分区消费模式源码介绍

分区消费模式直接由客户端(任何高级语言编写)使用Kafka提供的协议向服务器发送RPC请求获取数据,服务器接受到客户端的RPC请求后,将数据构造成RPC响应,返回给客户端,客户端解析相应的RPC响应获取数据。
Kafka支持的协议众多,使用比较重要的有:
获取消息的FetchRequest和FetchResponse
获取offset的OffsetRequest和OffsetResponse
提交offset的OffsetCommitRequest和OffsetCommitResponse
获取Metadata的Metadata Request和Metadata Response
生产消息的ProducerRequest和ProducerResponse

2.组消费模式源码介绍

3.两种消费模式服务器端源码对比

分区消费模式具有以下特点:
指定消费topic、partition和offset通过向服务器发送RPC请求进行消费;
需要自己提交offset;
需要自己处理各种错误,如:leader切换错误
需要自己处理消费者负载均衡策略
组消费模式具有以下特点:
最终也是通过向服务器发送RPC请求完成的(和分区消费模式一样);
组消费模式由Kafka服务器端处理各种错误,然后将消息放入队列再封装为迭代器(队列为FetchedDataChunk对象) ,客户端只需在迭代器上迭代取出消息;
由Kafka服务器端周期性的通过scheduler提交当前消费的offset,无需客户端负责

Kafka服务器端处理消费者负载均衡
监控工具Kafka Offset Monitor 和Kafka Manager 均是基于组消费模式;

所以,尽可能使用组消费模式,除非你需要:
自己管理offset(比如为了实现消息投递的其他语义);
自己处理各种错误(根据自己业务的需求);

二、Kafka生产者源码介绍

1.同步发送模式源码介绍

2.异步发送模式源码介绍

3.两种生产模式服务器端源码对比

同步发送模式具有以下特点:
同步的向服务器发送RPC请求进行生产;
发送错误可以重试;
可以向客户端发送ack;
异步发送模式具有以下特点:
最终也是通过向服务器发送RPC请求完成的(和同步发送模式一样);
异步发送模式先将一定量消息放入队列中,待达到一定数量后再一起发送;
异步发送模式不支持发送ack,但是Client可以调用回调函数获取发送结果;

所以,性能比较高的场景使用异步发送,准确性要求高的场景使用同步发送

三、Kafka Server Reactor设计模型

1.认识Java NIO

Java NIO由以下几个核心部分组成 :
Channels;
Buffers;
Selectors

Selector允许单线程处理多个 Channel。使用Selector,首先得向Selector注册Channel,然后调用它的select()方法。此方法会一直阻塞到某个注册的Channel有事件就绪。一旦这个方法返回,线程就可以处理这些事件,事件的例子如新连接进来,数据接收等。
下图为一个单线程中使用一个Selector处理3个Channel:
 

2.认识Linux epoll模型

epoll 是一种IO多路复用技术 ,在linux内核中广泛使用。常见的三种IO多路复用技术为select模型、poll模型和epoll模型。
select 模型需要轮询所有的套接字查看是否有事件发生 。缺点: (1)套接字最大支持1024个;(2)主动轮询效率很低;(3) 事件发生后需要将套接字从内核空间拷贝到用户空间,效率低
poll模型和select模型原理一样,但是修正了select模型最大套接字限制的缺点;
epoll模型修改主动轮询为被动通知,当有事件发生时,被动接收通知。所以epoll模型注册套接字后,主程序可以做其他事情,当事件发生时,接收到通知后再去处理。修正了select模型的三个缺点(第三点使用共享内存修正)。
Java NIO的Selector模型底层使用的就是epoll IO多路复用模型

3.Kafka Server Reactor模型

Kafka SocketServer是基于Java NIO开发的,采用了Reactor的模式(已被大量实践证明非常高效,在Netty和Mina中广泛使用)。Kafka Reactor的模式包含三种角色:
Acceptor;
Processor ;
Handler;
Kafka Reacator包含了1个Acceptor负责接受客户端请求,N个Processor线程负责读写数据(为每个Connection创建出一个Processor去单独处理,每个Processor中均引用独立的Selector),M个Handler来处理业务逻辑。在Acceptor和Processor,Processor和Handler之间都有队列来缓冲请求。

Acceptor的主要职责是监听客户端的连接请求,并建立和客户端的数据传输通道,然后为这个客户端指定一个Processor,它的工作就到此结束,这样它就可以去响应下一个客户端的连接请求了;
Processor的主要职责是负责从客户端读取数据和将响应返回给客户端,它本身不处理具体的业务逻辑,每个Processor都有一个Selector,用来监听多个客户端,因此可以非阻塞地处理多个客户端的读写请求,Processor将数据放入RequestChannel的RequestQueue 中和从ResponseQueue读取响应 ;
Handler(kafka.server.KafkaRequestHandler,kafka.server.KafkaApis)的职责是从RequestChannel中的RequestQueue取出Request,处理以后再将Response添加到RequestChannel中的ResponseQueue中;

四、Kafka Partition Leader选举机制

1.大数据常用的选主机制

Leader选举算法非常多,大数据领域常用的有 以下两种:
Zab(zookeeper使用);
Raft;
……

它们都是Paxos算法的变种。

Zab协议有四个阶段:
Leader election;
Discovery(或者epoch establish);
Synchronization(或者sync with followers)
Broadcast
比如3个节点选举leader,编号为1,2,3。1先启动,选择自己为leader,然后2启动首先也选择自己为 leader,由于1,2都没过半,选择编号大的为leader,所以1,2都选择2为leader,然后3启动发现1,2已经协商好且数量过半,于是3也选择2为leader,leader选举结束。

在Raft中,任何时候一个服务器可以扮演下面角色之一
Leader: 处理所有客户端交互,日志复制等,一般只有一个Leader;
Follower: 类似选民,完全被动
Candidate候选人: 可以被选为一个新的领导人

启动时在集群中指定一些机器为Candidate ,然后Candidate开始向其他机器(尤其是Follower)拉票,当某一个Candidate的票数超过半数,它就成为leader。

2.常用选主机制的缺点

由于Kafka集群依赖zookeeper集群,所以最简单最直观的方案是,所有Follower都在ZooKeeper上设置一个Watch,一旦Leader宕机,其对应的ephemeral znode会自动删除,此时所有Follower都尝试创建该节点,而创建成功者(ZooKeeper保证只有一个能创建成功)即是新的Leader,其它Replica即为Follower。

前面的方案有以下缺点:
split-brain (脑裂): 这是由ZooKeeper的特性引起的,虽然ZooKeeper能保证所有Watch按顺序触发,但并不能保证同一时刻所有Replica“看”到的状态是一样的,这就可能造成不同Replica的响应不一致 ;
herd effect (羊群效应): 如果宕机的那个Broker上的Partition比较多,会造成多个Watch被触发,造成集群内大量的调整;
ZooKeeper负载过重 : 每个Replica都要为此在ZooKeeper上注册一个Watch,当集群规模增加到几千个Partition时ZooKeeper负载会过重

3.Kafka Partition选主机制

Kafka 的Leader Election方案解决了上述问题,它在所有broker中选出一个controller,所有Partition的Leader选举都由controller决定。controller会将Leader的改变直接通过RPC的方式(比ZooKeeper Queue的方式更高效)通知需为此作为响应的Broker。
 

Kafka 集群controller的选举过程如下 :
每个Broker都会在Controller Path (/controller)上注册一个Watch。当前Controller失败时,对应的Controller Path会自动消失(因为它是ephemeral Node),此时该Watch被fire,所有“活”着的Broker都会去竞选成为新的Controller(创建新的Controller Path),但是只会有一个竞选成功(这点由Zookeeper保证)。竞选成功者即为新的Leader,竞选失败者则重新在新的Controller Path上注册Watch。因为Zookeeper的Watch是一次性的,被fire一次之后即失效,所以需要重新注册。

Kafka partition leader的选举过程如下 (由controller执行):
从Zookeeper中读取当前分区的所有ISR(in-sync replicas)集合
调用配置的分区选择算法选择分区的leader

所以,对于下图partition 0先选择broker 2,之后选择broker 0作为leader;对于partition 1 先选择broker 0,之后选择broker 1作为leader;partition 2先选择broker 1,之后选择broker 2作为leader。

四、Kafka 核心源码剖析的更多相关文章

  1. HashMap的结构以及核心源码分析

    摘要 对于Java开发人员来说,能够熟练地掌握java的集合类是必须的,本节想要跟大家共同学习一下JDK1.8中HashMap的底层实现与源码分析.HashMap是开发中使用频率最高的用于映射(键值对 ...

  2. HTTP流量神器Goreplay核心源码详解

    摘要:Goreplay 前称是 Gor,一个简单的 TCP/HTTP 流量录制及重放的工具,主要用 Go 语言编写. 本文分享自华为云社区<流量回放工具之 goreplay 核心源码分析> ...

  3. Android版数据结构与算法(五):LinkedHashMap核心源码彻底分析

    版权声明:本文出自汪磊的博客,未经作者允许禁止转载. 上一篇基于哈希表实现HashMap核心源码彻底分析 分析了HashMap的源码,主要分析了扩容机制,如果感兴趣的可以去看看,扩容机制那几行最难懂的 ...

  4. Java内存管理-掌握类加载器的核心源码和设计模式(六)

    勿在流沙筑高台,出来混迟早要还的. 做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 上一篇文章介绍了类加载器分类以及类加载器的双亲委派模型,让我们能够从整体上对类加载器有 ...

  5. 手撕spring核心源码,彻底搞懂spring流程

    引子 十几年前,刚工作不久的程序员还能过着很轻松的日子.记得那时候公司里有些开发和测试的女孩子,经常有问题解决不了的,不管什么领域的问题找到我,我都能帮她们解决.但是那时候我没有主动学习技术的意识,只 ...

  6. 并发编程之 SynchronousQueue 核心源码分析

    前言 SynchronousQueue 是一个普通用户不怎么常用的队列,通常在创建无界线程池(Executors.newCachedThreadPool())的时候使用,也就是那个非常危险的线程池 ^ ...

  7. iOS 开源库系列 Aspects核心源码分析---面向切面编程之疯狂的 Aspects

    Aspects的源码学习,我学到的有几下几点 Objective-C Runtime 理解OC的消息分发机制 KVO中的指针交换技术 Block 在内存中的数据结构 const 的修饰区别 block ...

  8. Backbone事件机制核心源码(仅包含Events、Model模块)

    一.应用场景 为了改善酷版139邮箱的代码结构,引入backbone的事件机制,按照MVC的分层思想搭建酷版云邮局的代码框架.力求在保持酷版轻量级的基础上提高代码的可维护性.   二.遗留问题 1.b ...

  9. 6 手写Java LinkedHashMap 核心源码

    概述 LinkedHashMap是Java中常用的数据结构之一,安卓中的LruCache缓存,底层使用的就是LinkedHashMap,LRU(Least Recently Used)算法,即最近最少 ...

随机推荐

  1. week3b:个人博客作业

    vs2013的初步使用 由于自己在写这篇博客的时候已经把vs2013安装完毕,就我写了. 这是2013的使用步骤 第一步 注释 箭头指的方向是“点击” 第二步 第三步 第四步 第5步 第六步 最后点击 ...

  2. Android 布局类控件

    Android提供6种布局类的控件:LinearLayout.TableLayout.GridLayout.FrameLayout.RalativeLayout.AbsoluteLayout 网上搜到 ...

  3. .NET 切面编程 PostSharp

    目录 概念 实现方式 .Net平台的切面实现 PostSharp示例 概念 Aspect-Oriented Programming(AOP):想想OOP是不是有些熟悉,AOP翻译过来的意思就是面向切面 ...

  4. git bash使用(markdown版)

    前言 我是通过这个来学习的.个人愚笨,琢磨了半天,终于搞通了,醉了醉了,以前一直使用svn,用git确实有点水土不服.本文以如何使用git为主来展开,不涉及太多理论. git是分布式的版本管理.什么叫 ...

  5. windows结束端口对应的进程

    netstat -ano |findstr " //window查看端口占用 taskkill /pid 54828taskkill /F /pid 54828 //强制中止 转载请注明博客 ...

  6. Linux命令01

    Linux简介及Ubuntu安装 Linux,免费开源,多用户多任务系统.基于Linux有多个版本的衍生.RedHat.Ubuntu.Debian 安装VMware或VirtualBox虚拟机.具体安 ...

  7. Lottie开源库实现Android动画效果

    Lottie简介 Lottie是一个支持Android.iOS.React Native,并由Adobe After Effects制作aep格式的动画,然后经由bodymovin插件转化渲染为jso ...

  8. Integer to Roman - LeetCode

    目录 题目链接 注意点 解法 小结 题目链接 Integer to Roman - LeetCode 注意点 考虑输入为0的情况 解法 解法一:从大到小考虑1000,900,500,400,100,9 ...

  9. loj Snakes 的 Naïve Graph 【数论】

    题目链接 loj 题解 感谢珂神的指导orz 观察式子\(i \times j \equiv 1 \pmod m\),显然\(i,j\)是模\(m\)意义下成对的逆元,只需统计模\(m\)意义下存在逆 ...

  10. Linux及安全实践四——ELF文件格式分析

    Linux及安全实践四——ELF文件格式分析 一.ELF文件格式概述 1. ELF:是一种对象文件的格式,用于定义不同类型的对象文件中都放了什么东西.以及都以什么样的格式去放这些东西. 二.分析一个E ...