kafka概述

what:

  为什么要用消息队列?   

    解耦:允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。
    可恢复性:系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
    缓冲:有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致的情况。
    灵活性与峰值处理能力:在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见。如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。
    异步通信:很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。

 

  架构

  

    Producer :消息生产者,就是向kafka broker发消息的客户端。
    Consumer :消息消费者,向kafka broker取消息的客户端。
    Consumer Group (CG):消费者组,由多个consumer组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费;消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
    Broker :一台kafka服务器就是一个broker。一个集群由多个broker组成。一个broker可以容纳多个topic。
    Topic :可以理解为一个队列,生产者和消费者面向的都是一个topic。
    Partition:为了实现扩展性,一个非常大的topic可以分布到多个broker(即服务器)上,一个topic可以分为多个partition,每个partition是一个有序的队列。
    Replica:副本,为保证集群中的某个节点发生故障时,该节点上的partition数据不丢失,且kafka仍然能够继续工作,kafka提供了副本机制,一个topic的每个分区都有若干个副本,一个leader和若干个follower。
    leader:每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数据的对象都是leader。
    follower:每个分区多个副本中的“从”,实时从leader中同步数据,保持和leader数据的同步。leader发生故障时,某个follower会成为新的follower。

 

  数据的可靠性

  topic的每个partition收到producer发送的数据后,都需要向producer发送ack,分三种机制:

    0:producer不等待broker的ack,这一操作提供了一个最低的延迟,broker一接收到还没有写入磁盘就已经返回,当broker故障时有可能丢失数据。

    1:producer等待broker的ack,partition的leader落盘成功后返回ack,如果在follower同步成功之前leader故障,那么将会丢失数据。

 

    -1:producer等待broker的ack,partition的leader和follower全部落盘成功后才返回ack。但是如果在follower同步完成后,broker发送ack之前,leader发生故障,那么会造成数据重复。 

 

 

  数据同步:

    Leader维护了一个动态的in-sync replica set (ISR),意为和leader保持同步的follower集合。当ISR中的follower完成数据的同步之后,leader就会给producer发送ack。如果follower长时间未向leader同步数据,则该follower将被踢出ISR,该时间阈值由replica.lag.time.max.ms参数设定。Leader发生故障之后,就会从ISR举新的leader。

 

   

  follower故障恢复

    follower发生故障后会被临时踢出ISR,待该follower恢复后,follower会读取本地磁盘记录的上次的HW,并将log文件高于HW的部分截取掉从HW开始向leader进行同步。等该follower的LEO大于等于Partition的HW,即follower追上leader之后,就可以重新加入ISR了。

 

  leader故障恢复

    leader发生故障之后,会从ISR出一个的leader,之后,为保证多个副本之间的数据一致性,其余的follower会先将各自的log文件高于HW的部分截掉,然后从新的leader同步数据

 

  offerset的保存

    Kafka 0.9版本之前,consumer默认将offset保存在Zookeeper中。

    从0.9版本开始,consumer默认将offset保存在Kafka一个内置的topic中,该topic为__consumer_offsets

 

  零拷贝:

    零拷贝并不是不需要拷贝,而是减少不必要的拷贝次数。通常是说在IO读写过程中。

 

 

     正常是4次拷贝: 

      第一次:将磁盘文件,读取到操作系统内核缓冲区。
      第二次:将内核缓冲区的数据,copy到application应用程序的buffer。
      第三步:将application应用程序buffer中的数据,copy到socket网络发送缓冲区(属于操作系统内核的缓冲区)
      第四次:将socket buffer的数据,copy到网卡,由网卡进行网络传输。

 

    零拷贝是指读取磁盘文件后,不需要做其他处理,直接用网络发送出去。即:第二次和第三次数据copy不需要。

 

  Exactly Once

    服务器的ACK级别设置为-1,可以保证Producer到Server之间不会丢失数据,即At Least Once语义。相对的,将服务器ACK级别设置为0,可以保证生产者每条消息只会被发送一次,即At Most Once语义

    0.11版本的Kafka,引入了一项重大特性:幂等性。

    At Least Once + 幂等性 = Exactly Once

 

  幂等性原理

    开启幂等性的Producer在初始化的时候会被分配一个PID,发往同一Partition的消息会附带Sequence Number。而Broker端会对<PID, Partition, SeqNumber>做缓存,当具有相同主键的消息提交时,Broker只会持久化一条。

    注意:PID重启就会变化,同时不同的Partition也具有不同主键,所以幂等性无法保证跨分区跨会话的Exactly Once。

 

posted @ 2022-07-23 16:59  修心而结网  阅读(20)  评论(0编辑  收藏  举报