zoukankan      html  css  js  c++  java
  • Kafka写入流程和副本策略

    Kafka写入流程:

    1.producer 先从 zookeeper 的 "/brokers/.../state" 节点找到该 partition 的 leader

    2. producer 将消息发送给该 leader

    3. leader 将消息写入本地 log

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

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

    副本策略:

    Kafka的高可靠性的保障来源于其健壮的副本(replication)策略。

    1) 数据同步

    kafka在0.8版本前没有提供Partition的Replication机制,一旦Broker宕机,其上的所有Partition就都无法提供服务,而Partition又没有备份数据,数据的可用性就大大降低了。所以0.8后提供了Replication机制来保证Broker的failover。

    引入Replication之后,同一个Partition可能会有多个Replica,而这时需要在这些Replication之间选出一个Leader,Producer和Consumer只与这个Leader交互,其它Replica作为Follower从Leader中复制数据。

    [root@tourbis kafka_2.10-0.8.2.1]# bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic  test

    Topic:test      PartitionCount:3        ReplicationFactor:3     Configs:

            Topic: test     Partition: 0    Leader: 1       Replicas: 1,3,2 Isr: 1,3,2

            Topic: test     Partition: 1    Leader: 2       Replicas: 2,1,3 Isr: 2,1,3

            Topic: test     Partition: 2    Leader: 3       Replicas: 3,2,1 Isr: 3,2,1

    1个Topic,3个分区,每个分区有3个副本。

    2) 副本放置策略

    为了更好的做负载均衡,Kafka尽量将所有的Partition均匀分配到整个集群上。Kafka分配Replica的算法如下:

    将所有存活的N个Brokers和待分配的Partition排序

    将第i个Partition分配到第(i mod n)个Broker上,这个Partition的第一个Replica存在于这个分配的Broker上,并且会作为partition的优先副本

    将第i个Partition的第j个Replica分配到第((i + j-1) mod n)个Broker上

    假设集群一共有4个brokers,一个topic有4个partition,每个Partition有3个副本。下图是每个Broker上的副本分配情况。

            1                       2                          3                      4

    3)同步策略

    Producer在发布消息到某个Partition时,先通过ZooKeeper找到该Partition的Leader,然后无论该Topic的Replication Factor为多少,Producer只将该消息发送到该Partition的Leader。Leader会将该消息写入其本地Log。每个Follower都从Leader pull数据。这种方式上,Follower存储的数据顺序与Leader保持一致。Follower在收到该消息并写入其Log后,向Leader发送ACK。一旦Leader收到了ISR中的所有Replica的ACK,该消息就被认为已经commit了,Leader将增加HWhigh watermark并且向Producer发送ACK。

    为了提高性能,每个Follower在接收到数据后就立马向Leader发送ACK,而非等到数据写入Log中。因此,对于已经commit的消息,Kafka只能保证它被存于多个Replica的内存中,而不能保证它们被持久化到磁盘中,也就不能完全保证异常发生后该条消息一定能被Consumer消费。

    Consumer读消息也是从Leader读取,只有被commit过的消息才会暴露给Consumer。

  • 相关阅读:
    (OK) port_lighttpd_to_Android——没有基于android 4.4源码
    Linux添加头文件路径—INCLUDE_PATH
    (OK) 交叉编译hello.c for android (--sysroot),不使用Android.mk和ndk-build
    Building and running Node.js for Android
    编译node-v4.2.1,出现错误:undefined reference to getpwuid_r
    我为什么向后端工程师推荐Node.js
    (OK) 编译 pcre-8.37 静态库
    port_lighttpd_to_Android——基于android 4.4源码
    深受C/C++程序员欢迎的11款IDE
    推荐!国外程序员整理的 PHP 资源大全
  • 原文地址:https://www.cnblogs.com/dummyly/p/10097697.html
Copyright © 2011-2022 走看看