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

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

 

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

 

 

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

 

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占用大量的磁盘空间。

 

图1

 

图2

 

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

 

__consumer_offset的作用

 

图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 数据保留策略

 

图4

 

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

 

 

 

 

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

 

不合理的同步提交方式

 

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

 

 

 

以上是官方文档给出了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

时间: 2024-09-24 02:44:51

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

LinkedIn开源Cruise Control:一个Kafka集群自动化运维新利器

Kafka近年来日渐流行,LinkedIn的1800台Kafka服务器每天处理2万亿个消息.虽说Kafka运行得十分稳定,但要大规模运行Kafka,在运维方面仍然面临巨大的挑战.每天都会有broker崩溃,导致集群工作负载不均衡.SRE团队需要花费大量的时间和精力来重分配分区,以便让集群重新恢复均衡. 自动化因此变得十分重要,这也就是为什么我们要开发Cruise Control:持续监控Kafka集群,自动调整分配给服务器的资源,达到预期的性能目标.用户设定目标,Cruise Control对集

Kafka详解二、如何配置Kafka集群

Kafka集群配置比较简单,为了更好的让大家理解,在这里要分别介绍下面三种配置 单节点:一个broker的集群 单节点:多个broker的集群 多节点:多broker集群 一.单节点单broker实例的配置 1. 首先启动zookeeper服务      Kafka本身提供了启动zookeeper的脚本(在kafka/bin/目录下)和zookeeper配置文件(在kafka/config/目录下),首先进入Kafka的主目录(可通过 whereis kafka命令查找到):      [roo

扩展-kafka集群 报错 在线等

问题描述 kafka集群 报错 在线等 WARN [Controller-1-to-broker-2-send-thread], Controller 1's connection to broker Node(2, mine-28, 9092) was unsuccessful (kafka.controller.RequestSendThread) java.io.IOException: Connection to Node(2, mine-28, 9092) failed at kafk

kafka集群部署

前提:kafka集群依赖于zk集群,没有zk集群环境的请先参考 http://www.cnblogs.com/yjmyzz/p/4587663.html . 假设搭建3个节点的kafka集群,下面是步骤:  一.下载 http://kafka.apache.org/downloads ,如果只是安装,直接down kafka_2.12-0.11.0.0.tgz 即可. 二.解压 假设$KAFKA_HOME为解压后的根目录,将tag包解压到该目录下(3台机器上都解压) 三.修改$KAFKA_HOM

如何为Kafka集群选择合适的Partitions数量

如何为Kafka集群选择合适的Partitions数量 Hadoop技术博文 这是许多kafka使用者经常会问到的一个问题.本文的目的是介绍与本问题相关的一些重要决策因素,并提供一些简单的计算公式. 文章目录 1 越多的分区可以提供更高的吞吐量 2 越多的分区需要打开更多地文件句柄 3 更多地分区会导致更高的不可用性 4 越多的分区可能增加端对端的延迟 5 越多的partition意味着需要客户端需要更多的内存 6 总结   越多的分区可以提供更高的吞吐量 首先我们需要明白以下事实:在kafka

部署kafka集群到服务器

前面文章写道的是伪集群的部署,是在同一台服务器部署了四个kafka broker 实际上没有任何的高HA作用.现在来部署一个真正的kafka集群 三台服务器,分别是106 107 108-现在已经部署的lafka在106上 -已经在106上启动了kafka服自带的zookeeper 编辑106服务器的kafka server.properties conf/server.properties 修改broker.id=0 修改listeners=PLAINTEXT://0.0.0.0:9092 修

Kafka集群配置

之前一篇博文简单讲述了zookeeper和kafka的单机配置,详细可以参考<Linux(CentOS)中常用软件安装,使用及异常--Zookeeper, Kafka>. 本文只要讲述Kafka集群的配置事项,包括zookeeper集群的配置.本文讲述的前提是kafka和zookeeper在单机情况下已正确安装和配置.如有疑问,可以参考<Linux(CentOS)中常用软件安装,使用及异常--Zookeeper, Kafka>. 假设集群中有三台机器, ip地址分别为: 10.10

解决Linux系统SureHA 2.0集群磁盘资源/镜像磁盘资源FSCK设置导致启动时间过长的办法

Linux系统SureHA 2.0集群磁盘资源/镜像磁盘资源中默认设置分区挂载到一定次数后会进行FSCK检验,需要时间可能较长,默认的超时时间为1800秒,如果数据量较大,甚至可能因超时导致资源启动失败. 解决方案: 可以在HA设置中直接关闭FSCK设置. 切换到"设定模式"中,在failover中选定对应的资源,右键单击选择"属性",在"详细"选项卡中点击"调整",如下图:   在"Fsck"选项卡中,将

共享型SureHA集群磁盘过滤信息丢失导致无法启动

共享型SureHA集群磁盘过滤信息丢失,会导致组资源启动失败,出现该问题时,集群内的所有服务器均可以访问共享磁盘. 如果未设置NP资源,管理页面报错如下:     如果设置了NP资源,管理页面报错如下: 解决方案: 在设定模式中,选中第一台服务器,右键单击选择属性,如下图:   在HBA选项卡中,点击"连接",如下图:   勾选中共享磁盘所在的HBA,如下图,点击"确定":   按照同样的方法,为第二台服务器勾选共享磁盘HBA. 两台服务器修改完成后,在文件中选择&