• Kafka工作原理与工作过程


    一、Kafka简介  

      Kafka是一个快速的、可扩展的、高吞吐的、可容错的分布式发布订阅系统,与传统的消息中间件(ActiveMQ、RabbitMQ)相比,Kafka具有高吞吐量、内置分区、支持消息副本和高容错的特点,非常适合大规模消息处理应用程序。

      其系统架构如下所示

      

       Kafka的应用场景很多,以下是几个比较常见的场景:

        消息系统 Messaging

        Web网站活动追踪  Website Activity Tracking

        数据监控 Metrics

        日志聚合 Log Aggregation

        流处理 Stream Processing

        事件源 Event Sourcing

        提交日志 Commit Log

      Kafka与其他MQ相比最大的特点就是吞吐率高,为了增加存储能力,Kafka将所有的消息都存放在了硬盘上,但是由于Kafka采用了如下方式,其仍然保证了高吞吐率:

        顺序读写:Kafka将消息写入到了分区partition中,而分区中消息是顺序读写的,顺序读写的速度要远高于随机读写 

        零拷贝:生产者、消费者对于Kafka中消息的操作是采用零拷贝实现的。

        批量发送:Kafka允许使用批量消息发送模式

        消息压缩:Kafka支持对消息进行压缩

    二、Kafka的基本术语

    术语 说明
    Topic 主题,用于划分消息类型,类似于分类标签,是个逻辑概念
    Partition 分区,topic中的消息被分割为一个或多个partition,是一个物理概念,对应到系统上的是一个或者多个目录
    Segment 段,将partition进一步细分为若干个段,每个segment文件的最大大小相等
    Broker Kafka集群包含一个或多个服务器,每个服务器节点称为一个Broker,一个topic中设置partition的数量是broker的整数倍
    Producer 生产者,即消息发送者,会将消息发送到相应的partition中
    Consumer Group 消费组,一个partition中的消息只能被同一个消费组中的一个消费者进行消费;而一个消费组内的消费者只会消费一个或者几个特定的partition
    Replication of partition 分区副本,副本是一个分区的备份,是为了防止消息丢失而创建的分区备份
    Partition Leader 每个partition有多个副本,其中有且仅有一个作为Leader,Leader是当前负责读写的partition,即所有读写操作只能发生于Leader分区上
    Partition Follower 所有Follower都要从Leader上同步消息,Follower与Leader始终保持消息同步;partition leader与partition follower之间是主备关系而非主从关系
    ISR ISR:In-Sync Replicas,是指副本同步列表;AR:Assiged Replicas,指所有副本;OSR:Outof-Sync Replicas;AR=ISR+OSR 
    offset 偏移量,每个消息都有一个当前Partition下唯一的64字节的offset,他是相当于当前分区第一条消息的偏移量
    offset commit  当consumer从partition中消费了消息后,consumer会将其消费消息的offset提交给broker,表示当前partition已经消费到了该offset所标识的消息。
    Rebalance 当消费者组中消费者数量发生变化或者topic中partition数量发生变化,partition的所有权会在消费者间转移,即partition会重新分配。
    __commit_offsets  消费者提交的offset被封装为了一种特殊的消息被写入到一个由系统创建的、名称为__commit_offstes的特殊topic的partition中,该topic默认包含50个partition,这些offset的默认有效期为一天
    Broker Controller Kafka集群的多个broker中,会有一个被选举为controller,负责管理集群中partition和副本replicas的状态。 
    Zookeeper  负责维护和协调Broker,负责Broker Controller的选举;这里要说明一下,Broker Controller是由Zookeeper选举出来的,而Partition Leader是由Broker Controller选举出来的。
    Group Coordinator group coordinator是运行在broker上的线程,主要用于consumer group中各个成员的offset位移管理和Rebalance;Group Coordinator同时管理着当前broker的所有消费者组。当Consumer需要消费数据时,并不是直接中__comsumer_offset的partition中获取的,而是从当前broker的Coordinator的缓存中获取的。而缓存中的数据是在consumer消费完提交offset时,同时提交到coordinator的缓存以及__consumer_offset的partition中的。

    三、Kafka的工作原理及过程

      路由策略:

        在通过API方式发布消息时,生产者是以Record为消息进行发布的,Record中包含Key和Value,其中value就是我们真正要使用的消息,而key是用于路由消息要存放的位置的。

        消息要放入到哪个partition并不是随机的,而是按照以下路由策略进行处理的:

          如果制定了partition,则直接写入指定的partition

          如果没有指定partition但是指定了key,则通过key的hash值与partition数量进行取模,取模结果就是partition的索引

          如果partition和key都未指定,则使用轮询算法选出一个partition

      消息写入算法:

        

         1、producer向broker集群提交连接请求,其所连接上的任意一个broker都会向其发送broker controller的通信URL,即broker controller主机配置文件中的listeners地址

        2、当producer指定了要生产消息的topic后,其会向broker contriller发送请求,请求当前topic的所有partition leader

        3、broker controller在接收到请求后,会从zk服务器中查找指定topic的所有partition leader返回给producer

        4、producer在接收到partition leader列表后,会根据路由策略找到对应的partition leader,将消息发送该partition leader

         5、leader将消息写入log,并通知ISR中的followers

        6、ISR中的follower从leader中同步消息后向leader发送ACK消息

        7、leader收到了所有ISR中的follower的ACK后,增加HW,表示消费者可以消费到该位置;如果leader在等待的follower的ACK超时了,发现还有follower没有发送ACK,则会将这些没有发送ACK的follower从ISR中剔除,然后再增加HW

      HW(高水位):

        上面说到leader收到了所有ISR中的follower的ACK后,就会增加HW,这里的HW是高水位的意思,表示consumer可以消费到的最高partition偏移量。

        HW保证了Kafka集群中消息的一致性,确切地说,是在broker集群正常运转的情况下,保证了partition的follower和leader之间数据的一致性。

        LEO,Log End Offset,日志最后消息的偏移量,消息是被写入到Kafka的日志文件中的,这是当前最后一个写入的消息在partition中的偏移量。

        对于新写入的消息,consumer是不能立刻消费的,leader会等待该消息被所有的ISR中的partition follower同步后才会更新HW,此时消息才能被consumer消费。

        

       HW截断机制:

        如果partition leader接收到了新的消息,ISR中其他follower正在同步过程中,还未同步完毕leader就挂了,此时就需要选举新的leader,若没有HW截断机制,将会导致partition中Leader与Follower数据不一致。

        当原leader宕机恢复后,将其LEO回退到宕机时的HW,然后再与新的Leader进行数据同步,这种机制称为HW截断机制。

        HW截断机制会引起数据丢失。

      消息发送的可靠性机制:

        生产者向Kafka发送消息时,可以选择可靠性级别,通过acks参数的值进行设置

        0:异步发送,生产者向kafka发送消息而不需要kafka反馈成功ack,该方式效率最高,但是可靠性最低,可能会存在数据丢失的问题。

        1:同步发送,默认值。生产者发送消息给kafka,broker的partition leader在收到消息后,会反馈ack,生产者收到后才会在发送消息,如果一直未收到kafka的ack,则生产者会认为消息发送失败,会重发消息。该种情况,仍然可能存在数据丢失的问题,因为如果partition leader收到消息并返回了ack,但是在同步partition follower时leader发生宕机,此时需要选举新的leader,即HW截断机制的发生。

        -1:同步发送,其值等同于all,生产者发送消息给kafka,kafka收到消息后,要等到ISR列表中的所有副本都同步消息完成后,才向生产者发送ack。该模型的可靠性最高,很少出现数据丢失的情况,但是可能出现部分follower重复接收消息的情况(不是重复消息)。

      消费者消费过程解析:

        

        1、consumer向broker集群提交连接请求,其所连接上的任意broker都会向其发送broker controller的通信URL,即broker controller主机配置文件中的listeners。

        2、当consumer指定了要消费的topic后,其会向broker controller发送poll请求

        3、broker controller会为consumer分配一个或这几个partition leader,并将该partition的当前offset发送给consumer

        4、consumer会按照broker controller分配的partition对其中的消息进行消费

        5、当consumer消费完该条数据后,消费者会向broker发送一个消息已被消费的反馈,即该消息的offset。

        6、当broker接收到consumer的offset后,会将其更新到__consumer_offset中

        7、以上过程一直重复,直到消费者停止请求消息;消费者可以重置offset,从而可以灵活的消费存储在broker上的消息

      Partititon Leader选举范围:

        当leader挂了后,broker controller会从ISR中选一个follower成为新的leader,但是如果所有的follower都挂了怎么办?可以通过unclean.leader.election.enable的取值来设置leader的选举范围。

        false:必须等待ISR列表中由副本活过来才进行新的选举,该策略可靠性有保证,但是可用性低

        true:在ISR中没有副本存活的情况下,可以选择任何一个该topic的partition作为新的leader,该策略可用性高,但是可靠性没有保证,可能会引发大量的消息丢失。

      重复消费问题即解决方案:

        重复消费最常见的有两种情况:同一个consumer的重复消费和不同consumer的重复消费

        同一个consumer的重复消费:

          当consumer由于消费能力较低而引发消费超时时,则可能会引发重复消费。

          解决方案:可以减少读取的消息个数,也可以演唱自动提交的时间,还可以将自动提交转变为手动提交。

        不同consumer的重复消费:

          当consumer消费了消息但还未提交offset时宕机,则这些已被消费过的消息会被重复消费。

        

    ------------------------------------------------------------------
    -----------------------------------------------------------
    ---------------------------------------------
    朦胧的夜 留笔~~
  • 相关阅读:
    JS 获取本月第一天零点时间戳并转化成yy-mm-dd
    JS 两个对象数组合并并去重
    element ui datePicker 设置当前日期之前的日期不可选
    整理一些vue elementui 问题 + 链接方法
    css 修改placeholder的颜色
    js循环内0.5s停止
    自定义border 为 dashed 时的虚线间距
    如何让浮动元素水平/垂直居中
    centos7.6设置sftp服务
    HikariCP Druid比较
  • 原文地址:https://www.cnblogs.com/liconglong/p/14560681.html
Copyright © 2020-2023  润新知