Kafka 存储机制和副本
1.概述
Kafka 快速稳定的发展,得到越来越多开发者和使用者的青睐。它的流行得益于它底层的设计和操作简单,存储系统高效,以及充分利用磁盘顺序读写等特性,和其实时在线的业务场景。对于Kafka来说,它是一个分布式的,可分区的,多副本,多订阅者的,基于Zookeeper统一协调的分布式日志系统。常见的可以用于系统日志,业务日志,消息数据等。那今天笔者给大家分析Kafka的存储机制和副本的相关内容。
2.Replication
Replication是Kafka的重要特性之一,针对其Kafka Brokers进行自动调优Replication数,是比较有难度的。原因之一在于要知道怎么避免Follower进入和退出同步 ISR (In-Sync Replicas)。再消息生产的过程当中,在有一大批海量数据写入时,可能会引发Broker告警。如果某些Topic的部分Partition长期处于 “under replicated”,这样是会增加丢失数据的几率的。Kafka 通过多副本机制实现高可用,确保当Kafka集群中某一个Broker宕机的情况下,仍然可用。而 Kafka 的复制算法保证,如果Leader发生故障或者宕机,一个新的Leader会被重新选举出来,并对外提供服务,供客户端写入消息。Kafka 在同步的副本列表中选举一个副本为Leader。
在Topic中,每个分区有一个预写式日志文件,每个分区都由一系列有序,不可变的消息组成,这些消息被连续的追加到分区中,分区中的每个消息都包含一个连续的序列号,即:offset。它用于确定在分区中的唯一位置。如下图所示:

在Kafka中,假如每个Topic的分区有N个副本,由于Kafka通过多副本机制实现故障自动转移,这里需要说明的是,当KafkaController出现故障,进而不能继续管理集群,则那些KafkaController Follower开始竞选新的Leader,而启动的过程则是在KafkaController的startup方法中完成的,如下所示:
def startup() = {
inLock(controllerContext.controllerLock) {
info("Controller starting up")
registerSessionExpirationListener()
isRunning = true
controllerElector.startup
info("Controller startup complete")
}
}
然后启动ZookeeperLeaderElector,在创建临时节点,进行session检查,更新leaderId等操作完成后,会调用故障转移函数onBecomingLeader,也就是KafkaController中的onControllerFailover方法,如下所示:
def onControllerFailover() {
if(isRunning) {
info("Broker %d starting become controller state transition".format(config.brokerId))
readControllerEpochFromZookeeper()
incrementControllerEpoch(zkUtils.zkClient)
// before reading source of truth from zookeeper, register the listeners to get broker/topic callbacks
registerReassignedPartitionsListener()
registerIsrChangeNotificationListener()
registerPreferredReplicaElectionListener()
partitionStateMachine.registerListeners()
replicaStateMachine.registerListeners()
initializeControllerContext()
// We need to send UpdateMetadataRequest after the controller context is initialized and before the state machines
// are started. The is because brokers need to receive the list of live brokers from UpdateMetadataRequest before
// they can process the LeaderAndIsrRequests that are generated by replicaStateMachine.startup() and
// partitionStateMachine.startup().
sendUpdateMetadataRequest(controllerContext.liveOrShuttingDownBrokerIds.toSeq)
replicaStateMachine.startup()
partitionStateMachine.startup()
// register the partition change listeners for all existing topics on failover
controllerContext.allTopics.foreach(topic => partitionStateMachine.registerPartitionChangeListener(topic))
info("Broker %d is ready to serve as the new controller with epoch %d".format(config.brokerId, epoch))
maybeTriggerPartitionReassignment()
maybeTriggerPreferredReplicaElection()
if (config.autoLeaderRebalanceEnable) {
info("starting the partition rebalance scheduler")
autoRebalanceScheduler.startup()
autoRebalanceScheduler.schedule("partition-rebalance-thread", checkAndTriggerPartitionRebalance,
5, config.leaderImbalanceCheckIntervalSeconds.toLong, TimeUnit.SECONDS)
}
deleteTopicManager.start()
}
else
info("Controller has been shut down, aborting startup/failover")
}
正因为有这样的机制存在,所示当Kafka集群中的某个Broker宕机后,仍然保证服务是可用的。在Kafka中发生复制操作时,确保分区的预写式日志有序的写到其他节点,在N个复制因子中,其中一个复制因子角色为Leader,那么其他复制因子的角色则为Follower,Leader处理分区的所有读写请求,同时,Follower会被动的定期去复制Leader上的数据。以上分析可以总结为以下几点,如下所示:
- Leader负责处理分区的所有读写请求。
- Follower会复制Leader上数据。
- Kafka 的故障自动转移确保服务的高可用。
3.存储
对于消息对应的性能评估,其文件存储机制设计是衡量的关键指标之一,在分析Kafka的存储机制之前,我们先了解Kafka的一些概念:
- Broker:Kafka消息中间件节点,一个节点代表一个Broker,多个Broker可以组建成Kafka Brokers,即:Kafka集群。
- Topic:消息存储主题,即可以理解为业务数据名,Kafka Brokers能够同时负责多个Topic的处理。
- Partition:针对于Topic来说的,一个Topic上可以有多个Partition,每个Partition上的数据是有序的。
- Segment:对于Partition更小粒度,一个Partition由多个Segment组成。
- Offset:每个Partition上都由一系列有序的,不可变的消息组成,这些消息被连续追加到Partition中。而在其中有一个连续的序列号offset,用于标识消息的唯一性。
3.1 Topic存储
在Kafka文件存储中,同一个Topic下有多个不同的Partition,每个Partition为一个单独的目录,Partition的命名规则为:Topic名称+有序序号,第一个Partition序号从0开始,序号最大值等于Partition的数量减1,如下图所示:

3.2 分区文件存储
每个分区相当于一个超大的文件被均分到多个大小相等的Segment数据文件中,但是每个Segment消息数量不一定相等,正因为这种特性的存在,方便了Old Segment File快速被删除。而对于每个分区只需要支持顺序读写即可,Segment文件生命周期由服务端配置的参数决定。这样即可快速删除无用数据文件,有效提高磁盘利用率。
3.3 Segment文件存储
这里,Segment文件由Index File和Data File组成,文件是一一对应的,后缀为 .index 表示索引文件, .log 表示数据文件,如下图所示:

如上图所示,Segment文件命名规则由分区全局第一个Segment从0开始,后续每一个Segment文件名为上一个Segment文件最后一个消息的Offset值。这里Segment数据文件由许多消息组成,消息物理结构如下所示:
| Key | Describer |
| offset | 用于标识每个分区中每条消息的唯一性,Offset的数值标识该分区的第几条消息 |
| message Size | 消息大小 |
| CRC32 | 用CRC32校验消息 |
| “magic” | 当前发布Kafka服务程序的协议版本号 |
| “attribute” | 独立版本,或标识压缩类型,或者编码类型 |
| key length | key的长度 |
| key | 可选 |
| payload length | 实际消息数据 |
3.4 分区中查找消息
在分区中,可以通过offset偏移量来查找消息,如上图中,文件00000000000046885905.index的消息起始偏移量为46885906=46885905+1,其他文件依此类推,以起始偏移量命名并排序这些文件,这样能够快速的定位到具体的文件。通过segment file,当offset为46885906时,我们可以定位到00000000000046885905.index元数据物理位置和00000000000046885905.log物理偏移地址。
4.总结
通过对副本和存储机制的分析,我们可以清楚的知道,Kafka通过自动故障转移来确保服务的高可用,Leader负责分区的所有读写操作,Follower会复制Leader上的数据。Kafka针对Topic,使某一个分区中的大文件分成多个小文件,通过多个小的segment file,使之便捷定期清理或删除已经消费的文件,减少磁盘占用。另外,通过索引文件稀疏存储,可以大幅度降低索引文件元数据所占用的空间。
5.结束语
这篇博客就和大家分享到这里,如果大家在研究学习的过程当中有什么问题,可以加群进行讨论或发送邮件给我,我会尽我所能为您解答,与君共勉。
Kafka 存储机制和副本的更多相关文章
- kafka存储机制
kafka存储机制 @(博客文章)[storm|大数据] kafka存储机制 一关键术语 二topic中partition存储分布 三 partiton中文件存储方式 四 partiton中segme ...
- Kafka存储机制(转)
转自:https://www.cnblogs.com/jun1019/p/6256514.html Kafka存储机制 同一个topic下有多个不同的partition,每个partition为一个目 ...
- kafka存储机制以及offset
1.前言 一个商业化消息队列的性能好坏,其文件存储机制设计是衡量一个消息队列服务技术水平和最关键指标之一.下面将从Kafka文件存储机制和物理结构角度,分析Kafka是如何实现高效文件存储,及实际应用 ...
- kafka知识体系-kafka设计和原理分析-kafka文件存储机制
kafka文件存储机制 topic中partition存储分布 假设实验环境中Kafka集群只有一个broker,xxx/message-folder为数据文件存储根目录,在Kafka broker中 ...
- Kafka(3)--kafka消息的存储及Partition副本原理
消息的存储原理: 消息的文件存储机制: 前面我们知道了一个 topic 的多个 partition 在物理磁盘上的保存路径,那么我们再来分析日志的存储方式.通过 [root@localhost ~]# ...
- Kafka文件存储机制及offset存取
Kafka是什么 Kafka是最初由Linkedin公司开发,是一个分布式.分区的.多副本的.多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx ...
- Kafka文件存储机制那些事
Kafka是什么 Kafka是最初由Linkedin公司开发,是一个分布式.分区的.多副本的.多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx ...
- kafka学习之-文件存储机制
Kafka是什么 Kafka是最初由Linkedin公司开发,是一个分布式.分区的.多副本的.多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx ...
- 转】 Kafka文件存储机制那些事
原博文出自于:http://tech.meituan.com/kafka-fs-design-theory.html 感谢! Kafka是什么 Kafka是最初由Linkedin公司开发,是一个 ...
随机推荐
- 【面经】腾讯和YY实习生面试总结
[前言] 之前的四月份和五月份各面试了腾讯和YY的暑假实习,腾讯的失败了,YY的成功了.面试中我总会遇到自己不懂的,所幸的是不懂的越来越少,自己也一步一脚印得攻克自己不懂的.此时六月份的我再回顾起来, ...
- 【Android Developers Training】 67. 响应触摸事件
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- FFT/NTT 多项式学习笔记
FFT(快速傅立叶变换)和NTT(快速数论变换)看上去很高端,真正搞懂了就很simple了辣. 首先给出多项式的一些定义(初中数学内容): 形如Σaixi的式子就是多项式! 多项式中每个单项式叫做多项 ...
- Java多线程(二) —— 线程安全、线程同步、线程间通信(含面试题集)
一.线程安全 多个线程在执行同一段代码的时候,每次的执行结果和单线程执行的结果都是一样的,不存在执行结果的二义性,就可以称作是线程安全的. 讲到线程安全问题,其实是指多线程环境下对共享资源的访问可能会 ...
- PHP接入阿里云市场 阿里短信服务DEMO
阿里短信服务:支持三大运营商短信.智能管道等优质能力,产品特点:3秒可达.99%到达率.超低资费. 使用阿里短信服务步骤: 1.购买服务 到https://market.aliyun.com/prod ...
- linux中日志介绍
linux日志 linux日志大多是以明文存储,一般存储在/var/log目录中,linux系统中主要有三个日志子系统:连接时间日志,进程统计日志,错误日志. 连接时间日志 连接时间日志是有多个程序执 ...
- Java的基本数据类型和运算
编码 ASCII--0~127 65-A 97-a 西欧码表---ISO-8859-1---0-255---1个字节 gb2312----0-65535---gbk---2个字节 Unicode编 ...
- tomcat支持php
最近做项目遇到了问题,服务器是用的tomcat,而有用到php,就想在tomcat下面可以运行php,步骤如下: 1.下载php压缩包解压或者用wamp/xampp 我下载的是wamp,用的里面的ph ...
- php使用flock阻塞写入文件和非阻塞写入文件的实例讲解
php使用flock阻塞写入文件和非阻塞写入文件的实例讲解: 阻塞写入代码:(所有程序会等待上次程序执行结束才会执行,30秒会超时) <?php $file = fopen("test ...
- 基于Windows服务的聊天程序(一)
本文将演示怎么通过C#开发部署一个Windows服务,该服务提供各客户端的信息通讯,适用于局域网.采用TCP协议,单一服务器连接模式为一对多:多台服务器的情况下,当客户端连接数超过预设值时可自动进行负 ...