Kafka之ReplicaManager(1)
基于Kafka 0.9.0版
ReplicaManager需要做什么
Replicated Logs
Kafka的partition可以看成是一个replicated log, 每个replica就是这个replicated log其中的一个log。多个replica是为了容忍机器故障,因此同一个partition的不同replica需要被分配到不同的broker上。所以,对于一个partition,broker id即可唯一代表一个replica,也被当作replica id。
为了一致性,Kafka在同一个partition的replicas中选出一个作为leader,由它接受client的所有读写请求,而其它的replica作为follower,从leader处拉取数据,leader作为唯一的"source of truth"。在有些情况下,follower会truncate自己的log(这个log和以下的log都是指"replicated log"这个概念里的log),然后重新从leader处抓取数据,以求与leader一致(下面会讲到)。
leader和follower的角色区分,也主要是ReplicaManager来实现。具体地讲
- leader
- leader会接受client的读取请求和写入请求。
- leader需要接受follwer抓取message的请求,返回message给follower
- leader需要维护ISR(in-sync replicas)列表。“保持同步”的含义有些复杂,0.9之前版本对这个概念的定义与0.9不同,详情参见KIP-16 - Automated Replica Lag Tuning。0.9版本,broker的参数replica.lag.time.max.ms用来指定ISR的定义,如果leader在这么长时间没收到follower的拉取请求,或者在这么长时间内,follower没有fetch到leader的log end offset,就会被leader从ISR中移除。ISR是个很重要的指标,controller选取partition的leader replica时会使用它,因此leader选取ISR后会把结果记到Zookeeper上。
- leader需要维护high watermark。high watermark以下的消息就是所有ISR列表里的replica都已经读取的消息(注意,并不是所有replica都一定有这些消息,而只是ISR里的那些才肯定会有)。因此leader会根据follower拉取数据时提供的offset和ISR列表,决定HW,并且在返回给follower的请求中附带最新的HW。
- follower
- follower需要不停地去leader处拉取最新的log
- follower需要根据leader在fetch reponse中提供的HW,更新自己本地保存的leader的HW信息。在它过行leader或follower转变时,会用到这个HW。
HW与LEO
HW、ISR以及leader对于partition这个多副本系统算是一种元数据。ISR和leader确要在controller和所有replica之间保持一致,HW需要在leader和follower之间保持一致,因为在leader转换的时候,HW是安全线。
下面明确一下high watermark和log end offset在源码里的意义
HW high watermark offset的数据小于被认为是commit的,注意,offset为high watermark的message并不是commit的。
LEO log end offset 这个replica的log里最后一条消息的下一条消息的offset
这些数据根据实际需求,以不同的方式在Kafka中传递:
- HW。随着follower的拉取进度的即时变化,HW是随时在变化的。follower总是向leader请求自己已有messages的下一个offset开始的数据,因此当follower发出了一个fetch request,要求offset为A以上的数据,leader就知道了这个follower的log end offset至少为A。此时就可以统计下ISR里的所有replica的LEO是否已经大于了HW,如果是的话,就提高HW。同时,leader在fetch本地消息给follower时,也会在返回给follower的reponse里附带自己的HW。这样follower也就知道了leader处的HW(但是在实现中,follower获取的只是读leader本地log时的HW,并不能保证是最新的HW)。但是leader和follower的HW是不同步的,follower处记的HW可能会落后于leader。
- ISR以及leader。 在需要选举leader的场景下,leader和ISR是由controller决定的。在选出leader以后,ISR是leader决定。如果谁是leader和ISR只存在于ZK上,那么每个broker都需要在Zookeeper上监听它host的每个partition的leader和ISR的变化,这样效率比较低。如果不放在Zookeeper上,那么当controller fail以后,需要从所有broker上重新获得这些信息,考虑到这个过程中可能出现的问题,也不靠谱。所以leader和ISR的信息存在于Zookeeper上,但是在变更leader时,controller会先在Zookeeper上做出变更,然后再发送LeaderAndIsrRequest给相关的broker。这样可以在一个LeaderAndIsrRequest里包括这个broker上有变动的所有partition,即batch一批变更新信息给broker,更有效率。另外,在leader变更ISR时,会先在Zookeeper上做出变更,然后再修改本地内存中的ISR。
Hight Watermark Checkpoint
以外,由于HW是随时变化的,如果即时更新到Zookeeper,会带来效率的问题。而HW是如此重要,因此需要持久化,ReplicaManager就启动了单独的线程定期把所有的partition的HW的值记到文件中,即做highwatermark-checkpoint。
Epoch
除了leader,ISR之外,在replica系统中还有其它三个对于一致性有重要作用的参数:controller epoch、leader epoch和zookeeper version。
- controller epoch: 当新的controller开始工作后,旧的controller可能还在工作,这时就会有两个自认为是的controller,那么broker该听哪个的呢?cpmtroller epoch是一个整数,记在Zookeeper的/controller_epoch path的数据中,当新的controller当选后,它更新Zookeeper中的这个数据,把这个整数的值+1,并且以每个命令中都附带上controller epoch。这样broker收到一个controller的命令后,就与自己内存中保存的controller epoch比较,如果命令中的值小于内存中的值,就代表是旧的controller的命令,如果大于内存中的值,就更新内存中的controller epoch为新值,并且执行命令。
- leader epoch: 对于同一个controller,也存在它的LeaderAndIsrRequest以错误的顺序到达broker的可能,这样broker就可以在检查controller的epoch之后,再检查leader epoch,以确认该执行哪个命令。
- zkVersion 对于在zookeeper path中存储的controller epoch, leaderAndIsr信息进行更新时,始终都得进行条件更新,以避免产生竞态。比如,在controller读取Zookeeper上的leaderAndIsr信息后,更新leaderAndIsr信息前,如果leader更改了ISR的信息,而controller以更改前的ISR进行leader选举的话,就可能会产生异常状态;或者在controller更新完leaderAndIsr之后,旧的leader又去更新zk上的这个数据,也会使集群不一致。所以,就需要zkVersion来进行条件变更。controller和replica在内存中存储上一次状态更新时读取到的zkVersion,当它依据此状态做出决定时,需要带上这个zkVersion做条件更新,以保证根据旧状态做出的更新不会生效。这种条件更新是使用的kafka.utils.ZkUtils的conditionalUpdatePersistentPath方法。
由这三个版本号共同作用,Kafka基本都保证对于leader, ISR, controller的认知在各个broker间不会出现大问题(但是还会有bug和潜在的问题导致认知不一致)。
update MetadataCache
此外,当broker收到UpdateMetadataRequest时,它会把这个request交给ReplicaManager处理,而ReplicaManager在确定UpdateMetadataRequest的controller epoch有效之后,就会交由MetadataCache来处理。之所以不直接收MetadataCache处理,可能是ReplicaManager处会保存controller epoch, 不过MetadataCache内部也可能获取controller epoch,只是没有做为单独的一个field保存起来。这样做显得有些混乱,不知道是什么原因。
Kafka之ReplicaManager(1)的更多相关文章
- Kafka单节点及集群配置安装
一.单节点 1.上传Kafka安装包到Linux系统[当前为Centos7]. 2.解压,配置conf/server.property. 2.1配置broker.id 2.2配置log.dirs 2. ...
- Kafka运维填坑(转)
前提: 只针对Kafka 0.9.0.1版本; 说是运维,其实偏重于问题解决; 大部分解决方案都是google而来, 我只是作了次搬运工; 有些问题的解决方案未必一定是通用的, 若应用到线上请慎重; ...
- Linux Kafka源码环境搭建
本文主要讲述的是如何搭建Kafka的源码环境,主要针对的Linux操作系统下IntelliJ IDEA编译器,其余操作系统或者IDE可以类推. 1.安装和配置JDK确认JDK版本至少为1.7,最好是1 ...
- Kafka 0.8 Controller设计机制和状态变化
在kafka集群中,其中一个broker server作为中央控制器Control,负责管理分区和副本状态并执行管理着这些分区的重新分配. 下面说明如何通过中央控制器操作分区和副本的状态. 名词解释 ...
- 5 Kafka 应用问题经验积累
16.Kafka 配置文件同步 为了给kafka的进程添加GC日志信息,方便在以后重启的时候,加入GC日志: 修改bin/kafka-server-start.sh: export KAFKA_OPT ...
- kafka的安装及基本使用
1.安装zookeeper # 解压缩 [root@localhost zookeeper]# .tar.gz [root@localhost zookeeper]# zk_simple # 复制zo ...
- kafka报错:Invalid message size: 0
现象 1.kafka topic 部分分区积压 2.问题kafka 节点上一直报错:java.lang.IllegalStateException: Invalid message size: 0 [ ...
- kafka的安装和初步使用
简介 最近开发的项目中,kafka用的比较多,为了方便梳理,从今天起准备记录一些关于kafka的文章,首先,当然是如何安装kafka了. Apache Kafka是分布式发布-订阅消息系统. Apac ...
- Kafka压测— 搞垮kafka的方法(转)
分布式系统故障场景梳理方法: 场景梳理逻辑关系: 单点硬件故障→单点进程故障类型→集群影响→集群故障场景 第三方依赖故障→集群依赖关系→集群影响→集群故障场景 业务场景→集群负载/错误影响→集群故障场 ...
随机推荐
- Javascript Class
做个记录,javascript 如何创建类? 有早期的,有原型的,有构造函数的 // early javascript object var o = {}; o.color = 'red'; o.sh ...
- 初探内联方式的 onload="doSomething()"为何要加"()"?而js代码的 onload="doSomething" 和 addEventListener 为何不加"()"?
问题引入:在看<Jquery基础教程>第四版的时,P34页有这样一段话 引用函数与调用函数 这里在将函数指定为处理程序时,省略了后面的圆括号,只使用了函数名.如果带着圆括号,函数会被立即调 ...
- 9款让你眼前一亮的HTML5/CSS3示例及源码
1.HTML5 3D点阵列波浪翻滚动画 今天我们要再分享一款基于HTML5 3D的点阵列波浪翻滚动画特效,同样是非常的壮观. 在线演示 源码下载 2.HTML5小球弹跳动画 很不错的3D小球 今天我要 ...
- 3D球状标签云(兼容IE8)
看见一个很有趣的标签云,3D球状,兼容 IE 8,亲测可用!其他版本没有测试.觉得挺有意思就拿来记录下来,学习学习,本文下方会放出我看的文章地址,先看一下效果: 接下来是代码,html + css + ...
- C++将类的构造函数、析构函数声明为private或者protected的用途
如果将构造函数.析构函数声明为private或者protected,表示不能从类的外部正常调用构造和析构函数了. 这种用法的通常使用的场景如下: 1.如果不想让外面的用户直接构造一个类A的对象,而希望 ...
- Vim 保存和退出命令
命令 简单说明 :w 保存编辑后的文件内容,但不退出vim编辑器.这个命令的作用是把内存缓冲区中的数据写到启动vim时指定的文件中. :w! 强制写文件,即强制覆盖原有文件.如果原有文件的访问权限不允 ...
- 《DNS加密更新》RHEL6
DNS加密更新: 继DNS更新之后,现在又玩DNS加密更新,差不多. DNS更新指定一台主机,那台主机或多台主机来更新它,其他主机没权限. DNS加密更新,谁有密码说就可以更新. 做过上次的更新之后, ...
- WP开发笔记——日期时间DateTime.Now函数
//2008年4月24日 System.DateTime.Now.ToString("D"); //2008-4-24 System.DateTime.Now.ToString(& ...
- WCF全面解析第二章 地址(Adress)
2.1 统一资源标识(URL) 2.1.1 Http/Https 2.1.2 Net.TCP 2.1.3 Net.Pipe WCF只将命名管道专门用于同一台机器的跨进程通信. 2.1.4 Net.Ms ...
- css透明(支持各浏览器)
opacity: 0.4;filter: progid:DXImageTransform.Microsoft.Alpha(opacity=40); -ms-filter: "progid:D ...