kafka原理详解之各种offset和checkpoint
每一个分区都是一个顺序的、不可变的消息队列,并且可以持续的添加。分区中的消息都被分配了一个序列号,称之为偏移量(offset),在每个分区中此偏移量都是唯一的。
一个分区在文件系统里存储为一个文件夹。文件夹里包含日志文件和索引文件。其文件名是其包含的offset的最小的条目的offset。
每个文件是一个segment。
在broker的log存储文件下,除了存储这各个topic的文件夹,还存在这几个checkpoint文件。分别是
recovery-point-offset-checkpoint 负责记录topic已经被写入磁盘的offset。
replication-offset-checkpoint 用来存储每一个replica的HighWatermark。由ReplicaManager负责写。参考下面关于HW定义,也就是那些已经成功被复制给其他broker消息的offset。
__consumer_offsets存储各个topic的消费者offset。但是,他的只有一份。
一些常见的offset
HighWatermark 最后committed消息的起始偏移。它后面的消息在目前还是uncommited的状态。
logStartOffset 日志段集合中第一个日志段(segment)的基础位移,也就是这个日志对象的基础位移
LogEndOffset 下一条将要被加入到日志的消息的位移。注意,这个offset未必在硬盘中,可能目前只在内存中还没有被flush到硬盘。
recovery-point-offset-checkpoint 已经被确认写入磁盘的offset
replication-offset-checkpoint 已经确认复制给其他replica的offset。也就是HW。
失败的follower开始恢复时,会首先将自己的日志截断到上次的checkpointed时刻的HW。然后,向leader拉去消息。
同时,kafka有日志清理机制,日志清理主要是用于缩减日志的大小,如清理重复的key等等。min.compaction.lag.ms配置不满足的最近segment和activesegment显然是不能清理的。
FAQ
Resetting first dirty offset of __consumer_offsets
例如,重复报错信息如下,这显然是清理线程在一直遇到麻烦。
[2018-06-01 13:46:27,156] WARN Resetting first dirty offset of __consumer_offsets-18 to log start offset 44 since the checkpointed offset 42 is invalid. (kafka.log.LogCleanerManager$)
报错代码段为
val lastCleanOffset: Option[Long] = lastClean.get(topicPartition)
// If the log segments are abnormally truncated and hence the checkpointed offset is no longer valid;
// reset to the log starting offset and log the error
val logStartOffset = log.logSegments.head.baseOffset
val firstDirtyOffset = {
val offset = lastCleanOffset.getOrElse(logStartOffset)
if (offset < logStartOffset) {
// don't bother with the warning if compact and delete are enabled.
if (!isCompactAndDelete(log))
warn(s"Resetting first dirty offset of ${log.name} to log start offset $logStartOffset since the checkpointed offset $offset is invalid.")
logStartOffset
} else {
offset
}
}
我们可以看见,清理线程试图获取一个partition的最后清理的位移(lastCleanOffset),并同时获取了该partition中现存的所有segment中最小的头部offset(logStartOffset)。但是,却发现lastCleanOffset比logStartOffset还要小。清理线程自然会反应,那些我没有清理的数据跑哪里去了呢?抱怨完后,其将firstDirtyOffset置为logStartOffset,准备下一次从这里开始清理。报错中令人迷惑的checkpointed offset是指lastCleanOffset。
val dirtyNonActiveSegments = log.logSegments(firstDirtyOffset, log.activeSegment.baseOffset)
kafka本来应该是在完成清理后将lastCleanOffset提高,但是问题在于,如果此时没有可清理的segment,lastCleanOffset也就将保持不变。则线程下一次循环时仍然会遇到这个问题。
解决方案中最快捷的是清空kafka的data目录。或者忽略这个问题,等待大量数据灌入。一旦产生可以清理的segment,这个问题就会解决。
kafka原理详解之各种offset和checkpoint的更多相关文章
- Kafka原理详解
Kafka是最初由Linkedin公司开发,是一个分布式.支持分区的(partition).多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量 ...
- 节点地址的函数list_entry()原理详解
本节中,我们继续讲解,在linux2.4内核下,如果通过一些列函数从路径名找到目标节点. 3.3.1)接下来查看chached_lookup()的代码(namei.c) [path_walk()> ...
- Influxdb原理详解
本文属于<InfluxDB系列教程>文章系列,该系列共包括以下 15 部分: InfluxDB学习之InfluxDB的安装和简介 InfluxDB学习之InfluxDB的基本概念 Infl ...
- 【转载】JAVA消息服务JMS规范及原理详解
转载:https://www.cnblogs.com/molao-doing/articles/6557305.html 作者: moyun- 一.简介 JMS即Java消息服务(Java Messa ...
- JAVA消息服务JMS规范及原理详解
JAVA消息服务JMS规范及原理详解 一.简介 JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应 ...
- Batchnorm原理详解
Batchnorm原理详解 前言:Batchnorm是深度网络中经常用到的加速神经网络训练,加速收敛速度及稳定性的算法,可以说是目前深度网络必不可少的一部分. 本文旨在用通俗易懂的语言,对深度学习的常 ...
- kafka实战教程(python操作kafka),kafka配置文件详解
kafka实战教程(python操作kafka),kafka配置文件详解 应用往Kafka写数据的原因有很多:用户行为分析.日志存储.异步通信等.多样化的使用场景带来了多样化的需求:消息是否能丢失?是 ...
- I2C 基础原理详解
今天来学习下I2C通信~ I2C(Inter-Intergrated Circuit)指的是 IC(Intergrated Circuit)之间的(Inter) 通信方式.如上图所以有很多的周边设备都 ...
- Zigbee组网原理详解
Zigbee组网原理详解 来源:互联网 作者:佚名2015年08月13日 15:57 [导读] 组建一个完整的zigbee网状网络包括两个步骤:网络初始化.节点加入网络.其中节点加入网络又包括两个 ...
随机推荐
- JavaScript深入浅出第5课:Chrome是如何成功的?
摘要: Chrome改变世界. <JavaScript深入浅出>系列: JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼? JavaScript深入浅出第2课:函数是一 ...
- jar 冲突、class 冲突的检测脚本
思路很简单,解开war包,解开 jar 包,发现有同名 package.class 就报出来,不管是否“兼容” .. import zipfile import io from collections ...
- git tag介绍
我们常常在代码发版时,使用git 创建一个tag ,这样一个不可修改的历史代码版本就像被我们封存起来一样,不论是运维发布拉取,或者以后的代码版本管理,都是十分方便的. git的tag功能git 下打标 ...
- 跟着ALEX 学python day5 模块
文档内容学习于 http://www.cnblogs.com/xiaozhiqi/ 模块 1.模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能),本质就是.py结尾的pyt ...
- Spring data redis的使用
Spring data redis的使用 一.Redis的安装和使用 Redis是用C语言开发的一个高性能键值对数据库,可用于数据缓存,主要用于处理大量数据的高访问负载. 下载地址:https://g ...
- 【Spring IoC】IoC容器初始化(二)
Ioc容器的初始化是由refresh()方法来启动的,这个方法标志着Ioc容器的正式启动. 具体来说这个启动过程包括三个基本过程: BeanDefinition的Resource定位 BeanDefi ...
- 【使用篇二】SpringBoot整合Servlet(1)
两种方式: 通过注解扫描完成 Servlet组件的注册 通过方法完成 Servlet组件的注册 一.通过注解扫描完成 Servlet 组件的注册 1. 编写Servlet类 /** * SpringB ...
- NOIP 2016 回文日期
洛谷P2010 https://www.luogu.org/problemnew/show/P2010 JDOJ 3313 https://neooj.com:8082/oldoj/problem.p ...
- luoguP3327 [SDOI2015]约数个数和
题意 首先有个结论: \(d(i,j)=\sum\limits_{x|i}\sum\limits_{y|j}[gcd(x,y)=1]\) 证明: 假设\(i=p_1^{a_1}*p_2^{a_2}*. ...
- JS中的箭头函数与this
转载自:https://juejin.im/post/5aa1eb056fb9a028b77a66fd#heading-1 JavaScript在ES6语法中新增了箭头函数,相较于传统函数,箭头函数不 ...