转:关于Kafka日志留存策略的讨论

关于Kafka日志留存(log retention)策略的介绍,网上已有很多文章。不过目前其策略已然发生了一些变化,故本文针对较新版本的Kafka做一次统一的讨论。如果没有显式说明,本文一律以Kafka 1.0.0作为分析对象。

所谓日志留存策略,就是Kafka保存topic数据的规则,我将按照以下几个方面分别介绍留存策略:

  • 留存策略类型

  • 留存机制及其工作原理

一、留存策略类型

目前,与日志留存方式相关的策略类型主要有两种:delete和compact。这两种留存方式的机制完全不同。本文主要讨论针对delete类型的留存策略。用户可以通过设置broker端参数log.cleanup.policy来指定集群上所有topic默认的策略类型。另外也可以通过topic级别参数cleanup.policy来为某些topic设置不同于默认值的策略类型。当前log.cleanup.policy参数的默认值是[delete,compact],这是一个list类型的参数,表示集群上所有topic会同时开启delete和compact两种留存策略——这是0.10.1.0新引入的功能,在0.10.1.0之前,该参数只能两选一,不能同时兼顾,但在实际使用中很多用户都抱怨compact类型的topic存在过期key消息未删除的情况,故社区修改了该参数配置,允许一个topic同时开启两种留存策略。

再次强调下, 本文只讨论delete类型的留存策略。

二、留存机制及其工作原理

在开始详细介绍各种留存机制之前,先简要说下Kafka是如何处理日志留存的。每个Kafka broker启动时,都会在后台开启一个定时任务,定期地去检查并执行所有topic日志留存,这个定时任务触发的时间周期由broker端参数log.retention.check.interval.ms控制,默认是5分钟,即每台broker每5分钟都会尝试去检查一下是否有可以删除的日志。因此如果你要缩短这个间隔,只需要调小log.retention.check.interval.ms即可。

鉴于日志留存和日志删除实际上是一个问题的两个方面,因而我们下面讨论的是关于Kafka根据什么规则来删除日志。但有一点要强调一下,待删除的标的是日志段,即LogSegment,也就是以.log结尾的一个个文件,而非整个文件夹。另外还有一点也很重要,当前日志段(active logsegment)是永远不会被删除的,不管用户配置了哪种留存机制。

当前留存机制共有3种:

  1. 基于空间维度

  2. 基于时间维度

  3. 基于起始位移维度

前两种策略相信大家已经耳熟能详,而第三种策略由于新加入的时间不长,目前网上对其的介绍并不多。我们一个一个来看。

2.1 基于空间维度

也称size-based retention,指的是Kafka定期为那些超过磁盘空间阈值的topic进行日志段的删除。这个阈值由broker端参数log.retention.bytes和topic级别参数retention.bytes控制,默认是-1,表示Kafka当前未开启这个留存机制,即不管topic日志量涨到多少,Kafka都不视其为“超过阈值”。如果用户要开启这种留存机制,必须显式设置log.retention.bytes(或retention.bytes)。

一旦用户设置了阈值,那么Kafka就会在定时任务中尝试比较当前日志量总大小是否超过阈值至少一个日志段的大小。这里所说的总大小是指所有日志段文件的大小,不包括索引文件的大小!如果是则会尝试从最老的日志段文件开始删起。注意这里的“超过阈值至少一个日志段的大小”,这就是说超过阈值的部分必须要大于一个日志段的大小,否则不会进行删除的,原因就是因为删除的标的是日志段文件——即文件只能被当做一个整体进行删除,无法删除部分内容。

举个例子来说明,假设日志段大小是700MB,当前分区共有4个日志段文件,大小分别是700MB,700MB,700MB和1234B——显然1234B那个文件就是active日志段。此时该分区总的日志大小是3*700MB+1234B=2100MB+1234B,如果阈值设置为2000MB,那么超出阈值的部分就是100MB+1234B,小于日志段大小700MB,故Kafka不会执行任何删除操作,即使总大小已经超过了阈值;反之如果阈值设置为1400MB,那么超过阈值的部分就是700MB+1234B > 700MB,此时Kafka会删除最老的那个日志段文件。

2.2 基于时间维度

也称time-based retention,指的是Kafka定期未那些超过时间阈值的topic进行日志段删除操作。这个阈值由broker端参数log.retention.ms、log.retention.mintues、log.retention.hours以及topic级别参数retention.ms控制。如果同时设置了log.retention.ms、log.retention.mintues、log.retention.hours,以log.retention.ms优先级为最高,log.retention.mintues次之,log.retention.hours最次。当前这三个参数的默认值依次是null, null和168,故Kafka为每个topic默认保存7天的日志。

这里需要讨论下这“7天”是如何界定的?在0.10.0.0之前,Kafka每次检查时都会将当前时间与每个日志段文件的最新修改时间做比较,如果两者的差值超过了上面设定的阈值(比如上面说的7天),那么Kafka就会尝试删除该文件。不过这种界定方法是有问题的,因为文件的最新修改时间是可变动的——比如用户在终端通过touch命令查看该日志段文件或Kafka对该文件切分时都可能导致最新修改时间的变化从而扰乱了该规则的判定,因此自0.10.0.0版本起,Kafka在消息体中引入了时间戳字段(当然不是单纯为了修复这个问题),并且为每个日志段文件都维护一个最大时间戳字段。通过将当前时间与该最大时间戳字段进行比较来判定是否过期。使用当前最大时间戳字段的好处在于它对用户是透明的,用户在外部无法直接修改它,故不会造成判定上的混乱。

最大时间戳字段的更新机制也很简单,每次日志段写入新的消息时,都会尝试更新该字段。因为消息时间戳通常是递增的,故每次写入操作时都会保证最大时间戳字段是会被更新的,而一旦一个日志段写满了被切分之后它就不再接收任何新的消息,其最大时间戳字段的值也将保持不变。倘若该值距离当前时间超过了设定的阈值,那么该日志段文件就会被删除。

2.3 基于起始位移维度

用户对前两种留存机制实际上是相当熟悉的,下面我们讨论下第三种留存机制:基于日志起始位移(log start offset)。这实际上是0.11.0.0版本新增加的功能。其实增加这个功能的初衷主要是为了Kafka流处理应用——在流处理应用中存在着大量的中间消息,这些消息可能已经被处理过了,但依然保存在topic日志中,占用了大量的磁盘空间。如果通过设置基于时间维度的机制来删除这些消息就需要用户设置很小的时间阈值,这可能导致这些消息尚未被下游操作算子(operator)处理就被删除;如果设置得过大,则极大地增加了空间占用。故社区在0.11.0.0引入了第三种留存机制:基于起始位移

所谓起始位移,就是指分区日志的当前起始位移——注意它是分区级别的值,而非日志段级别。故每个分区都只维护一个起始位移值。该值在初始化时被设置为最老日志段文件的基础位移(base offset),随着日志段的不断删除,该值会被更新当前最老日志段的基础位移。另外Kafka提供提供了一个脚本命令帮助用户设置指定分区的起始位移:kafka-delete-records.sh。

该留存机制是默认开启的,不需要用户任何配置。Kafka会为每个日志段做这样的检查:1. 获取日志段A的下一个日志段B的基础位移;2. 如果该值小于分区当前起始位移则删除此日志段A。

依然拿例子还说明,假设我有一个topic,名字是test,该topic只有1个分区,该分区下有5个日志段文件,分别是A1.log, A2.log, A3.log, A4.log和A5.log,其中A5.log是active日志段。这5个日志段文件中消息范围分别是09999,1000019999,2000029999,3000039999和40000~43210(A5未写满)。如果此时我确信前3个日志段文件中的消息已经被处理过了,于是想删除这3个日志段,此时我应该怎么做呢?由于我无法预知这些日志段文件产生的速度以及被消费的速度,因此不管是基于时间的删除机制还是基于空间的删除机制都是不适用的。此时我便可以使用kafka-delete-records.sh脚本将该分区的起始位移设置为A4.log的起始位移,即40000。为了做到这点,我需要首先创建一个JSON文件a.json,内容如下:

{"partitions":[{"topic": "test", "partition": 0,"offset": 40000}],"version":1}

然后执行下列命令:

bin/kafka-delete-records.sh --bootstrap-server localhost:9092 --offset-json-file a.json

如果一切正常,应该可以看到类似于这样的输出:

Executing records delete operation

Records delete operation completed:

partition: test-0 low_watermark: 40000

此时test的分区0的起始位移被手动调整为40000,那么理论上所有最大消息位移< 40000的日志段都可以被删除了。有了这个机制,用户可以实现更为灵活的留存策略。

以上就是关于当前Kafka针对于delete留存类型的topic的3种留存机制。也许在未来社区会增加更多的留存策略,我们拭目以待~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,110评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,443评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,474评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,881评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,902评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,698评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,418评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,332评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,796评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,968评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,110评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,792评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,455评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,003评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,130评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,348评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,047评论 2 355

推荐阅读更多精彩内容

  • 姓名:周小蓬 16019110037 转载自:http://blog.csdn.net/YChenFeng/art...
    aeytifiw阅读 34,722评论 13 425
  • kafka的定义:是一个分布式消息系统,由LinkedIn使用Scala编写,用作LinkedIn的活动流(Act...
    时待吾阅读 5,324评论 1 15
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,663评论 18 139
  • 4. 设计思想 4.1 动机 我们设计的 Kafka 能够作为一个统一的平台来处理大公司可能拥有的所有实时数据馈送...
    疯狂的橙阅读 1,080评论 1 4
  • 影评来了~关于健忘村 健忘村看完了,看到一半想弃剧,看到三分之二决定好评,看到五分之四杂么出好些味道来,还好没弃,...
    书妆阅读 1,490评论 1 0