Kafka

kafka工作原理解析

  1. 有两个生产者,生产Topic(不同的Topic表示不同消息的类型)
  • 消息的类型可以是web前端产生的Page View服务器日志系统的CPUMemory
  1. 每一个topic中的partition都会有副本(replices),例如一个topic1,有两个partition,另一个topic有一个partition(一个partition对应),每一个partition有三个副本。
  2. 确定brokers的个数(集群中服务器节点的个数),使用zookeeper管理集群,使负载均衡,将partition的副本分别分到4个brokers中,
  3. 从每一个partition的副本中选取一个leader,其他为follower,这样就可以在一个leader挂掉了以后,在选举一个leader出来
  4. 消费者消费数据(partition中的leader)
  5. zookeeper在Consumer Group发生变化时进行rebalance

二、topic和paritition

kafka工作原理解析

  1. Kafka读取特定消息的时间复杂度为O(1),这是因为消息都放在队列中,每次只需要在队列中读取消息。kafka在接收到生产者发送的消息之后,会根据均衡策略将消息存储到不同的分区中。因为每条消息都被append到该Partition中,属于顺序写磁盘

  2. Kafka提供两种策略删除旧数据:

    • 定时删除

    • 定量删除(超过某个设定的大小时,删除旧数据)

  3. 正常情况下Consumer会在消费完一条消息后递增该offset。offset由Consumer控制,所以Kafka broker是无状态的,它不需要标记哪些消息被哪些消费过,也不需要通过broker去保证同一个Consumer Group只有一个Consumer能消费某一条消息,因此也就不需要锁机制.

  4. 有了Partition后,不同的消息可以并行写入不同broker的不同Partition里(通过key指定消息发送到哪个分区中)

  5. 使用Consumer high level API时,同一Topic的一条消息只能被同一个Consumer Group内的一个Consumer消费,但多个Consumer Group可同时消费这一消息。

    • 广播(发送给所有的consumer)的实现:一个consumer在一个consumerGroup中
    • 单播(发送给一个consumer)的实现:所有的consumer都在一个Group中。

kafka工作原理解析

三、传递方式(delivery guarantee)

传递方式主要包含以下几类:

  1. At most once  消息可能会丢,但绝不会重复传输
  2. At least one  消息绝不会丢,但可能会重复传输
  3. Exactly once  每条消息肯定会被传输一次且仅传输一次,很多时候这是用户所想要的。

1.在producer向服务器发送消息时的传递

  • 当Producer向broker发送消息时,一旦这条消息被commit,因replication的存在,它就不会丢。
  • 在通讯中断时,Producer就无法判断该条消息是否已经commit,可以产生一种主键(类似token),在故障时,根据幂等性多次重试,做到Exactly once
    • 幂等性:就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。
    • 幂等性常用领域:解决支付过程中,通信中断,还需要再次支付的问题(以前的解决方法是将其加入到事务控制,后面在网页上,使用token等方式作为唯一标识)

2.在consumer从服务器中读取消息时的传递

  • commit:

    会在Zookeeper中保存该Consumer在该Partition中读取的消息的offset。该Consumer下一次再读该Partition时会从下一条开始读取.

  • 未commit:

    下一次读取的开始位置会跟上一次commit之后的开始位置相同

  • autocommit:

    即Consumer一旦读到数据立即自动commit

三、kafka设计解析

1.kafka分配partition的方式

Kafka分配Replica的算法如下

  1. 将所有Broker(假设共n个Broker)和待分配的Partition排序

  2. 将第i个Partition分配到第(i mod n)个Broker上

  3. 将第i个Partition的第j个Replica分配到第((i + j) mode n)个Broker上

**目的:**为了使parition 均匀的分布在集群上。如果所有的Replica都在同一个Broker上,那一旦该Broker宕机,该Partition的所有Replica都无法工作,也就达不到HA的效果。同时,如果某个Broker宕机了,需要保证它上面的负载可以被均匀的分配到其它幸存的所有Broker上。

2.副本之间的消息传递方式

kafka工作原理解析
producer ------zookeeper—> partition(leader) —> leader将消息写入本地log(持久化到本地磁盘) —> Follwer从leader pull数据(保证follwer和leader存储数据一致)----> follwer接收到数据后立刻向leader发送ACK(不保证数据一定写入了log,所以也不能保证数据一定会被consumer消费) ----> consumer消费leader中的数据

3.ISR(in-sync replica)确保数据不丢失和吞吐率

常用的复制机制:

  1. 同步复制

    需要等所有能工作的Follower都复制完,这条消息才会被认为commit,这种复制方式极大的影响了吞吐率

  2. 异步复制

    数据只要被Leader写入log就被认为已经commit,这种情况下如果Follower都复制完都落后于Leader,而如果Leader突然宕机,则会丢失数据

kafka使用的复制机制(ISR):

ISR:如果一个Follower宕机,或者落后太多,Leader将把它从ISR(保持同步的replica列表)中移除。Follower可以批量的从Leader复制数据。

一条消息只有被ISR里的所有Follower都从Leader复制过去才会被认为已提交。这样就避免了部分数据被写进了Leader,还没来得及被任何Follower复制就宕机了,而造成数据丢失(Consumer无法消费这些数据)

producer可以等待消息是否被commit。这种机制确保了只要ISR有一个或以上的Follower,一条被commit的消息就不会丢失

4 .如何处理所有的replica中的数据都不工作

在ISR中至少有一个follower时,Kafka可以确保已经commit的数据不丢失,但如果某个Partition的所有Replica都宕机了,就无法保证数据不丢失了。这种情况下有两种可行的方案:

  1. 等待ISR中的任一个Replica“活”过来,并且选它作为Leader

    • 可能等待的时间较长
    • 如果ISR中的所有Replica都无法“活”过来了,或者数据都丢失了,这个Partition将永远不可用
  2. 选择第一个“活”过来的Replica(不一定是ISR中的)作为Leader

    • 不能保证已经包含了已经commit的所有消息,导致数据丢失

5.producer写入消息的流程

kafka工作原理解析
流程的步骤:

  • producer 先从 zookeeper 的 “/brokers/…/state” 节点找到该 partition 的 leader

  • producer 将消息发送给该 leader

  • leader 将消息写入本地 log

  • followers 从 leader pull 消息,写入本地 log 后 leader 发送 ACK

  • leader 收到所有 ISR 中的 replica 的 ACK 后,增加 HW(high watermark,最后 commit 的 offset) 并向 producer 发送ACK

相关文章: