运维学习————kafka(2)

目录

一、工作流程

 1、分区的好处

2、分区是如何分配到broker上 

目的

规则

3、副本的好处

4、zk保存kafka数据的目录结构是什么样子的,在kafka集群中的作用 

二、生产者如何写入消息的 

 1、消息写入时,放入分区的规则

2、ack应答机制 

 3、ISR(In Sync Replicas)

三、消费者消费要点 

四、相关面试 

kafka 如何减少数据丢失

消费者故障,出现活锁问题如何解决? 

kafka 如何不消费重复数据? 


一、工作流程

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


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

 

由于生产者生产的消息会不断追加到log文件末尾,为防止log文件过大导致数据定位效率低下,Kafka采取了分片索引机制,将每个partition分为多个segment。每个segment对应两个文件——“.index”文件和“.log”文件。这些文件位于一个文件夹下,该文件夹的命名规则为:topic名称+分区序号。例如,first这个topic有三个分区,则其对应的文件夹为first-0,first-1,first-2。

 

00000000000000000000.index

00000000000000000000.log

00000000000000170410.index

00000000000000170410.log

00000000000000239430.index

00000000000000239430.log

 1、分区的好处

1,方便集群的伸缩

每个Partition可以通过调整以适应它所在的机器,而一个topic又可以有多个Partition组成,因此整个集群就可以适应任意大小的数据了

2,可以提高并发

可以以Partition为单位读写,提高集群的读写速度

2、分区是如何分配到broker上 

目的

1. 保证所有的分区以及副本可以均衡在分布上所有的broker上

2. 保证同一个分区及其副本尽量不要分布在同一个broker上

规则

让分区和broker进行排序                  partition  leader排序:  p0    p1    p2    p3

partition 副本:           p0r   p1r   p2r   p3r

broker排序:               br0   br1    br2
 

分区怎么分配到broker上:     p0随机一个broker    topic越多,每个topic都对应有一个p0 越平均的分配到不同的broker

leader            p0->br1    p1->br2        p2 ->br0    p3->br1(p0随机,以后的放入下一个)

副本随机:     p0r->br0   p1r->br1      p2r->br1    p3r->br2

3、副本的好处

提高kafka的系统的可靠性和稳定性,同一个partitation对应一个或者多个副本,创建topic时就可以设置(--replication-factor  2)。没有副本,一旦当前保存消息的服务器宕机,就会造成消息丢失,如果有replication,当保存消息的服务器宕机后,从新选举新的leader,继续进行消息读写,不会造成消息丢失。

4、zk保存kafka数据的目录结构是什么样子的,在kafka集群中的作用 

1,broker在zk中注册:集群启动时,每个broker都会在/brokers/ids/下注册(创临时节点),如果broker挂掉了,zk就会删除该节点。

2,topick会在zk中注册:创建topic时,每个topic都会在/brokers/topics/下注册,topic删除,节点失效。每个broker和topic的对应关系也是由zk进行维护。

3,consumer(消费者)在zk注册:当新的消费者都会zk进行注册,zk在/consumers/consumer-group/ 创建3个节点    ids    offsets(偏移量)  owners

ids:  记录当前消费者组所有的消费者id

offsets:消费者在消费topic每个partition时,消费到哪个位置(offset 偏移量)

owners:记录该消费者组消费的topic信息(订阅了哪些topic)

新版本无效

二、生产者如何写入消息的 

get  /brokers/topics/tpa/partitions/0/state

{"controller_epoch":7,"leader":2,"version":1,"leader_epoch":19,"isr":[2]}

ack=-1/all  

为保证producer发送的数据,能可靠的发送到指定的topictopic的每个partition收到producer发送的数据后,都需要向producer发送ackacknowledgement确认收到),如果producer收到ack,就会进行下一轮的发送,否则重新发送数据。

 1、消息写入时,放入分区的规则

1、指定分区,直接按照指定分区写入

2、没有指定分区,但是消息中含有key(一般消息是key value的方式),通过key的值进行hash运算,计算得到一个partition,写入到这个分区。(aaa hash运算后可能得到一个和aaa没有任何关系的一个数值123132,对分区的总数量取模,根据结果,得到分区)

3、如果没有指定分区,key都没有,使用轮询(第一次调用时随机生成一个整数(后面每次调用在这个整数上自增),将这个值与 topic 可用的 partition 总数取余得到 partition 值,也就是常说的 round-robin 算法),找出一个分区,并写入。

2、ack应答机制 

0  producer不等待broker同步完成的确认,继续发送下一条(批)信息

提供了最低的延迟。但是最弱的持久性,当服务器发生故障时,就很可能发生数据丢失。例如leader已经死亡,producer不知情,还会继续发送消息broker接收不到数据就会数据丢失
 

1  producer要等待leader成功收到数据并得到确认,才发送下一条message。此选项提供了较好的持久性较低的延迟性。Partition的Leader死亡,follwer尚未复制,数据就会丢失
 

-1/all  意味着producer得到leader和所有follwer确认,才发送下一条数据

 3、ISR(In Sync Replicas)

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

Leader维护了一个动态的in-sync replica set (ISR),意为和leader保持同步的follower集合。当ISR中的follower完成数据的同步之后,follower就会给leader发送ack。如果follower长时间未向leader同步数据,则该follower将被踢出ISR,该时间阈值由replica.log.time.max.ms参数设定。Leader发生故障之后,就会从ISR中选举新的leader。

三、消费者消费要点 

消息的消费模式有两种:推送模式(push) 和拉取模式(pull)

kafka采取的拉取模式(pull),由消费者自己记录消费状态(消费者自己记录自己的消费位置(offset偏移量)),每个消费者相互独立的消费每个一个分区的消息。每个消费者消费完了后,对消息本身不做任何处理,决定该消息是否能被删除,跟消费者没有任何关系,与配置的消息过期时间和消息总容量的大小配置参数有关(log.retention.hours=168  log.retention.bytes=1G)。

消费者是以消费者组( consumer group)的方式,由一个或者多个消费者组成一个组,共       同消费一个topic(主题),在同一时刻,只能由同一个组的一个消费者去消费同一个分区。
 

pull模式不足之处是,如果kafka没有数据,消费者可能会陷入循环中,一直返回空数据。针对这一点,Kafka的消费者在消费数据时会传入一个时长参数timeout,如果当前没有数据可供消费,consumer会等待一段时间之后再返回,这段时长即为timeout。

四、相关面试 

kafka 如何减少数据丢失

Producer端:

#在Producer端用来存放尚未发送出去的Message的缓冲区大小。缓冲区满了之后可以选择阻塞发送或抛出异常,由block.on.buffer.full的配置来决定。

block.on.buffer.full = true

acks = all

#无限重试,直到你意识到出现了问题

retries = MAX_VALUE

#限制客户端在单个连接上能够发送的未响应请求的个数。设置此值是1表示kafka broker在响应请求之前client不能再向同一个broker发送请求。

max.in.flight.requests.per.connection = 1

#而不是send(record)方法自定义回调逻辑处理消息发送失败

使用KafkaProducer.send(record, callback)

#设置此参数是为了避免消息乱序

callback逻辑中显式关闭producer:close(0)

#关闭unclean leader选举,即不允许非ISR中的副本被选举为leader,以避免数据丢失

unclean.leader.election.enable=false

replication.factor = 3

#消息至少要被写入到这么多副本才算成功,也是提升数据持久性的一个参数。与acks配合使用

min.insync.replicas = 2

replication.factor > min.insync.replicas

Consumer端:

consumer端丢失消息的情形比较简单:如果在消息处理完成前就提交了offset,那么就有可能造成数据的丢失。由于Kafka consumer默认是自动提交位移的,所以在后台提交位移前一定要保证消息被正常处理了,因此不建议采用很重的处理逻辑,如果处理耗时很长,则建议把逻辑放到另一个线程中去做。为了避免数据丢失,现给出两点建议:

enable.auto.commit=false

消息处理完成之后再提交位移

消费者故障,出现活锁问题如何解决? 

kafka 消费者正常情况下是订阅一个 topic 并且能够 poll 消息。该消费者会占用一个分区,同时需要定时向 zk 发送心跳监测,以证明自己活着。当消费者占用一个分区后,且能够正常发送心跳,但是不 poll 消息了,不再进行消息处理了,这种情况下就出现了活锁。

kafka 这边处理的时候会配置 max.poll.interval.ms 活跃监测机制。如果客户端调用 poll 的频率大于最大间隔,就会将当前客户端连接断开,让其它的消费者过来消费。

kafka 如何不消费重复数据? 

1,幂等操作,重复消费不会产生问题

2,对每个partitionID,产生一个uniqueID,.只有这个partition的数据被完全消费,才算成功,否则失败回滚。下次若重复执行,就skip

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值