数据存储格式

Kafka的高可靠性的保障来源于其健壮的副本(replication)策略。一个Topic可以分成多个Partition,而一个Partition物理上由多个Segment组成。

Segment分2部分:索引文件和数据文件。索引文件保存元数据,记录了消息在数据文件中的偏移(offset),消息有固定物理结构,保证了正确的读取长度。

Segment文件带来好处:方便过期文件清理。只需要整体删除过期的Segment。以追加的方式写消息,顺序写磁盘极大提高了效率。

读取某offset消息的步骤变为:通过二分查找,找到offset所在Segment。通过Segment的索引文件,找到offset所在数据文件的物理偏移。读取数据。

副本复制与同步

从外部来看Partition类似一个不断增长,存储消息的数组,每个Partition有一个类似MySQL binlog的文件用来记录数据的写入。有两个新名词,HW(HighWatermark)表示当前Consumer可以看到Partition的offset位置,LEO(LogEndOffset)表示当前Partition最新消息的offset,各个副本单独维护。为了提高消息可靠性,Partition有N个副本。

N个副本中,有一个Leader,余下N-1个Follower。Kafka的写操作只在Leader副本上进行。通常这种副本写有两种方式:

  1. Leader写日志文件成功即返回成功。这样如果Follower在同步完数据前Leader当机,数据丢失。这种方式带来较高效率。

  2. Leader等待Follwer写日志成功并收到返回的acks后,才返回成功。这样Leader当机,重新选举的Leader与当机Leader数据一致,数据不丢失。但因为要等待Follwer返回,效率较慢。一般采用少数服从多数的选举方式,如果要应对f个副本当机,则至少需要2f+1个副本并使中的f+1个写成功。

Kafka没有使用上述机制。它实现了ISR(In-Sync Replication)的机制。

ISR(In-Sync Replication)机制

Leader维护一个副本队列(包含Leader自己),会及时将慢响应的Follwer剔除,并将追上Leader数据的Follower重新加入副本队列。

这样要保证数据高可靠所需要的副本数更少。比如应对2台机器的当机,ISR机制只需要3个副本。而上述机制2则需要2*2+1个副本。这样有效节约了大约一半的存储空间。

Leader当机,新的Leader是从ISR中按顺序选出。Leader恢复后成为Follower,删除上一个HW后所有数据后,从新的Leader进行同步。

数据可靠性配置

以下逻辑,可以保证一定程序数据可靠。当然副本越多,min.insync.replicas越大,则越可靠,但实际情况需要根据场景在效率与数据可靠上做权衡。

  1. 副本数设置为3。副本是Kafka实现HA的基础,通过replication.factor配置

  2. min.insync.replicas设置为2。ISR副本队列中副本最小个数。极端情况下,ISR中只有一个Leader副本,若Leader当机则服务不可用。因此至少配置为2个。若ISR中副本小于这个数字,Producer返回异常。

  3. 配置Leader选举条件unclean.leader.election.enable=false,只允许Leader从ISR队列中选出。

  4. request.required.acks=-1(等待ISR中的所有Follower都收到数据才返回成功),producer.type=sync(同步调用)

以上,保证了一个副本所在机器当机,Kafka仍提供服务,且数据正确未丢失。

数据去重

以上配置,保证了只要Leader返回成功,即不存在数据丢失。但考虑一种情况,Producer提交写请求到Leader后,Producer到Leader网络断开,此时Producer认为写失败。但实际,Follower正常同步到了Leader数据,HW更新。

此时Producer因为发送失败,会重发消息。此时Kafka中存在重复数据。这需要在Consume时业务逻辑中去重。Kafka本身不保证数据不重复。

Kafka高效的几个原因

1)架构层面 
1. 一个Topic多Partition部署实现并行处理,线性扩展 
2. ISR副本复制机制实现性能与可用性的平衡

2)磁盘优化 
1. Partition中顺序写磁盘 
2. mmap实现内存批量写磁盘,减少I/O次数

3)网络优化 
1. sendfile系统调用实现零拷贝,减少上下文切换 
2. Producer批量发送,减少网络I/O次数 
3. 支持数据压缩

Kafka高可用实现原理的更多相关文章

  1. Kafka高可用环境搭建

    Apache Kafka是分布式发布-订阅消息系统,在 kafka官网上对 kafka 的定义:一个分布式发布-订阅消息传递系统. 它最初由LinkedIn公司开发,Linkedin于2010年贡献给 ...

  2. Kafka 高可用设计

    Kafka 高可用设计 2016-02-28 杜亦舒 Kafka在早期版本中,并不提供高可用机制,一旦某个Broker宕机,其上所有Partition都无法继续提供服务,甚至发生数据丢失对于分布式系统 ...

  3. kafka高可用探究

    kafka高可用探究 众所周知 kafka 的 topic 可以使用 --replication-factor 数和 partitions 数来保证服务的高可用性 问题发现 但在最近的运维过程中,3台 ...

  4. Kafka —— 基于 ZooKeeper 搭建 Kafka 高可用集群

    一.Zookeeper集群搭建 为保证集群高可用,Zookeeper集群的节点数最好是奇数,最少有三个节点,所以这里搭建一个三个节点的集群. 1.1 下载 & 解压 下载对应版本Zookeep ...

  5. Kafka 学习之路(二)—— 基于ZooKeeper搭建Kafka高可用集群

    一.Zookeeper集群搭建 为保证集群高可用,Zookeeper集群的节点数最好是奇数,最少有三个节点,所以这里搭建一个三个节点的集群. 1.1 下载 & 解压 下载对应版本Zookeep ...

  6. Kafka 系列(二)—— 基于 ZooKeeper 搭建 Kafka 高可用集群

    一.Zookeeper集群搭建 为保证集群高可用,Zookeeper 集群的节点数最好是奇数,最少有三个节点,所以这里搭建一个三个节点的集群. 1.1 下载 & 解压 下载对应版本 Zooke ...

  7. 入门大数据---基于Zookeeper搭建Kafka高可用集群

    一.Zookeeper集群搭建 为保证集群高可用,Zookeeper 集群的节点数最好是奇数,最少有三个节点,所以这里搭建一个三个节点的集群. 1.1 下载 & 解压 下载对应版本 Zooke ...

  8. Kafka高可用实现

    数据存储格式 Kafka的高可靠性的保障来源于其健壮的副本(replication)策略.一个Topic可以分成多个Partition,而一个Partition物理上由多个Segment组成. Seg ...

  9. Kafka高可用的保证

    zookeeper作为去中心化的集群模式,消费者需要知道现在那些生产者(对于消费者而言,kafka就是生产者)是可用的.    如果没有zookeeper每次消费者在消费之前都去尝试连接生产者测试下是 ...

随机推荐

  1. iOS 面试总结

    APP崩溃 启动秒退 在新 iOS 上正常的应用,到了老版本 iOS 上秒退最常见原因是系统动态链接库或Framework无法找到.这种情况通常是由于 App 引用了一个新版操作系统里的动态库(或者某 ...

  2. 【转】MVC中code first方式开发,数据库的生成与更新(Ef6)

    一,在models文件夹中,建立相应的model文件         这里注意一点,这里建立的class名,就是数据库里表的名字.         在这里面,可以建立表之间的关系. 这里要说明一点的事 ...

  3. vue2.0 transition 手风琴

    <div class="food"> <button @click="show=!show">show</button> & ...

  4. VCG(VisualCodeGrepper)安装使用教程

    一.说明 代码审计工具看来还是比较难做,一是开源的代码审计工具少,二是原本的一些开源审计工具很多都不更新甚至不能使用了. VCG支持审计C++.Java.C#.PHP和VB,但其“审计”基本相当于函数 ...

  5. Linux磁盘性能分析(CentOS)

    1.top查看CPU是否长时间等待IO top %wa超过30%,说明IO压力很大 2.iostat查看磁盘工作时长占比 iostat -x #1表示1秒刷新一次 %util表示在过去的时间段中磁盘进 ...

  6. Lamda 表达式里的Join和GroupJoin的区别, 如何实现SQL的Left Join效果

    例如,可以将产品表与产品类别表相联接,得到产品名称和与其相对应的类别名称 db.Products .Join ( db.Categories, p => p.CategoryID, c => ...

  7. java的八大排序

    public class Sort2 { public static void main(String[] args) { Sort2 sort = new Sort2(); System.out.p ...

  8. node(2) EventEmitter类 事件队列 事件和error事件方法

    事件队列的核心:事件触发与事件监听器功能的封装. // 引入 events 模块 var events = require('events'); // 创建 eventEmitter 对象 var e ...

  9. linux 常用重启

    sudo reboot 为最常用重启 Linux centos关机与重启命令详解与实战 Linux centos重启命令: 1.reboot 普通重启 2.shutdown -r now 立刻重启(r ...

  10. Android开发 --代码布局

    Android开发 --代码布局 在线性布局LinearLayout里加入view比较简单,因为属性比较少,布局简单 示例,加入一个TextView LinearLayout layout = (Li ...