当前位置: 首页 > news >正文

Kafka集群磁盘使用率瞬超85%,幕后元凶竟是它?

Kafka是一种快速、可扩展的,设计内在就是分布式的、分区的和可复制的提交日志服务。作为一种高吞吐量的分布式发布订阅消息系统,Kafka被广泛的应用于海量日志的收集、存储。网上有大量Kafka架构、原理介绍的文章,本文不再重复赘述,重点谈谈Consumer Offset默认保存机制。

 

Topic作为一类消息的逻辑集合,Kafka集群为其维护了一个分区的日志,其结构如图:

 

20170428101059865.jpg

 

Topic每个分区是一个有序的、信息不断追加的序列。分区中的每个消息都分配了一个连续的ID号,称为偏移量(offset),用于唯一标识每个消息在分区中的位置。消费者根据自身保存的offset值确定各分区消费的位置。在0.8版本之前,Kafka一直将consumer的 offset信息记录在ZooKeeper中。

 

20170428101107207.jpg

Kafka的ZooKeeper存储架构图

 

如图,在offsets的子节点中保存了不同的topic的offset 信息。Consumer在消费topic中的信息时需要不断的更新ZooKeeper中的offset信息。

 

众所周知,由于ZooKeeper并不适合大批量的频繁写入操作,从0.8.2版本开始Kafka开始支持将consumer的位移信息保存在Kafka内部的topic中(从0.9.0版本开始默认将offset存储到系统topic中),虽然此举解决了ZooKeeper频繁写入的性能瓶颈,但却引入了新的问题。

 

以下是一个真实的案例:

 

磁盘使用率异常

 

某日Kafka集群的pc-xxx01主机的文件系统使用率超过80%,触发告警。通过分析发现,topic __consumer_offset 相关log占用大量的磁盘空间。

 

20170428101120548.jpg

图1

 

20170428101129265.jpg

图2

 

如图1、2所示,pc-xxx01主机data3目录的磁盘使用率超过85%,其中__consumer_offset对应的24号分区的日志占用了952G,占总使用量的41%。

 

__consumer_offset的作用

 

20170428101137954.jpg

图3

 

如图3所示,通过消费__consumer_offsets 分区24的数据可以发现,该topic保存的消息格式为[consumer group,topic name,partition]::[offsetmetadata[offset value,nometadata],committime value,expiratintime value],即一条消息包含消费组、topic、分区、offset值、提交时间、过期时间等信息。此topic正是kafka用来保存consumer offset的系统topic(根据实验验证该topic的消息以consumer group为key进行hash,相同consumer group的offset信息会被插入同一个partition)。

 

__consumer_offsets数据产生的频率

 

Consumer消费消息之后会向offset manager 发送offsetCommitrequest请求,offset manager 负责将对应的consumer group、topic、partition、offset等信息插入__consumer_offsets topic。系统默认每60s为consumer提交一次offsetcommit请求(由auto.commit.interval.ms, auto.commit.enable两个参数决定)。应用可以采用同步commit的方式进行数据消费(即consumer每处理一条消息触发一次commit操作),这可能导致频繁发送offsetCommitrequest请求的现象发生。

 

__consumer_offsets 数据保留策略

 

20170428101147423.jpg

图4

 

如图4所示,当前__consumer_offsets 24号分区保留了16年10月到现在的所有消息日志,总量达到952G。

 

20170428101157489.jpg

 

20170428101204444.jpg

 

20170428101210217.jpg

 

当前__consumer_offsets 的清理策略为compact,日志保留周期为24小时,但是系统默认的log.cleaner.enable为false,导致kafka不会对超过保留周期的数据进行压缩处理,topic保留了系统上线以来的所有历史数据。

 

不合理的同步提交方式

 

通过前期分析发现,__consumer_offsets 数据量暴增的24分区的数据主要来自于对log_xxx_plat_xx这个topic的消费组。通过获取应用相关代码分析发现,该topic相关consumer 采用了同步commit方式进行数据消费。

 

20170428101217586.jpg

 

20170428101226942.jpg

 

以上是官方文档给出了consumer同步commit消费信息的两种示例代码。第一种方式,只要消费一条消息,就会产生一条commit记录,数据量庞大;第二种方式,对同步commit做了精细化处理,每次批量数据消费,只会对被消费topic各分区中最后一条消息进行commit。如果一个topic包含10个分区,每次消费单个分区需要处理10条消息,采用第一种方式将产生100条commit记录,而第二中方式只会产生10条commit记录,差距巨大。经开发确认,相关应用正是采用了第一种方式进行同步commit。

 

系统topic分区大小异常的原因

 

通过以上分析,当前__connsumer_offsets部分分区数据量异常的问题是由于以下两方面原因共同造成:

 

  1. __connsumer_offsets默认清理策略设置不当,导致过期历史数据无法正常清理。

  2. 部分应用消费方式不当,导致产生大量commit信息。

 

针对该问题,我们后续优化策略如下,取得了不错的成效。

 

  1. 要求应用优化代码,减少commit信息的产生,应用进行代码改造之后commit信息日增加量由原先的37G减少到1.5G。

  2. 调整topic 清理策略,将系统log.cleaner.enable设置为true,重起broker节点触发日志清理。

 

优化之后__consumer_offsets 数据量由原先的900G下降到2G。

原文发布时间为:2017-04-28

本文来自云栖社区合作伙伴DBAplus

相关文章:

  • 如何挑选服务器?哪个牌子的最好?(1万元以下的)
  • SNMP、ASN.1、MIB之间的关系
  • Oracle浅谈之逻辑体系第一回
  • 迁移TFS2008后,项目门户网站及Team Explorer的报表均无法正常显示的原因
  • Word编辑故障经典问答
  • java 是否输出是整数
  • 项目实践中Linux集群的总结和思考
  • Android开发之策略模式初探
  • android 2.3 StrictMode 使用
  • 前端之本http协议
  • 浙江省委组织部长蔡奇做客腾讯:我是微博控
  • SEO优化方案及SEO流程表
  • SpriteKit 技巧之添加背景图片
  • 实验九 三层交换机配置路由DHCP中继(二)
  • ILMerge合并多个DLL
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • crontab执行失败的多种原因
  • ES6系列(二)变量的解构赋值
  • Making An Indicator With Pure CSS
  • spark本地环境的搭建到运行第一个spark程序
  • Vue学习第二天
  • 编写符合Python风格的对象
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 复习Javascript专题(四):js中的深浅拷贝
  • 面试题:给你个id,去拿到name,多叉树遍历
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 手写一个CommonJS打包工具(一)
  • 数据可视化之 Sankey 桑基图的实现
  • 带你开发类似Pokemon Go的AR游戏
  • 进程与线程(三)——进程/线程间通信
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • (06)金属布线——为半导体注入生命的连接
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (数据结构)顺序表的定义
  • (算法二)滑动窗口
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • ./configure、make、make install 命令
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
  • .NET CF命令行调试器MDbg入门(一)
  • .net FrameWork简介,数组,枚举
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • .stream().map与.stream().flatMap的使用
  • :O)修改linux硬件时间
  • @Bean, @Component, @Configuration简析
  • @ConditionalOnProperty注解使用说明
  • @manytomany 保存后数据被删除_[Windows] 数据恢复软件RStudio v8.14.179675 便携特别版...
  • @RequestParam详解
  • @SuppressLint(NewApi)和@TargetApi()的区别
  • @Tag和@Operation标签失效问题。SpringDoc 2.2.0(OpenApi 3)和Spring Boot 3.1.1集成
  • @在php中起什么作用?