Kafka核心组件详解
1.概述
对于Kafka的学习,在研究其系统模块时,有些核心组件是指的我们去了解。今天给大家来剖析一下Kafka的一些核心组件,让大家能够更好的理解Kafka的运作流程。
2.内容
Kafka系统设计的非常优秀,它的核心组件由生产者、消费者、主题、代理节点、以及Zookeeper组成。这些核心组件彼此独立、却又相互存在一定的联系来支持Kafka系统正常运作。
2.1 核心组件术语
2.1.1 生产者
生产者即消息数据产生的来源头,通常情况下,将原始数据(如数据库、审计日志、系统日志)写入到Kafka系统的应用程序称之为生产者实例。
生产者的主要作用是发送业务数据到Kafka系统,它在Kafka系统中承担着“搬运工”的角色,负责将分布在不同地方的原始数据,集中“搬运”到Kafka系统中进行存储。
2.1.2 消费者
消费者即消息数据流出的出口,通常情况下,读取Kafka系统中业务数据的应用程序被称为消费者实例。
消费者的主要作用是读取Kafka系统中的业务数据,然后在消费者实例中经过逻辑处理后将结果写到不同的及时查询存储介质中。例如,将经过处理后的结果分别写入到分布式文件系统(HDFS)、非关系型海量存储数据库(HBase)等。消费者在Kafka系统中承担着数据分流的角色。
提示:
数据分流顾名思义就是将一份数据分别写入到不同的地方。在大数据领域中,例如Kafka系统中集中存储了业务数据,用户通过消费者实例,读取了Kafka系统中的业务数据,经过业务处理后,结果需要写到不同的及时查询存储介质中。这个过程就是一个典型的数据分流过程。
2.1.3 Topic(主题)
主题即业务数据在Kafka系统中的分类集合,通常情况下,相同类型的业务数据会存储在同一个主题下。 主题的主要作用是将不同的业务数据分类存储,便于Kafka系统统一维护和管理业务数据。对比关系型数据库,主题在Kafka系统中“扮演”的角色和关系型数据库中表的角色很类似。
2.1.4 Broker(代理节点)
代理节点即Kafka系统中服务节点,通常情况下,Kafka系统中一台服务器主机被称为Kafka系统的一个代理节点。
代理节点的主要作用是负责消息数据的存储、为客户端提供服务、保证Kafka系统的正常运行等。代理节点是Kafka系统组建集群的最小单位,一个Kafka集群由一个代理节点或者多个代理节点组成。
2.1.5 Zookeeper
Zookeeper即Kafka集群元数据管理系统,由于Kafka系统是一个分布式消息系统,由于分布式的原因,Kafka系统需要Zookeeper来协调管理服务。
Zookeeper在Kafka系统中主要作用是选举主题分区Leader、协调各个代理节点服务、存储Kafka元数据信息等。
在新版本Kafka系统中,Kafka系统对于新的消费者实例使用了Kafka内部的消费者组协调协议,减少了对Zookeeper的依赖。这时的Zookeeper对于Kafka系统来说,更像是一个小型的分布式元数据存储系统。
2.2 核心组件元数据分布
Kafka系统中,核心组件的元数据信息均存储在Zookeeper系统。这些元数据信息具体包含控制器选举次数、代理节点和主题、配置、管理员操作、控制器、以及老版本消费者实例。这些元数据信息在Zookeeper系统中的分布,如下图所示:
2.2.1 控制器选举次数
Kafka系统中的控制器每进行一次选举次数,都会在Zookeeper系统/controller_epoch节点下进行记录。该值为一个数字,Kafka集群中第一个代理节点(Broker)启动时该值为1。
Kafka集群中,如果遇到代理节点宕机或者变更,那么Kafka集群会重新选举新的控制器。每次控制器发生变化时,在Zookeeper系统/controller_epoch节点中的值就会加1。
2.2.2 Broker和Topic
在Zookeeper系统/brokers节点中存储着Kafka代理节点和主题的元数据信息。
其中,Zookeeper系统/brokers/ids节点中存储着代理节点的ID值。Zookeeper系统/brokers/topics节点中存储着主题和分区的元数据信息。
2.2.3 配置
Kafka系统中修改主题属性这类操作,会被存储到Zookeeper系统/config节点,/config节点主要包含三个子节点,分别是:
- topic:存储Kafka集群主题的额外属性,比如修改过主题的属性操作;
- client:客户端和主题配置被重写,包含消费者应用和生产者应用;
- changes:配置修改通知。
2.2.4 管理员操作
在执行管理员操作时,比如删除、分配等。在Zookeeper系统/admin节点会生成相应的子节点,内容如下:
- delete_topics:标记待删除的主题名;
- reassign_partitions:重新分配分区操作;
- preferred_replica_election:恢复Leader分区平衡操作。
2.2.5 控制器
Kafka系统正常运行时,在Zookeeper系统/controller节点下会存储一个Kafka代理节点的ID值,该ID值与Kafka代理节点ID相同,表示代理节点上存在控制器功能。
2.2.6 老版本消费者实例
在消费者实例中,如果使用kafka.tools.ConsoleConsumer接口去读取Kafka主题数据,则会产生Zookeeper系统/consumers节点。
在Zookeeper系统/consumers节点中,存在若干个消费者组子节点,每个消费者组子节点下又会存在三个子子节点:
- 消费者线程ID(Zookeeper系统/consumers/ids);
- 消费者产生的偏移量(Zookeeper系统/consumers/offsets);
- 消费者线程和分区的对应关系(Zookeeper系统/consumers/owners)。
注意:
如果使用的是Kafka新版本消费者接口,则消费者实例产生的元数据信息不会存储在Zookeeper系统/consumers节点中,而是存储在Kafka系统的内部主题中。
3.分区存储与过期数据删除
- Broker:Kafka集群组建的最小单位,消息中间件的代理节点;
- Topic:用来区分不同的业务消息,类似于数据库中的表;
- Partition:Topic物理意义上的分组,一个Topic可以分为多个Partition,每个Partition是一个有序的队列;
- Segment:每个Partition又可以分为多个Segment文件;
- Offset:每个Partition都由一系列有序的、不可修改的消息组成,这些消息被持续追加到Partition中,Partition中的每条消息记录都有一个连续的序号,用来标识这条消息的唯一性;
- Message:Kafka系统中,文件存储的最小存储单位。
Kafka系统中的Message是以Topic为基本单位,不同的Topic之间是相互独立、互不干扰的。每个Topic又可以分为若干个Partition,每个Partition用来存储一部分的Message。
3.1 分区存储
Kafka系统在创建主题时,它会规划将分区分配到各个代理节点(Broker)。例如,现有3个代理节点,准备创建一个包含6个分区、3个副本的主题,那么Kafka系统就会有18个分区副本,这18个分区副本能够被分配到3个代理节点。
在Kafka系统中,一个主题(Topic)下包含多个不同的分区(Partition),每个分区为单独的一个目录,分区的命名规则为:主题名+有序序号,第一个分区的序号从正整数0开始,序号最大值等于分区总数减1。 主题的存储路径由“log.dirs”属性决定,切换到代理节点中主题分区的存储分布,结果如图所示:
每个分区相当于一个超大的文件被均匀分配成若干个大小相等的片段(Segment),但是每个片段的消息数据量不一定是相等的,正因为这种特性的存在,方面过期的片段数据能够被快速的删除。 片段文件的生命周期由代理节点server.properties文件中配置的参数决定,这样快速删除无用的数据,可以有效的提高磁盘利用率。
片段文件由索引文件和数据文件组成,其中后缀为“.index”表示索引文件,后缀为“.log”的表示数据文件,查看某一个分区的片段,输出结果如下图所示:
Kafka系统中的索引文件并没有给数据文件中的每条消息记录都建立索引,而是采用了稀疏存储的方式,每隔一定字节的数据来建立一条索引。如下图所示:
提示:
通过稀疏存储索引的方式,避免了索引文件占用过多的磁盘空间。从而将索引文件存储在内存中,虽然没有建立索引的Message不能一次性定位到所在的数据文件上的位置,但是因为有稀疏索引的存在,会极大的缩小顺序扫描的范围。
3.2 消息格式
对于普通日志来说,一条记录以“\n”结尾,或者通过其他特殊的分隔符来拆分,这样就可以从文件中拆分出一条条的记录。但是这种方式对于文本来说比较适合,对Kafka系统来说,需要的是一种二进制格式。 因此,Kafka系统使用了一种经典的消息格式,在消息前面固定长度的几个字节中记录这条消息的大小(单位为byte)。在Kafka系统消息协议中,消息的具体格式见代码如下:
Message => Crc MagicByte Attributes Key Value
Crc => int32
MagicByte => int8
Attributes => int8
Timestamp => int64
Key => bytes
Value => bytes
这些字段含义如下所示:
4.清理过期数据
Kafka系统在清理过期的消息数据时,提供了两种清除策略。它们分别是:
- 基于时间和大小的删除策略;
- 压缩(Compact)清理策略。
这两种策略通过属性“log.cleanup.policy”来控制,可选值包含“delete”、“compact”,其默认值为“delete”。
1.删除策略
按照时间来配置删除策略,配置内容:
# 系统默认保存7天
log.retention.hours=168
按照保留大小来删除过期数据,配置内容:
# 系统默认没有设置大小
log.retention.bytes=-1
另外,也可以同时配置时间和大小,来进行设置混合规则。一旦日志大小超过阀值就清除分区中老的片段数据,或者分区中某个片段的的数据超过保留时间也会被清除。
2.压缩策略
如果要使用压缩策略清除过期日志,需要显示的指定属性“log.cleanup.policy”的值为“compact”。压缩清除,只能针对特定的主题应用,即写的消息数据都包含Key,合并相同Key的消息数据,只留下最新的消息数据。
5.总结
Kafka核心组件整体来说比较好理解,实际在编写应用程序时,用到比较频繁的就是生产者和消费者,因此,处理学会应用之外,我们还需要更近一步的来了解Kafka的核心组件。
6.结束语
这篇博客就和大家分享到这里,如果大家在研究学习的过程当中有什么问题,可以加群进行讨论或发送邮件给我,我会尽我所能为您解答,与君共勉!
另外,博主出书了《Hadoop大数据挖掘从入门到进阶实战》,喜欢的朋友或同学, 可以在公告栏那里点击购买链接购买博主的书进行学习,在此感谢大家的支持。
Kafka核心组件详解的更多相关文章
- Hadoop生态圈-Kafka配置文件详解
Hadoop生态圈-Kafka配置文件详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.默认kafka配置文件内容([yinzhengjie@s101 ~]$ more /s ...
- ansible安装与核心组件详解
第1章 安装anisble 1.1 安装epel源 rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarc ...
- kafka实战教程(python操作kafka),kafka配置文件详解
kafka实战教程(python操作kafka),kafka配置文件详解 应用往Kafka写数据的原因有很多:用户行为分析.日志存储.异步通信等.多样化的使用场景带来了多样化的需求:消息是否能丢失?是 ...
- kafka知识点详解
第一部分:kafka概述 一.定义(消息引擎系统) 一句话概括kafka的核心功能就是:高性能的消息发送与高性能的消息消费. kafka刚推出的时候是以消息引擎的身份出现的,它具有强大的消息传输效率和 ...
- 转载:kafka参数详解
原文:http://kafka.apache.org/documentation.html ############################# System ################# ...
- Kafka参数详解
一.相关参数配置 System 系统参数 #唯一标识在集群中的ID,要求是正数. broker.id=0 #服务端口,默认9092 port=9092 #监听地址,不设为所有地址 host.name= ...
- Hibernate核心组件详解
Hibernate是对象/关系映射(ORM,Object/Relational Mapping)的解决方案,就是将Java对象与对象关系映射到关系型数据库中的表格与表格之间的关系.它是Java应用与关 ...
- streaming kafka direct 详解
http://blog.cloudera.com/blog/2015/03/exactly-once-spark-streaming-from-apache-kafka/ http://www.jia ...
- Kafka 学习之路(四)—— Kafka消费者详解
一.消费者和消费者群组 在Kafka中,消费者通常是消费者群组的一部分,多个消费者群组共同读取同一个主题时,彼此之间互不影响.Kafka之所以要引入消费者群组这个概念是因为Kafka消费者经常会做一些 ...
随机推荐
- 你能用Java覆盖静态方法吗?如果我在子类中创建相同的方法是编译时错误?
不,你不能在Java中覆盖静态方法,但在子类中声明一个完全相同的方法不是编译时错误,这称为隐藏在Java中的方法.你不能覆盖Java中的静态方法,因为方法覆盖基于运行时的动态绑定,静态方法在编译时使用 ...
- 通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?
Dao接口即Mapper接口.接口的全限名,就是映射文件中的namespace的值:接口的方法名,就是映射文件中Mapper的Statement的id值:接口方法内的参数,就是传递给sql的参数. M ...
- java-等待唤醒机制(线程中的通信)-线程池
为什么需要线程间的通信 多个线程并发执行时,在默认情况下CPU时随机切换线程的,当我们需要多个线程共同完成一件任务,并且 希望他们有规律的执行,那么多线程之间需要一些协调通信,以此来帮我们达到多线程共 ...
- 区分构造函数注入和 setter 注入?
构造函数注入 setter 注入 没有部分注入 有部分注入 不会覆盖 setter 属性 会覆盖 setter 属性 任意修改都会创建一个新实例 任意修改不会创建一个新实例 适用于设置很多属性 适用于 ...
- Go 语言 结构体
Go 语言 结构体 引言Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型结构体是由一系列具有相同类型或不同类型的数据构成的数据集合结构体表示一项记录,比如保存图书 ...
- Python turtle 模块可以编写游戏,是真的吗?
1. 前言 turtle (小海龟) 是 Python 内置的一个绘图模块,其实它不仅可以用来绘图,还可以制作简单的小游戏,甚至可以当成简易的 GUI 模块,编写简单的 GUI 程序. 本文使用 tu ...
- numpy入门—numpy是什么
numpy是什么?为什么使用numpy 使用numpy库与原生python用于数组计算性能对比
- Polymer API开发指南 (二)(翻译)
公开 property 当你公开一个 Polymer 元素的 property 名字时,就等于把这个 property 设置为公开API了.公开 property 会有如下的特性: 支持声明数据双向绑 ...
- 2D骨骼动画工具DragonBones的使用教程
怎样用更少的美术成本创造出更生动的动画效果?今天就为大家介绍一套开源的2D骨骼动画框架和工具--DragonBones,它包含了桌面骨骼动画制作工具DragonBonesPro和一套多语言版本的Dra ...
- java中为什么接口中的属性都默认为static和final?
1)为什么接口中的属性都默认为static和final?Sun公司当初为什么要把java的接口设计发明成这样?[新手可忽略不影响继续学习]答:马克-to-win:接口中如果可能定义非final的变量的 ...