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 存储机制和副本的更多相关文章

  1. kafka存储机制

    kafka存储机制 @(博客文章)[storm|大数据] kafka存储机制 一关键术语 二topic中partition存储分布 三 partiton中文件存储方式 四 partiton中segme ...

  2. Kafka存储机制(转)

    转自:https://www.cnblogs.com/jun1019/p/6256514.html Kafka存储机制 同一个topic下有多个不同的partition,每个partition为一个目 ...

  3. kafka存储机制以及offset

    1.前言 一个商业化消息队列的性能好坏,其文件存储机制设计是衡量一个消息队列服务技术水平和最关键指标之一.下面将从Kafka文件存储机制和物理结构角度,分析Kafka是如何实现高效文件存储,及实际应用 ...

  4. kafka知识体系-kafka设计和原理分析-kafka文件存储机制

    kafka文件存储机制 topic中partition存储分布 假设实验环境中Kafka集群只有一个broker,xxx/message-folder为数据文件存储根目录,在Kafka broker中 ...

  5. Kafka(3)--kafka消息的存储及Partition副本原理

    消息的存储原理: 消息的文件存储机制: 前面我们知道了一个 topic 的多个 partition 在物理磁盘上的保存路径,那么我们再来分析日志的存储方式.通过 [root@localhost ~]# ...

  6. Kafka文件存储机制及offset存取

    Kafka是什么 Kafka是最初由Linkedin公司开发,是一个分布式.分区的.多副本的.多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx ...

  7. Kafka文件存储机制那些事

    Kafka是什么 Kafka是最初由Linkedin公司开发,是一个分布式.分区的.多副本的.多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx ...

  8. kafka学习之-文件存储机制

    Kafka是什么 Kafka是最初由Linkedin公司开发,是一个分布式.分区的.多副本的.多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx ...

  9. 转】 Kafka文件存储机制那些事

    原博文出自于:http://tech.meituan.com/kafka-fs-design-theory.html    感谢! Kafka是什么 Kafka是最初由Linkedin公司开发,是一个 ...

随机推荐

  1. Entity Framework Code First数据库连接

    1. 安装Entity Framework 使用NuGet安装Entity Framework程序包:工具->库程序包管理器->程序包管理器控制台,执行以下语句: PM> Insta ...

  2. 全中国的省市县镇乡村数据获取以及展示java源代码

    第一步.准备工作(数据源+工具): 数据源(截止目前最全面权威的官方数据):http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2013/ 爬取数据的工具 ...

  3. 记事本源代码 python3

    已实现基本功能,显示行号功能暂时实现不了(后面学会了再加,右下角可以实现定位光标所在行.列) 可能会有些bug 1 from tkinter import * from tkinter.message ...

  4. window、linux系统与linux服务器之间使用svn同步及自动部署代码的方法

    摘要: 在家用PC,在公司用办公电脑对一个项目的代码进行修改时,会遇到代码同步的问题.本文讲解了代码同步及自动部署的解决办法. 实现方法: 1.首先在linux服务器上和linux上安装svn(sud ...

  5. 《用Java写一个通用的服务器程序》02 监听器

    在一个服务器程序中,监听器的作用类似于公司前台,起引导作用,因此监听器花在每个新连接上的时间应该尽可能短,这样才能保证最快响应. 回到编程本身来说: 1. 监听器最好由单独的线程运行 2. 监听器在接 ...

  6. JavaScript Promise:去而复返

    原文:http://www.html5rocks.com/en/tutorials/es6/promises/ 作者:Jake Archibald 翻译:Amio 女士们先生们,请准备好迎接 Web ...

  7. XShell停止滚屏,禁止滚动

     Ctrl+S:锁定当前屏幕  Ctrl+Q:解锁当前屏幕 Ctrl+Alt+]  进入命令输入状态

  8. Django中的ORM关系映射查询方面

    ORM:Object-Relation Mapping:对象-关系映射 在MVC框架中的Model模块中都包括ORM,对于开发人员主要带来了如下好处: 实现了数据模型与数据库的解耦,通过简单的配置就可 ...

  9. Java网络编程和NIO详解8:浅析mmap和Direct Buffer

    Java网络编程与NIO详解8:浅析mmap和Direct Buffer 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NI ...

  10. 关于JavaScript诞生之初的趣事

    我在读很多优秀的JavaScript源码时候常常被它诡异的语法搞的精疲力尽,所以时不时的加固JavaScript基础知识是十分有必要的,这些知识每次温故或者你换个角度去思考都能收获颇多,那么如此深不可 ...