Kafka-高效读写数据,Zookeeper在Kafka中的作用,Kafka事务

Kafka高效读写数据

1)顺序写磁盘

Kafka 的 producer 生产数据,要写入到 log 文件中,写的过程是一直追加到文件末端,为顺序写。

官网有数据表明,同样的磁盘,顺序写能到600M/s,而随机写只有100K/s。这与磁盘的机械机构有关,顺序写之所以快,是因为省去了大量磁头寻址的时间

2)应用Pagecache

Kafka数据持久化是直接持久化到Pagecache中,这样会产生以下几个好处:

  • I/O Scheduler 会将连续的小块写组装成大块的物理写从而提高性能

  • I/O Scheduler 会尝试将一些写操作重新按顺序排好,从而减少磁盘头的移动时间

  • 充分利用所有空闲内存(非 JVM 内存)。如果使用应用层 Cache(即 JVM 堆内存),会增加 GC 负担

  • 读操作可直接在 Page Cache 内进行。如果消费和生产速度相当,甚至不需要通过物理磁盘(直接通过 Page Cache)交换数据

  • 如果进程重启,JVM 内的 Cache 会失效,但 Page Cache 仍然可用,Page Cache 不在JVM中,不会增加GC的压力

3)零复制技术

在这里插入图片描述
将数据从磁盘读取之后写入网络:

正常情况:

  1. 先把将数据读取到内核的 pagecache 中
  2. 再把数据从 pagecache 拷贝到用户内存中进行操作
  3. 然后将数据写入内核的 socket 缓冲区
  4. 最后将数据从 socket 缓冲区写入网卡

零拷贝

  1. 将数据读取到内核的 pagecache 中
  2. 直接将数据从 pagecache 写入网卡

Zookeeper在Kafka中的作用

Kafka集群中有一个 broker 会被选举为 Controller (靠抢的方式,随机选取),负责监听集群 broker 的上下线,所有 topic 的分区副本的分配leader选举等工作。

若 Controller 宕机,则会从其余的 broker 选举出新的 Controller (靠抢的方式,随机选取),kafka 的任何选举工作都是靠抢的方式。

Controller 的管理工作都是依赖于 Zookeeper 的。以下为 partition 的leader选举过程:
在这里插入图片描述
流程:

  1. kafka 集群在启动的时候,会从 broker 中选一个作为 controller.
  2. broker 会到 zookeeper 中进行注册 </brokers/ids/.>
  3. controller 监听 </brokers/ids/.>,后续 broker 宕机,就能够马上知道
  4. broker 上保存的 partitition 也会在 zookeeper 上进行注册</brokers/topics/topic名称/partitions/分区号>
  5. 若 broker 宕机,如果该 broker上有 leader,则选举出新 leader。
  6. 获取 /brokers/topics/topic名称/partitions/分区号/state数据,更新ISR信息,leader信息

Kafka事务

Kafka从0.11版本开始引入了事务支持。事务可以保证Kafka在Exactly Once语义的基础上,生产和消费可以跨分区和会话,要么全部成功,要么全部失败。

1 Producer事务

为了实现跨分区跨会话的事务,需要引入一个全局唯一的 Transaction ID,并将 Producer 获得的 PID 和 Transaction ID 绑定。这样当 Producer 重启后就可以通过正在进行的 Transaction ID 获得原来的PID。

为了管理Transaction,Kafka引入了一个新的组件Transaction Coordinator。Producer就是通过和Transaction Coordinator交互获得Transaction ID对应的任务状态。Transaction Coordinator还负责将事务所有写入Kafka的一个内部Topic,这样即使整个服务重启,由于事务状态得到保存,进行中的事务状态可以得到恢复,从而继续进行。

2 Consumer事务(精准一次性消费)

上述事务机制主要是从Producer方面考虑,对于Consumer而言,事务的保证就会相对较弱,尤其时无法保证Commit的信息被精确消费。这是由于Consumer可以通过offset访问任意信息,而且不同的Segment File生命周期不同,同一事务的消息可能会出现重启后被删除的情况。

如果想完成Consumer端的精准一次性消费,那么需要kafka消费端将消费过程和提交offset过程做原子绑定。此时我们需要将kafka的offset保存到支持事务的自定义介质(比如mysql)。

猜你喜欢

转载自blog.csdn.net/qq_32727095/article/details/108032339