kafka官方文档解读

Kafka是一种分布式的,基于发布/订阅的消息系统。

Kafka目前主要作为一个分布式的发布订阅式的消息系统使用,由Scala写成。

1、Kafka消息传输流程

整体架构
kafka整体架构
图1

  • 其中:Producer:生产者;Broker:kafka的服务器;Consumer:消费者;Zookeeper:对整个Producer、Broker、Consumer进行协调。

Producer: Producer-生产者将数据发布到他们选择的主题。生产者负责选择哪个记录分配给主题中的哪个分区。这可以通过循环的方式来完成,只是为了平衡负载,或者可以根据一些语义分区功能(比如记录中的某个键)来完成。

已经发布的消息保存在一组服务器中,它们被称之为代理(Broker)或者kafka集群

Broker:消息中间处理节点,一个kafka节点就是一个Broker,多个Broker可以组成一个kafka集群。


Topic: Topic-主题是记录发布消息的类别名或饲料名称。kafka的主题是多订阅 的,也就是一个主题可以有0个,1个或者多个consumer订阅。一个Topic由多个分区组成,每个分区都是有序的不断追加记录的一个结构化序列,每个分区中的记录都分配了一个连续的ID号,称为唯一地标识分区中每个记录的偏移量。


在kafka中,topic只是一个逻辑概念,是producer与consumer之间交换的桥梁,与消息本身的存储broker没有关系。同时,在kafka中,对各个topic消息采取的独立分区分布式存储的方式,能够利用分布式,极大地增强传输效率。


每个分区都有一个服务器充当“leader”和零个或多个充当“followers”的服务器。“leader”处理分区的所有读写请求,而“followers”被动地复制领导者。如果leader失败,其中一个followers将自动成为新的leader。每个服务器充当它的一些分区的leader和其他人的followers,因此集群内的负载平衡得很好。


Consumer: Consumer-消费者将自己标记为一个消费者组,并将每个发布到主题的记录传递给每个订阅消费群组中的一个消费者实例。消费者实例可以是独立的进程,也可以是独立的机器。

  • 如果所有的消费者实例都具有相同的消费群,那么记录将有效地在消费者实例上进行负载平衡。
  • 如果所有的消费者实例都有不同的消费群体,那么每个记录将被广播到所有消费者进程。

Producer即生产者,向Kafka集群发送消息,在发送消息之前,会对消息进行分类,即Topic

Topic即主题,通过对消息指定主题可以将消息分类,消费者可以只关注自己需要的Topic中的消息

Consumer即消费者,消费者通过与kafka集群建立长连接的方式,不断地从集群中拉取消息,然后可以对这些消息进行处理。

什么是进程(Process):普通的解释就是,进程是程序的一次执行,而什么是线程(Thread),线程可以理解为进程中的执行的一段程序片段。在一个多任务环境中下面的概念可以帮助我们理解两者间的差别:进程间是独立的,这表现在内存空间,上下文环境;线程运行在进程空间内
一般来讲(不使用特殊技术)进程是无法突破进程边界存取其他进程内的存储空间;而线程由于处于进程空间内,所以同一进程所产生的线程共享同一内存空间。同一进程中的两段代码不能够同时执行,除非引入线程。线程是属于进程的,当进程退出时该进程所产生的线程都会被强制退出并清除。线程占用的资源要少于进程所占用的资源。进程和线程都可以有优先级。在线程系统中进程也是一个线程。可以将进程理解为一个程序的第一个线程。

线程是指进程内的一个执行单元,也是进程内的可调度实体.与进程的区别:(1)地址空间:进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间;(2)进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源(3)线程是处理器调度的基本单位,但进程不是.(4)二者均可并发执行.


消息传递有两种模式:队列和发布订阅。 在队列中,一个用户池可以从服务器读取,每个记录转到其中一个用户,在发布订阅中,记录被广播给所有消费者;

队列的优势在于它允许您在多个消费者实例上划分数据处理,这使您可以扩展处理过程。不幸的是,一旦一个进程读取数据,队列就不是多订阅服务器了

发布订阅的优势在于允许您向多个进程广播数据,但由于每个消息都传递给每个订阅者,所以没有缩放处理的方法。

2、Kafka服务器消息存储策略


kafka的存储,不得不提到partitions,创建一个topic时,同时可以指定分区数目,分区数越多,其吞吐量也就越大,但是需要的资源也就越多,也会导致更高的不可用性,kafka在接收到生产者发送的消息之后,会根据负载均衡策略将消息存储到不同的分区中。


相关术语

Consumer Group(消费组):在kafaka中,所有消费者都属于一个消费组。
Topic(消息类型):Topic就是对消息进行逻辑上的分类。 Partition(分区):消息的分区,kafka中对消息进行分区管理。
Replica(副本):Partition的副本,主要从服务的容灾上进行备份。 Replica
Leader(副本-主):Partition分区的leader备份。 Replica
Follower(副本-从):Partition分区的Follower备份。
Segment(段文件):Topic消息的文件组成。
Offset(偏移量):消息存储的偏移量,在kafka中生产者和消费者主要是依靠Offset进行控制消息的发送和消费。


消息结构

这里写图片描述

图2

从整体流程了解一下kafka消息的结构,从大到小依次为:
Topic>>Partition>>segment>>index/log


消息结构关系

这里写图片描述

图3


由上图可以看出, 一个topic可以被拆分成多个Partition进行存储,每个partition还有自己的副本,作为容灾备份,每个Partition是由segment文件进行组成,每个segment文件又由两类文件组成,一类是index索引文件,主要是存储元数据和位置的关系,一类是log文件,主要存储的是数据文件。

这里写图片描述

图4

上图形象的描述了Partition中段文件存储方式。
每个Partition(目录)相当于一个巨型文件被平均分配到多个大小相等的segment(段)数据文件中。但是每个段segment file消息数量不一定相等,这种特性方便old segment file快速删除。

segment file的组成和物理结构

  • segment file组成:由2大部分组成,分别为index file和data file,此2个文件一一对应,成对出现,后缀“.index”和“.log”分别表示为segment索引文件和数据文件。
  • segment文件的命名规则:Partition全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值。数值最大的为64位的long大小,19位数字字符长度,没有数字用0填充。

接下来,以一对segment file文件为例,说明segment中index-data file对应物理结构如下:
这里写图片描述

图5

上图索引文件xxx.index存储大量元数据,数据文件xxx.log存储大量消息,索引文件xxx.index中元数据指向对应数据文件中message的物理偏移地址。其中以索引文件中元数据为3497为例,依次在数据文件中表示地3个message(在全局partition表示第368772个message)、以及该消息的物理偏移地址是497。

从上述信息中,可以了解到segment的data file由许多的message组成,接下来详细介绍message的物理结构
这里写图片描述
图6

  • 8 byte offset—-在partition(分区)内的每条消息都有一个有序的id号,这个id号被称为偏移(offset),它可以唯一确定每条消息在partition(分区)内的位置。即offset表示partition的第多少message。
  • 4 byte message size—-message的大小
  • 4 byte CRC32—-用crc32校验message
  • 1 byte “magic“—-表示本次发布Kafka服务程序协议版本号
  • 1 byte “attributes”—-表示独立版本、或标识压缩类型、或编码类型
  • 4 byte key length—-表示key的长度,当key为-1时,K byte key字段不填
  • K byte key—-可选
  • value bytes payload—-表示实际消息数据

在partition中通过offset查找message

这里写图片描述
图7

例如读取offset=368776的message
第一步:
在上图7中,其中00000000000000000000.index表示最开始的文件,起始偏移量(offset)为0.第二个文件00000000000000368769.index的消息量起始偏移量为368770 = 368769 + 1.同样,第三个文件00000000000000737337.index的起始偏移量为737338=737337 + 1,其他后续文件依次类推,以起始偏移量命名并排序这些文件,只要根据offset 二分查找文件列表,就可以快速定位到具体文件。
当offset=368776时定位到00000000000000368769.index|log
第二步:
通过第一步定位到segment file,当offset=368776时,依次定位到00000000000000368769.index的元数据物理位置和00000000000000368769.log的物理偏移地址,然后再通过00000000000000368769.log顺序查找直到offset=368776为止。


根据图5得知,segment index file采取稀疏索引存储方式,它减少索引文件大小,通过mmap可以直接内存操作,稀疏索引为数据文件的每个对应message设置一个元数据指针,它比稠密索引节省了更多的存储空间,但查找起来需要消耗更多的时间。

3、Partition分布

partition的引入能够有效解决水平扩展问题,下面以一个Kafka集群中的3个Broker举例,创建1个topic包含3个Partition分区,3个Replication副本,数据Producer流动如图8所示

这里写图片描述

当集群中新增到5个节点时,分区和副本重排,分布如图9所示
这里写图片描述

实现上述分区,副本重排的具体算法如下:
1.将所有n个Broker和待分配的i个Partition排序。
2.将第i个Partition分配到第(imodn)个Broker上。
3.将第i个Partition的第j个副本分配到第((i+j)mod n)个Broker上。

参考:
http://blog.csdn.net/ebay/article/details/46549661
http://kafka.apache.org/intro.html
https://www.cnblogs.com/hei12138/p/7805475.html
http://www.sohu.com/a/209375328_771850
http://blog.jobbole.com/89174/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值