架构介绍



通过生产者(Producer)向kafka集群(Kafka Cluster)发送数据,通过消费者(Consumer)向kafka集群(Kafka Cluster)拉取数据并消费。消费者组(Consumer Group)由干相同事情的一组消费者组成,消费同一个Topic的不同分区的数据,但是同一个分区只能由消费者组中的一个消费者消费。一个Topic分区(partition)可以有多个副本,副本只用来做容灾备份,当“备胎”,在leader挂了之后由副本(Follwer)内部竞争并选举一个Leader

kafka的读写高效以及Partition相关

每个partition都是⼀个有序并且不可变的消息记录集合。因为有序,磁盘的顺序读写非常快。当新的数据写⼊时,就被追加到partition的末尾。在每个partition中,每条消息都会被分配⼀个顺序的唯⼀标识,这个标识被称为offset,即偏移量。注意,Kafka只保证在同⼀个partition内部消息是有序的,在不同partition之间,并不能保证消息有序。

Leafer选举机制

Kafka提供了一个in -sync replicas(ISR)来确保Kafka的Leader选举所选出的Leader数据更加全面,ISR是一个保存分区node的集合,如果一个node宕机了或数据“落后太多”,leader会将该node节点从ISR中移除,只有ISR中的follower节点才有可能成为Leader,让Leader宕机后,符合条件的follower会竞争的在zk中创建一个文件目录,并且只有一个follower会创建成功,并且成为leader节点

kafka集群的数据推、拉选择

为什么不是kafka向消费者推数据,而是消费者向kafka拉数据?
因为消费者的消费能力不一样:

  • 消费者拉取数据的速率可以根据自身消费数据的能力而相应改变
  • kafka处理数据的效率非常高,采用推数据那么因为kafka无法得知消费者的消费能力,在很短的时间内进行大量的数据推送,导致消费者处理不了全部数据

ACK应答机制

producer在向kafka中写入数据的时候,可以设置参数来确定kafka是否收到数据,这个参数的值可以是0,1,all

  • 0代表producer往集群发送数据不需要等到集群的返回,不确保消息发送成功。安全性最低但是效 率最高。
  • 1代表producer往集群发送数据只要leader应答就可以发送下一条,只确保leader发送成功。
  • all代表producer往集群发送数据需要所有的follower都完成从leader的同步才会发送下一条,确保 leader发送成功和所有的副本都完成备份。安全性最⾼高,但是效率最低。

kafka的消息确认机制

对于Leader新接收到的消息(msg),不会立刻给client消费,leader会等待该消息被所有ISR中的副本(replica)同步后,更新HighWaterMark = max(replica.offset),此时该消息才能被client消费,这个机制保证了即使leader挂了,数据依然可以从新选举的leader中读取。

kafka的零拷贝机制

网络数据持久化到磁盘

传统IO流程会经过四次拷贝:

  • 将磁盘文件,读取到操作洗头膏内核缓冲区
  • 将内核缓冲区的数据,复制到应用程序的buffer中
  • 将应用程序buffer中的数据,复制到socket网络发送缓冲区中(属于内核缓冲区)
  • 将socket buffer的数据,复制到网卡,由网卡进行网络传输。

读取磁盘文件不做其他处理,直接由网络发送出去的时候,显然不需要第二和第三次数据的copy。因此,kafka引入了零拷贝机制:数据直接在内核完成输入输出,不需要拷贝到用户空间再写出去,kafka数据写入磁盘前,数据先写道进程的内存空间中。对于kafka来说,kafka的数据不是实时的写入磁盘,他充分利用了操作系统分页存储来利用内存提高I/O效率。

对于kafka来说,Producer生产的数据存到broker,这个过程读取到socket buffer的网络数据,其实可以直接在OS内核缓冲区,完成落盘。并没有必要将socket buffer的网络数据,读取到应用进程缓冲区;在这里应用进程缓冲区其实就是broker,broker收到生产者的数据,就是为了持久化。

总的来说Kafka快的原因:
1、partition顺序读写,充分利用磁盘特性,这是基础;
2、Producer生产的数据持久化到broker,采用mmap文件映射,实现顺序的快速写入;
3、Customer从broker读取数据,采用sendfile,将磁盘文件读到OS内核缓冲区后,直接转到socket buffer进行网络发送。