Kafka简介和机制

定义

kafka是一个分布式的基于发布/订阅模式消息队列,主要应用于大数据实时处理

 

好处

解耦(各个功能通过消息队列通知完成功能,而不用必须等待上个功能模块的通知,类似于自己排队和黄牛帮排队

削峰(大量的处理响应需要经过消息队列,挨个挨个执行,不会使系统崩溃)

可恢复性(当处理消息的进程挂掉,在消息队列中的消息可以在系统恢复时被处理

 

 

 

消息队列的两种模式(点对点(1对1),发布/订阅模式(1对多))

发布/订阅模式分为两种(消费者从队列里拉取数据(一直询问队列是否有新数据),队列主动推送给消费者(推送和处理速度不同,可能造成资源浪费和消费者挂掉))

 

 

 

 

 

kafka基础架构

 

 

Topic A(设置主题,存储数据到相应主题里,分类了数据)

Partition 1(设置分区,将数据存储到不同的分区中,提高了消息队列服务器的负载能力)

Leader 和 Follower(设置分区的主从关系,Leader会将数据拷贝到Follower中,避免了集群中某个分区挂了,消息丢失的情况,消费者只能使用Leader中的数据)

cosumer group(消费者组,消费者组中的不同消费者只能消费不同分区的数据,提高了消费能力)

zookeeper(存储kafka集群信息)

消费者的消费信息位置(offset)(存储在kafka集群信息,磁盘,过期时间7天)

 

分区只能保证区内有序,不能保证全局有序。

 

 

 

存储原理

生产者产生的数据会放在log的尾部,为防止log文件过大,kafka采用分片和索引的方式,将每个分区分为多个segment

每个segment分为.index文件和.log文件,存储位置为topic名称+分区的区号

log存储生产者内容

index文件存取log文件内容的偏移量(位置)

 

 

 

 

 

分区策略

分区原因:

(1)方便在集群中扩展,每个Partition可以通过调整以适应它所在的机器,而一个topic又可以有多个Partition组成,因此整个集群就可以适应任意大小的数据了;
(2)可以提高并发,因为可以以Partition为单位读写了。

 

 

 

 

数据传输可靠性(ISR(和leader保持同步的follower集合)同步)

ISR:和leader保持同步的follower集合

 

 

kafka选择使用所有的follower全部同步后才向消费者发送数据,因为虽然延迟高(同步时间长),但是当为容忍n台服务器挂掉,重新选举leader时需要的副本(follower)较少(n+1,只要有一个就能成为leader正常运行)

半数同步则需要2n+1个副本

而采用全部同步有缺点

 

设想以下情景: leader收到数据,所有follower都开始同步数据,但有一个follower,因为某种故障,迟迟不能与leader进行同步,那leader就要一直等下去,直到它完成同步,才能发送ack。这个问题怎么解决呢?

Leader维护了一个动态的in-sync replica set (ISR),意为和leader保持同步的follower集合。当ISR中的follower完成数据的同步之后,leader就会给follower发送 ack。

如果follower长时间未向leader同步数据,则该follower将被踢出ISR,该时间阈值由

replica.lag.time.max.ms参数设定。Leader 发生故障之后,就会从ISR中选举新的leader

 

 

数据丢失(ack应答机制)

 

 

 

 

 

就是已经同步了,并且leader发送数据Hello,但没有返回ack,会重新选举ISR中的为leader,再发一次数据Hello,返回ack

 

 

 

 

Exactly Once 语义,kafka幂等性(解决单会话,单分区的数据不丢失不重复)

将服务器的 ACK 级别设置为-1,可以保证 Producer 到 Server 之间不会丢失数据,即 At LeastOnce 语义。相对的,将服务器 ACK 级别设置为 0,可以保证生产者每条消息只会被发送一次,即At Most Once 语义。At Least Once 可以保证数据不丢失,

但是不能保证数据不重复;相对的,At Least Once可以保证数据不重复,但是不能保证数据不丢失。但是,对于一些非常重要的信息,比如说交易数据,下游数据消费者要求数据既不重复也不丢失,即Exactly Once 语义。

在0.11 版本以前的 Kafka,对此是无能为力的,只能保证数据不丢失,再在下游消费者对数据做全局去重。对于多个下游应用的情况,每个都需要单独做全局去重,这就对性能造成了很大影响。

0.11 版本的 Kafka,引入了一项重大特性:幂等性。所谓的幂等性就是指Producer 不论向 Server 发送多少次重复数据,Server端都只会持久化一条。幂等性结合 At Least Once 语义,就构成了 Kafka 的 Exactly Once 语义。

即:At Least Once + 幂等性 = Exactly Once要启用幂等性,只需要将 Producer的参数中 enable.idompotence 设置为 true 即可。

Kafka的幂等性实现其实就是将原来下游需要做的去重放在了数据上游。开启幂等性的Producer(生产者) 在初始化的时候会被分配一个 PID,发往同一 Partition(分区) 的消息会附带 SequenceNumber(TCP序列号)

Broker端(kafka服务器)会对<PID,Partition, SeqNumber>做缓存,当具有相同主键的消息提交时,Broker 只会持久化一条。但是 PID 重启就会变化,同时不同的 Partition也具有不同主键,所以幂等性无法保证跨分区跨会话的 ExactlyOnce

 

producer事务         

使用全局唯一TransactionID(解决跨会话,跨分区的数据不丢失不重复)

生产要么全部成功,要么全部失败

 

 

 

数据一致性问题

消费数据一致性

 

 

 

 

kafka消费者消费方式

生产者推数据到kafka中,消费者根据自己的情况拉取数据,当kafka没有需要拉取的数据时,消费者会等待一段时间,之后再试着拉取。

 

消费者分区分配策略(kafka默认使用range)

  • RoundRobin:轮训(费者订阅同一主题)(合并所有的topic再分配) ==》topic不应该被全部消费者消费时,造成消费错误
  • Range:(消费者订阅不同的主题)以topic为单位单独分==》造成分配不均匀

 

轮询(RoundRobin):将所有分区中的数据取出,获取hash值,之后根据hash值排序,然后根据排序后的数据轮询给消费者

范围(Range):根据主题的分区范围,给消费者该范围的分区数据

 

 

 范围(Range):

 

 

 

 

offset的维护(offset:消费者消费到哪的位置)

由于 consumer 在消费过程中可能会出现断电宕机等故障,consumer 恢复后,需要从故障前的位置的继续消费,所以consumer 需要实时记录自己消费到了哪个offset,

以便故障恢复后继续消费。

Kafka0.9 版本之前,consumer默认将 offset保存在 Zookeeper中,从 0.9 版本开始,consumer 默认将 offset 保存在 Kafka 一个内置的 topic 中,该 topic 为__consumer_offsets

 

Kafka 是如何实现高吞吐率(读写快)的?(☆)

Kafka是分布式消息系统,需要处理海量的消息,Kafka的设计是把所有的消息都写入速度低容量大的硬盘,以此来换取更强的存储能力,但实际上,使用硬盘并没有带来过多的性能损失。kafka主要使用了以下几个方式实现了超高的吞吐率:

1)顺序读写(新加数据追加到log文件尾部,顺序写入磁盘(速度快),而不是随机写磁盘)

2)零拷贝(将数据直接从磁盘文件复制到网卡设备中,而不需要经由应用程序之手 。)

3)文件分段

4)批量发送

5)数据压缩

 

零拷贝

 

 

posted @ 2021-08-30 16:52  低调的。。。  阅读(253)  评论(0编辑  收藏  举报