Kafka

kafka的架构模型以及内部细节

topic:每条发布到kafka集群的消息都有一个类别,这个类别就叫做Topic

broker:服务端,储存消息

consumer:消费者,从broker读取消息

producer:生产者,向broker放入消息

partition:一个topic消息划分不同的区,分区是kafka消息队列组织的最小单位,一个区可看作一个队列

一个broker服务下,可以创建多个分区,broker数与分区数没有关系。

topic的Partition数量在创建topic的时候配置,Partition数量决定了每个Consumergroup中并发消费者的最大数量。

在kafka中,每一个分区的命名是从序号0开始。

partition的offset:每一个分区的数据是有序的,生产是什么样的顺序,那么消费的时候也是什么样的顺序。任何发布到partition的消息都会被直接追加到数据文件的尾部,当消息添加至分区时,会为其分配一个位移offset(从0开始递增),并保证分区上唯一。每条消息的offset是该消息在文件中的位置(偏移message数),offset是一个long类型数字,它唯一标识了一条消息,消费者通过(offset,partition,topic)跟踪记录。

partition的副本数(replication-factor)就是消息保存在broker(服务器)上的个数,一般情况下等于broker的个数。同一个副本因子不能放在同一个Broker中。创建主题时,副本因子应该小于等于可用的broker数。副本因子操作是以分区为单位的,每个分区都有各自的主副本和从副本。主副本叫做leader,从副本叫做 follower(在有多个副本的情况下,kafka会为同一个分区下的所有分区 设定角色关系:一个leader和N个 follower),处于同步状态的副本叫做in-sync-replicas(ISR,基本同步),isr表示当前可用的副本。follower通过拉的方式从leader同步数据。消费者和生产者都是从leader读写数据,不与follower交互。副本因子赋予了kafka读写数据的可靠性。如果某一个分区有三个副本因子,如果其中一个挂掉,就在剩下的两个选择一个leader。如果所有的副本都挂了,生产者生产数据到指定分区的话,将写入不成功。

一个topic由多个partition组成,一个partition里面有多个segment文件段,一个segment里面有两个文件,一个是.log(数据文件),另外一个是.index(索引文件)。其中.log包含了发送的数据存储;.index文件记录的是.log文件的数据索引值,指向对应数据文件中message的物理偏移地址,以便于加快数据的查询速度。

分区与消费组的关系

消费组是由一个或者多个消费者组成,同一个组中的消费者对于同一条消息只消费一次。

消费组里的消费者数目不能大于主题的分区数,最好和分区数成整数倍。

同一个消费组的不同消费者不能在同一时刻消费同一个分区下的数据,只能同时消费不同分区下的数据。因此,分区数越多,同一时间可以有越多的消费者来进行消费,消费数据的速度就会越快,消费的性能就越高。

kafka的log寻址机制

指定一个message,给出绝对offset,如何找到这个message?

第一步:使用二分法,也叫折半查找,找数据属于哪一个segment段

segment文件命名规则:partion全局的第一个segment从0开始,后续每个segment文件名为上一个全局 partion的最大offset(偏移message数)。数值最大为64位long大小,19位数字字符长度,没有数字就用0填充。

第二步:通过.index文件来查找数据

上图的左半部分是索引文件,里面存储的是一对一对的key-value,其中key是消息在数据文件(对应的log文件)中的编号,比如“1,3,6,8……”,分别表示在log文件中的第1条消息、第3条消息、第6条消息、第8条消息……,那么为什么在index文件中这些编号不是连续的呢?这是因为index文件中并没有为数据文件中的每条消息都建立索引,而是采用了稀疏存储的方式,每隔一定字节的数据建立一条索引。这样避免了索引文件占用过多的空间,从而可以将索引文件保留在内存中。但缺点是没有建立索引的Message也不能一次定位到其在数据文件的位置,从而需要做一次顺序扫描,需要消耗更多的时间,但是这次顺序扫描的范围就很小了。

以索引文件中元数据3,497为例。3是相对offset(偏移message数),代表在右边log数据文件中从上到下第3个消息;497是物理偏移地址,代表在右边log数据文件中的字节位置。在log数据文件中,497字节位置对应的是Message368772,368772是绝对offset(偏移message数),代表在全局partiton的第368772个消息。

根据以上原理,在索引文件中寻址的具体步骤如下:

   1.将指定的绝对offset减去索引文件的起始offset,得出指定的相对offset。

   2.通过二分法,也叫折半查找,在索引文件中找到小于或者等于指定相对offset的索引条目中最大的那个相对offset。

   3.查看最大的那个相对offset所对应数据文件的物理偏移地址。

   4.打开数据文件,从 在索引文件查到的物理偏移地址 开始顺序扫描直到找到指定绝对offset的那条Message。

kafka中数据不丢失机制

Kafka中数据不丢失,原因有三个方面:

  1.     生产者数据不丢失:使用ack机制
  2.     broker数据不丢失:使用副本策略
  3.     消费者数据不丢失:记录offset

如何保证producer发送的数据不会丢失?

使用ack机制可最大限度地保证生产者数据不丢失。生产者向服务器broker发送数据后,等待服务器返回确认码,即ack响应码,以确认服务器是否能接收数据。

ack的响应有三个状态值

0:生产者只负责发送数据,不关心数据是否丢失,响应的状态码为0(丢失的数据,需要再次发送)

1:partition的leader收到数据,响应的状态码为1

-1:所有的从节点都收到数据,响应的状态码为-1

生产者发送数据的方式有两种

同步:发送一批数据给服务端,等待服务端返回结果,得到返回结果后再继续发送数据。

1、生产者等待10s,如果broker没有给出ack响应,就认为失败。

2、生产者重试3次,如果还没有响应,就报错。

异步:发送一批数据给生产者端的缓冲区,不需要等服务端获取数据。

1、先将数据保存在生产者端的缓冲区中。缓冲区大小是2万条。

2、缓冲区中的数据满足数据阈值或者数量阈值其中的一个条件就可以向服务端发送数据。

3、发送一批数据的大小是500条。

4、如果broker迟迟不返回ack响应,而缓冲区又满了,开发者可以设置清空缓存或者阻塞生产。

如何解决broker宕机导致数据丢失的问题?

使用副本机制,服务端的主副本分区获得生产者生产的数据后,把数据拷贝到几个从副本分区中,有多少个从副本,就启动多少个线程来进行数据同步。kafka维护了一个isr的列表,记录了从副本同步主副本的数据的进度,用于决定哪些副本是可用的。消费者优先选择主副本当中的数据进行消费,因为主副本当中的数据是最完整的。如果主副本因为宕机等原因不能将数据提供给消费者,消费者就选择isr列表中同步进度最高的其他副本分区来获取数据。

如何避免消费者重复消费或者丢失数据?

消费者记录好offset就知道自己消费到哪个数据了。消费者每次去消费的时候,都要先获取offset值。如果offset值没有获取到,就不知道从哪里开始消费。

为了避免磁盘被占满,kafka会周期性的删除陈旧的消息,删除策略是什么?

Kafka把topic中一个parition大文件分成多个小文件段,通过多个小文件段,就容易定期清除或删除已经消费完文件,减少磁盘占用。

删除陈旧消息的策略有两个,一种是根据消息保留的时间(7天,单位是时),一种是根据topic存储的数据大小(1G,单位是字节),均可以在Server.properties配置文件中配置。

# 启用删除策略
log.cleanup.policy=delete

# 直接删除,删除后的消息不可恢复。可配置以下两个策略:

# 策略一:超过指定时间后,删除旧的消息
# kafka当中已经消费掉的数据,没有存在的必要,可以对其进行删除.
# 默认是168小时之后就将过期的segment删除掉。
log.retention.hours=168

# 策略二:超过指定大小后,删除旧的消息
log.retention.bytes=1073741824

kafka的数据是保存在磁盘中,为什么那么快

因为Kafka具有优越的读写机制

主要有两个原因:1.pagecache技术;2.顺序读写磁盘。顺序读写磁盘比操作内存更快。生产者攒足一批消息再提交到任意分区里,这是批量发送策略。这些批量发送的数据都先进行了缓存,存在pagecache里面。pagecache是操作系统级别的缓存。缓存完了开始把数据写到分区里面,分区里面的数据是有序的,便于顺序读写磁盘。如下图所示:

磁盘在转动,早期的普通PC机的磁盘转速大概在5400转每分钟,现在的大多数是7200转每分钟,更快的有12000转每分钟。磁盘转得越快,数据读写速度也越快。顺序读写是通过磁头指向磁盘,磁盘转动,磁头不动,不需要浪费时间像随机读写那样去寻址找磁道。Kafka利用分区的有序性,把数据全部放在连续的像蚊香一样的磁道,所以读写磁盘比操作内存还快。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值