大数据6_04_Kafka架构原理

4 Kafka架构原理

4.1 Kafka工作流程及文件存储机制

image-20201102232857042

Kafka中消息是以topic进行分类的,生产者生产消息,消费者消费消息,都是面向topic的。

  • topic是逻辑上的概念,partition是物理上的概念。每个partition对应一个log文件,log文件存放的是producer生产的数据。producer生产的数据会不断的追加到log文件末端,而且每一条数据都有自己的偏移量offset。
  • 消费者组中的消费者,都会实时记录自己消费到哪个offset,以便出错恢复时,从上次位置继续消费。

因为log文件一直被追加,为了防止log存放数据的文件太大,查找效率太低。

Kafka采用①分片:log文件每1G就分一个片

​ ②索引机制:index文件

00000000000000.log存放大量的数据,00000000000000.index存放大量的索引信息。

image-20201102232427731

4.2 Kafka生产者

①分区策略

Kafka利用topic进行分类,然后每一个topic又进行分区操作。

分区的原则:将producer发送的数据封装成一个ProducerRecord对象(分3种情况)

image-20201102234117929

(1)指明partition,直接将指明的值作为partition值。

(2)没有指明partition值,但有key,将key的hash值与topic的partition数进行取余得到partition的值。

(3)既没有partition的值有没有key,kafka采用Sticky Partition(黏性分区器),会随机选择一个分区,并尽可能一直使用该分区,待该分区的batch已满或者已完成,kafka再随机一个分区进行使用。

②数据可靠性保证

生产者发送数据到topic partition的数据可靠性保证:

ACK应答策略

producer产生的消息发送给每个topic的partition(其实只发给了leader),每个partition收到消息后会发送一个ack(acknowledgement确认收到)

  • 如果producer收到了ack,就进行下一轮发送(!!!kafka是异步发送,不用收到ack就可以直接发送)
  • 如果producer没有收到ack,就重新发送

image-20201102235957888

ack应答级别

默认ack=1

0 : 最低的延迟,leader接收到还没写入磁盘就返回ack;leader故障时可能丢数据
1 : leader写完后返回ack,不等待follower写完;follower同步成功之前leader故障肯能会丢数据
-1 : leader和ISO内的所有的follower写完后,才返回ack;broker返回给producer时,leader故障,可能会数据重复
ISR同步副本策略

Kafka采用了ISR同步副本的策略进行同步副本。

Leader维护了一个动态的ISR(in-sync replica set),只要follower和leader的通信时间够快,就能进入到ISR集合中。时间阈值由replica.lag.time.max.ms参数设定。只同步ISR内所有的follower

谁可以进入到ISR这个集合?之前的版本中:

  • 通信时间够快(follower和leader交互快)默认10s
  • 消息条数,follower和leader同步的数据差距小的。(差距在10条内的进来,大于10条剔除)

新版本0.9取消了消息的条数,为什么去除呢?

​ 如果一次batch发送了11条给leader,此时全部的follower全部超过10条,全部剔除。同步很快,很快又小于10条,又全部拉回了ISR集合,这个发送频繁后,不仅消耗资源还增大ZK压力。

leader和follower故障处理

image-20201103002936533

LEO:指的是每个副本最大的offset

HW:指的是消费者能见到的最大的offset,ISR队列中最小的LEO。

(1)follower故障

follower发生故障后会被临时踢出ISR,待该follower恢复后,follower会读取本地磁盘记录的上次的HW,并将log文件高于HW的部分截取掉,从HW开始向leader进行同步。等该follower的LEO大于等于该Partition的HW,即follower追上leader之后,就可以重新加入ISR了。

(2)leader故障

leader发生故障之后,会从ISR中选出一个新的leader,之后,为保证多个副本之间的数据一致性,其余的follower会先将各自的log文件高于HW的部分截掉,然后从新的leader同步数据。

HW

消费者最大可见LEO=HW,作用(1)保证了消费者消费数据的一致性。

参差不齐的LEO,选出的leader会通知其他的follower,比leader高就截去,低就同步。作用(2)保证了数据存储的一致性。

只能保证数据的一致性,但是不能保证是否有数据丢失或重复(ack应答级别的事)

③Exactly One语义
  • At Least Once语义:ACK级别设置为-1

  • At Most Once语义:ACK级别设置为0

  • Exactly Once:At Least Once + 幂等性

at least once的ack为-1,leader和ISR内的所有follower都同步完,再发送ack,但是broker发送ack给producer的时候,如果leader出错误了,producer会重发。这个时候回出现重复数据。

at most once的ack为0,不管leader和follower是否同步完,就返回ack,这个时候leader挂掉,会丢失数据。

在at least once的基础上引入幂等性,在producer发送数据时,就算重发了数据,也会只持久化一条相同数据。

开启幂等性是在Producer初始化的时候分配一个PID,发往Partition的消息会附带一个Sequence Number。而在Broker端会对<PID, Partition, SeqNumber>做缓存,当具有相同主键的消息提交时,Broker只会持久化一条。

但是PID重启就会变化,同时不同的Partition也具有不同的主键,所以幂等性不能跨分区、不能跨会话。

# 开启幂等性
enable.idempotence=true

4.3 Kafka消费者

kafka消费者采用pull拉取的方式从broder读取数据。

push(推模式)缺点:很难适应消费速率不同的消费者,因为消息发送速率是由broker决定的。

pull模式缺点:如果kafka没有数据,消费者可能会陷入循环中,一直返回空数据。

①分区分配策略

有两种:RoundRobin和Range两种策略。

RoundRobin策略

根据组去划分。将某一个Topic的不同分区,封装成多个对象,通过比较对象的hash值排序,轮询的方式,分给不同的消费者。

image-20201103205206053

Range策略(系统默认)

根据主题划分。将某一个Topic的不同分区,根据分区数/消费者数,将余数给第一个消费者,模数给其他的消费者。

image-20201103205251602

消费者组订阅不同的Topic呢?

  • RoundRobin:如果一个消费者组内的不同消费者订阅了不同的Topic,还按照轮询的方式分配给不同的消费者,会出现A订阅了B的Topic,这样就乱了!!!
    • 所以如果RoundRobin策略下的消费者组内的不同消费者向订阅多个Tiopic,就必须组内的所有消费者订阅相同的多个Topic!!!
  • Range:Range策略下,就能够解决上面的订阅乱了的现象!

image-20201103112250124

② offset的维护

因为消费者在消费的过程中,有可能出现断电宕机等故障,consumer恢复后,应该从故障前的位置继续消费,所以consumer需要实时记录自己消费到哪个offset。

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

  • 本地中:按照GTP(groupid,topic,partition)就能确定唯一一个offset

思想: __consumer_offsets 为kafka中的topic, 那就可以通过消费者进行消费

  • 那么当前这个消费者组消费的信息在哪个分区保存着呢?

    系统50个分区根据GTP的hash值取选择存到这50个分区中的某一个中。

步骤1:修改consumer.properties

可以让普通的消费者消费系统的topic,不改为false的话,系统的topic无法消费。

# 不排除内部的topic
exclude.internal.topics=false

步骤2:创建一个topic

[atguigu@hadoop102 config]$ kafka-topics.sh --zookeeper hadoop102:2181 --create --topic WEI --partitions 2 --replication-factor 2

步骤3:启动生产者和消费者,分别向WEI这个topic生产数据和消费数据

[atguigu@hadoop102 ~]$ kafka-console-producer.sh --broker-list hadoop102:9092 --topic WEI
[atguigu@hadoop102 ~]$ kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --topic WEI --from-beginning

步骤4:消费系统的topic(offset)

[atguigu@hadoop102 kafka]$ kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --topic __consumer_offsets --formatter "kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter" --consumer.config config/consumer.properties --from-beginning

步骤5:收到的数据

[test-consumer-group,atguigu,1]::OffsetAndMetadata(offset=2, leaderEpoch=Optional[0],
 metadata=, commitTimestamp=1591935656078, expireTimestamp=None)
[test-consumer-group,atguigu,0]::OffsetAndMetadata(offset=1, leaderEpoch=Optional[0], metadata=, commitTimestamp=1591935656078, expireTimestamp=None)
③消费者组案例

测试同一个消费者组中的消费者,同一时刻只能有一个消费者消费

步骤1:在hadoop102,hadoop103上修改/opt/module/kafka/config/consumer.properties配置文件中的group.id属性为任意组名。

[atguigu@hadoop102 config]$ vim consumer.properties
group.id=mygroup

步骤2:在hadoop104上启动生产者

[atguigu@hadoop104 kafka]$ bin/kafka-console-producer.sh --broker-list hadoop102:9092 --topic first

步骤3:在hadoop102、hadoop103上分别启动消费者

因为配置了consumer.properties内的groupid,所以需要指定当前的消费者是哪个组的。如果不指定,会随机生成一个id,也就是自己是一个组。

[atguigu@hadoop102 kafka]$ bin/kafka-console-consumer.sh bootstrap-server hadoop102:9092 --topic first --consumer.config config/consumer.properties
[atguigu@hadoop103 kafka]$ bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --topic first --consumer.config config/consumer.properties

步骤4:查看hadoop102和hadoop103的消费者的消费情况。

4.4 Kafka高效读写数据

①顺序写磁盘

②应用Pagecache

③零复制技术

直接由操作系统操作拷贝文件。

**④分布式(分区)**并发读写

4.5 Zookeeper在Kafka中的作用

①元数据存储

zookeeper在kafka中的第一个作用就是,元数据的存储。

  • Kafka的brokers信息,包含了集群id、topic等信息。
  • cluster集群元数据信息。
  • config配置文件信息。
  • controller集群的老大,一般是broker0。
  • 0.9版本的consumer的offset等信息也保存在zookeeper。如:/consumers/ [消费者组A,…]现在没有

image-20201104125335283

②Controller管理

zookeeper的第二个作用就是,为controller管理broker,所有分区副本的分配和leader选举提供支持。

  • Controller的选举机制是竞争资源,哪个broker抢到资源谁就是Controller。Controller负责管理集群broker的上下线,分区副本分配、leader的选举。
  • leader是怎样选举的呢?

第一次选leader是随机的,之后如果leader挂掉了,那么此后是轮询的方式,选择下一个作为leader。

image-20201104131521820

image-20201104131626487

image-20201104130831722

4.6 Kafka事务

0.11版本引入事务。

  • kafka的幂等性生产和消费不能够跨分区和会话;引入kafka事务后在Exactly Once语义的基础上,生产和消费可以跨分区和会话,要么全部成功要么全部失败。
①Producer事务

Producer事务保证了精准一次性写入

  • 因为幂等性只能在当前会话和当前分区有效,所以需要一个全局唯一的Transaction ID,并将Producer获得的PID和Transaction ID绑定。这样当Producer重启后就可以通过正在进行的Transaction ID找到原来的PID。

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

②Consumer事务

Consumer事务解决的是精准一次性消费的问题。

消费者消费了消息,但是没有将offset更新,这个时候消费者挂掉了,再次消费的时候就会重复消费。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

最佳第六六六人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值