Kafka 术语及架构基础

  一、简介

目录

一、简介

1.1 消息系统介绍

1.2 发布-订阅消息传递模式

1.3 Kafka中的术语解释

       broker: Kafka 集群包含一个或多个服务器,服务器节点称为broker。

       Topic: 类似于数据库的表名

       Partition : 类似于数据库的行数据

       Producer: 生产者即数据的发布者

       Consumer: 消费者即数据的订阅者

       Consumer Group:消费者组

       Leader :partition中负责数据的读写      

       Follower: 与Leader保持数据同步

1.4 Producer在写入数据

1.5  保存数据        

         1.6 kafka集群partition分布原理分析

         1.7 Zookeeper在kafka的作用

         1.8 Kafka的特性


          Kafka是最初由Linkedin公司开发,是一个分布式、分区的、多副本的、多订阅者,基于zookeeper协调的分布式日志系统,消息中间件的一种,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。

主要应用场景是:日志收集系统和消息系统

1.1 消息系统介绍

        一个消息系统负责将数据从一个应用传递到另外一个应用,应用只需关注于数据,无需关注数据在两个或多个应用间是如何传递的,分布式消息传递基于可靠的消息队列,在客户端应用和消息系统之间异步传递消息。Kafka就是一种发布-订阅模式

有两种主要的消息传递模式:点对点传递模式、发布-订阅模式

1.2 发布-订阅消息传递模式

在发布-订阅消息系统中,消息被持久化到一个topic中。与点对点消息系统不同的是,消费者可以订阅一个或多个topic,消费者可以消费该topic中所有的数据,同一条数据可以被多个消费者消费,数据被消费后不会立马删除。在发布-订阅消息系统中,消息的生产者称为发布者,消费者称为订阅者。该模式的示例图如下:

发布者发送到topic的消息,只有订阅了topic的订阅者才会收到消息

1.3 Kafka中的术语解释

       broker: Kafka 集群包含一个或多个服务器,服务器节点称为broker。

          Broker是kafka实例,每个服务器上有一个或多个kafka的实例, 姑且认为每个broker对应一台服务器。每个kafka集群内的broker都有一个不重复的编号,如图中的broker-0、broker-1等……

     Topic: 类似于数据库的表名

        消息的主题,可以理解为消息的分类,kafka的数据就保存在topic。在每个broker上都可以创建多个topic。

       Partition : 类似于数据库的行数据

       Topic的分区,每个topic可以有多个分区,分区的作用是做负载,提高kafka的吞吐量。同一个topic在不同的分区的数据是不重复的,partition的表现形式就是一个一个的文件夹!

    为什么要分区呢?

"""为了性能考虑,如果不分区每个topic的消息只存在一个broker上,
那么所有的消费者都是从这个broker上消费消息,那么单节点的broker成为性能的瓶颈,
如果有分区的话生产者发过来的消息分别存储在各个broker不同的partition上,
这样消费者可以并行的从不同的broker不同的partition上读消息,实现了水平扩展。
"""

   分区文件下到底存了那些东西?

"""每个分区下保存了很多文件,而概念上我们把他叫segment,即每个分区都是又多个segment构成的,
其中index(索引文件),log(数据文件),time index(时间索引文件)统称为一个segment。"""

test-topic-0  
├── 00000000000000000001.index  
├── 00000000000000000001.log  
├── 00000000000000000001.timeindex  
├── 00000000000000001018.index  
├── 00000000000000001018.log  
├── 00000000000000001018.timeindex  
├── 00000000000000002042.index  
├── 00000000000000002042.log  
├── 00000000000000002042.timeindex

     Segment:每个分区的分段数据

        partition物理上由多个segment组成。Segment中核心文件是index索引文件和log数据文件,实现更高效的定位到数据

在这里插入图片描述

  为什么有了partition还需要segment ?

"""通过上面目录显示存在多个segment的情况,既然有分区了还要存多个segment干嘛?
如果不引入segment,那么一个partition只对应一个log文件,随着消息的不断发送这个文件不断增大,
由于kafka的消息不会做更新操作都是顺序写入的,如果做消息清理的时候只能删除文件的前面部分删除,
不符合kafka顺序写入的设计,如果多个segment的话那就比较方便了,
直接删除整个文件即可保证了每个segment的顺序写入"""

索引文件和数据文件中到底是存了什么内容?

"""实索引文件中其实就保存了offset和position,分别是消息的offset也就是具体那一条消息,
position表示具体消息存储在log中的物理地址。"""

# 索引文件:
offset: 1049 position: 16205  
offset: 1065 position: 32410  
offset: 1081 position: 48615  
offset: 1097 position: 64820  
offset: 1113 position: 81025  
offset: 1129 position: 97230

# log文件:

"""log数据文件中并不是直接存储数据,而是通过许多的message组成,message包含了实际的消息数据
"""

  kafka并不是每个offset都保存了,每隔6个offset存储一条索引数据,为什么在index文件中这些offset编号不是连续的呢?

"""因为index文件中并没有为数据文件中的每条消息都建立索引,
而是采用了稀疏存储的方式,每隔一定字节的数据建立一条索引。
这样避免了索引文件占用过多的空间,从而可以将索引文件保留在内存中。
但缺点是没有建立索引的Message也不能一次定位到其在数据文件的位置,
从而需要做一次顺序扫描,但是这次顺序扫描的范围就很小了。"""

消费者如何通过offset查找message?(偏移量区别

# 假如我们想要读取offset=1066的message,需要通过下面2个步骤查找。

"""查找segment file
00000000000000000000.index表示最开始的文件,起始偏移量(offset)为0.
第二个文件00000000000000001018.index的消息量起始偏移量为1019 = 1018 + 1.
(可能是版本区别,可忽略,偏移量是否+1)
同样,第三个文件00000000000000002042.index的起始偏移量为2043=2042 + 1,
其他后续文件依次类推,以起始偏移量命名并排序这些文件,
只要根据offset 二分查找文件列表,就可以快速定位到具体文件。
当offset=1066时定位到00000000000000001018.index|log

通过segment file查找message
通过第一步定位到segment file,当offset=1066时,依次定位到00000000000000001018.index
的元数据物理位置和00000000000000001018.log的物理偏移地址,此时我们只能拿到1065的
物理偏移地址,然后再通过00000000000000001018.log顺序查找直到offset=1066为止。
每个message都有固定的格式很容易判断是否是下一条消息
"""

 

        Message:每一条发送的消息主体。 

        Replication:副本的作用是做备胎

       引入Replication之后,同一个Partition可能会有多个Replication,这些Replication之间选出一个Leader,Producer和Consumer只与这个Leader交互,Leader 在partition中负责数据的读写,其它Replica作为Follower从Leader中复制数据,follower跟随Leader,所有写请求都通过Leader路由,数据会广播给所有Follower。follower跟随Leader,所有写请求都通过Leader路由,数据会广播给所有Follower

       在kafka中默认副本的最大数量是10个,且副本的数量不能大于Broker的数量,follower和leader绝对是在不同的机器,同一机器对同一个分区也只可能存放一个副本(包括自己)。

       如果Leader失效,则从Follower中选举出一个新的Leader。当Follower与Leader挂掉、卡住或者同步太慢,leader会把这个follower从“in sync replicas”(ISR)列表中删除,重新创建一个Follower。

      Producer: 生产者即数据的发布者

       该角色将消息发布到Kafka的topic中。broker接收到生产者发送的消息后,broker将该消息追加到当前用于追加数据的segment文件中。生产者发送的消息,存储到一个partition中,生产者也可以指定数据存储的partition。

     Consumer: 消费者即数据的订阅者

        消费者可以从broker中读取数据。消费者可以消费多个topic中的数据。

      Consumer Group:消费者组

        多个消费组组成一个消费者组,在kafka的设计中同一个分区的数据只能被消费者组中的某一个消费者消费。同一个消费者组的消费者可以消费同一个topic的不同分区的数据,这也是为了提高kafka的吞吐量!。

      Zookeeper:

        kafka集群依赖zookeeper来保存集群的的元信息,来保证系统的可用性。

  1. 无论是kafka集群,还是producer和consumer都依赖于zookeeper来保证系统可用性集群保存一些meta信息。
  2. Kafka使用zookeeper作为其分布式协调框架,很好的将消息生产、消息存储、消息消费的过程结合在一起。
  3. 同时借助zookeeper,kafka能够生产者、消费者和broker在内的所以组件在无状态的情况下,建立起生产者和消费者的订阅关系,并实现生产者与消费者的负载均衡。

   1.4 Producer在写入数据

 发送的流程就在图中已经说明了,就不单独在文字列出来了!需要注意的一点是,消息写入leader后,follower是主动的去leader进行同步的!producer采用push模式将数据发布到broker,每条消息追加到分区中,顺序写入磁盘,所以保证同一分区内的数据是有序的!写入示意图如下:

分区的主要目的是:

   1、 方便扩展。因为一个topic可以有多个partition,所以我们可以通过扩展机器去轻松的应对日益增长的数据量。
  2、 提高并发。以partition为读写单位,可以多个消费者同时消费数据,提高了消息的处理效率。

那在kafka中,如果某个topic有多个partition,producer又怎么知道该将数据发往哪个partition呢?

       1、 partition在写入的时候可以指定需要写入的partition,如果有指定,则写入。
  2、 如果没有指定partition,但是设置了数据的key,则会根据key的值hash出一个partition。
  3、 如果既没指定partition,又没有设置key,则会轮询选出一个partition。 

   1.5  保存数据         

  Producer将数据写入kafka后,集群就需要对数据进行保存了!kafka将数据保存在磁盘,可能在我们的一般的认知里,写入磁盘是比较耗时的操作,不适合这种高并发的组件。Kafka初始会单独开辟一块磁盘空间,顺序写入数据(效率比随机写入高)。

        Partition 结构
  前面说过了每个topic都可以分为一个或多个partition,如果你觉得topic比较抽象,那partition就是比较具体的东西了!Partition在服务器上的表现形式就是一个一个的文件夹,每个partition的文件夹下面会有多组segment文件,每组segment文件又包含.index文件、.log文件、.timeindex文件(早期版本中没有)三个文件, log文件就实际是存储message的地方,而index和timeindex文件为索引文件,用于检索消息。

  如上图,这个partition有三组segment文件,每个log文件的大小是一样的,但是存储的message数量是不一定相等的(每条的message大小不一致)。文件的命名是以该segment最小offset来命名的,如000.index存储offset为0~368795的消息,kafka就是利用分段+索引的方式来解决查找效率的问题。

        Message结构
上面说到log文件就实际是存储message的地方,我们在producer往kafka写入的也是一条一条的message,那存储在log中的message是什么样子的呢?消息主要包含消息体、消息大小、offset、压缩类型……等等!我们重点需要知道的是下面三个:
  1、 offset:offset是一个占8byte的有序id号,它可以唯一确定每条消息在parition内的位置!
  2、 消息大小:消息大小占用4byte,用于描述消息的大小。
  3、 消息体:消息体存放的是实际的消息数据(被压缩过),占用的空间根据具体的消息而不一样。

        存储策略
  无论消息是否被消费,kafka都会保存所有的消息。那对于旧数据有什么删除策略呢?
  1、 基于时间,默认配置是168小时(7天)。
  2、 基于大小,默认配置是1073741824。
  需要注意的是,kafka读取特定消息的时间复杂度是O(1),所以这里删除过期的文件并不会提高kafka的性能!

        消费数据

  消息存储在log文件后,消费者就可以进行消费了。与生产消息相同的是,消费者在拉取消息的时候也是找leader去拉取。

  多个消费者可以组成一个消费者组(consumer group),每个消费者组都有一个组id!同一个消费组者的消费者可以消费同一topic下不同分区的数据,但是不会组内多个消费者消费同一分区的数据!!!

 

 图示是消费者组内的消费者小于partition数量的情况,所以会出现某个消费者消费多个partition数据的情况,消费的速度也就不及只处理一个partition的消费者的处理速度!如果是消费者组的消费者多于partition的数量,那会不会出现多个消费者消费同一个partition的数据呢?上面已经提到过不会出现这种情况!多出来的消费者不消费任何partition的数据。所以在实际的应用中,建议消费者组的consumer的数量与partition的数量一致

假如现在需要查找一个offset为368801的message是什么样的过程呢?

建立在offset为有序的基础上,利用segment+有序offset+稀疏索引+二分查找+顺序查找等多种手段来高效的查找数据!至此,消费者就能拿到需要处理的数据进行处理了

   1.6 kafka集群partition分布原理分析

  1. 在Kafka集群中,每个Broker都有均等分配Partition的Leader机会。
  2. 上述图Broker Partition中,箭头指向为副本,以Partition-0为例:broker1中parition-0为Leader,Broker2中Partition-0为副本。
  3. 上述图种每个Broker(按照BrokerId有序)依次分配主Partition,下一个Broker为副本,如此循环迭代分配,多副本都遵循此规则。
  4. 副本分配算法如下:
  5. 将所有N Broker和待分配的i个Partition排序.
  6. 将第i个Partition分配到第(i mod n)个Broker上.
  7. 将第i个Partition的第j个副本分配到第((i + j) mod n)个Broker上.

    1.7 Kafka的特性

  1. 高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒,每个topic可以分多个partition, consumer group 对partition进行consume操作;
  2. 可扩展性:kafka集群支持热扩展;
  3. 持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失;
  4. 容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败);
  5. 高并发:支持数千个客户端同时读写;
  6. 支持实时在线处理和离线处理:可以使用Storm这种实时流处理系统对消息进行实时进行处理,同时还可以使用Hadoop这种批处理系统进行离线处理;

参考:

再过半小时,你就能明白kafka的工作原理了 - 苏苏喂苏苏+ - 博客园

2  初学Kafka工作原理流程介绍 - -加勒比海带 - 博客园

3 kafka架构和工作流程深入解析

kafka消费策略 & kafka存储机制 & segment file & 稀疏存储

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

**星光*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值