内容简介:了解了Kafka的窗户和内核之后,我们深入Broker中,看看Topic和Broker之间的关系,它们之间到底是用什么联系起来的。Broker对Message的持久化是如何处理的。Kafka的Partition是分区的概念,在Kafka中,一个Topic可以有多个Partition,换句话说,就是一个Topic中的内容是被多个Partition分割的。对于Partition,我们需要注意以下几个要点:
了解了Kafka的窗户和内核之后,我们深入Broker中,看看Topic和Broker之间的关系,它们之间到底是用什么联系起来的。Broker对Message的持久化是如何处理的。
Partition
Kafka的Partition是分区的概念,在Kafka中,一个Topic可以有多个Partition,换句话说,就是一个Topic中的内容是被多个Partition分割的。对于Partition,我们需要注意以下几个要点:
- 一个Topic下的所有Partition是有顺序的,或者说在创建Topic和Partition时,Partition的顺序就已经是确定了的。
- 每条进入Partition中的Message都会获得一个自增的ID,这个ID称为Offset(消息的偏移量)。
- 通常在说Message的Offset时,只是针对该条Message所在的Partition而言。举个例子,Partition-0中Offset为3的Message和Partition-1中Offset为3的Message没有任何关系。
- 当说到Message的顺序时,通常有两种解读:
- 业务语义上的Message顺序,如下图所示,1至4条Message之间是有语义顺序的,可以理解为是消息生产者生产消息时的顺序。
- Partition中的Message顺序,如下图所示,Partition-1中的Message如果按照Offset的顺序,那么第一条和第二条Message其实是语义上的第一条和第三条Message。
- 当Message进入Partition后,它的Offset和内容就无法再修改了。
- Message默认是随机存储在一个Topic下的不同的Partition中的,如上图。除非显示的指定Partition。
- 存储在Partition中的Message是有时效性的,默认是保存一周,可以通过配置更改(后续章节会介绍)。
在Kafka中,一个Partition对应物理机器上的一个文件夹,文件夹命名会以Topic名称加序号表示。换句话说,Partition在Broker中以文件夹的形式存在。每个Partition文件夹中会有多个大小相等的日志段文件(Segment File),消息生产者生产的消息发送到Broker后就会以追加到日志文件末尾的方式持久化到Partition中。
Replication
我们再来看一个和Partition相关的概念,Replication。从字面意思就可以看出,这是Partition副本的意思。Replication Factor决定了将Partition复制几份,也就是将数据复制几份。Partition的副本也是会随机被分配到任意Broker中。下图展示了它们之间的关系:
从上图中可以看出,如果Broker 102挂掉了,是不会影响我们的Kafka集群的运转的,因为我们的数据并没有丢失,Broker 101和Broker 103中任何持久化着Topic-A的数据。这就是Replication的作用,它可以有效保证数据在Kafka系统中的完整性和有效性。
Leader for Partition
当Partition有多个副本时,又会引出一个概念,那就是Partition的Leader Broker。关于Partition的Leader有以下几个要点:
- 在任何时候,只有一个Broker会成为某个Partition的Leader。
- 只有作为Leader的Broker才会为Partition接收和处理数据。其他持有Partition副本的Broker只是从Leader Broker同步数据。
- 每个Partition只有一个Leader Broker,但可以有多个随从Broker,或者说是ISR(in-sync replica)。
上图所示,Broker 101是Topic-A Partition 0的Leader Broker。Broker 102是Topic-A Partition 1的Leader Broker。如果Broker 101挂掉了,那么Broker 102会自动被选举为新的Topic-A Partition 0的Leader Broker。当Broker 101恢复后,会重新将Leader交还给Broker 101。选举Leader Broker的工作由Zookeeper帮Kafka完成,这里暂做了解。
Partition Count and Replication Factor Convention
在通常情况下,设置Topic的Partition数量和Replication数量有一些惯例可以参照。
首先这两个参数是非常非常重要的,直接关系到Kafka集群的性能、高可用问题。在创建Topic之前,一定要先思考如何设置Partition数量和Replication数量。并且尽量不要在之后调整Partition数量和Replication数量。
前文中讲过,如果在Kafka运行时调整Topic的Partition数量,会直接影响Message根据Key的顺序问题。如果调整Replication数量,会给集群带来较大的性能压力,因为涉及到Zookeeper要重新选举Leader一系列操作。
所以在较小的Kafka集群中(小于6个Broker),一般每个Topic的Partition数量为Broker数量的两倍。在较大的Kafka集群中(大于12个Broker),一般每个Topic的Partition数量等于Broker的数量。介于这两者之间的可以根据具体业务和IaaS的情况,设置两倍于Broker或等于Broker数量。
Replication数量最少为2,通常为3,最大也就设置到4。前文中说过,Replication的数量关系到我们可以容忍有几个Broker挂掉(N -1个)。而且如果 acks=all
,Replication太多会影响效率,并且会增加磁盘空间。所以综上,一般将Replication Factor设置为3,比较合理。
Segment File
我们已经知道了Topic是由Partition构成的。再来说说构成Partition的Segment文件。
进入 kafka_2.12-2.0.0/data/kafka
这个目录后(这里的目录暂做了解,后续在Kafka搭建小节里会讲到),可以看到一些以 Topic name-index
这种格式命名的文件夹,这些就是Partition:
进入 first_topic-0
这个Partition后,可以看到有一些文件, *.log
就是Partition的Segment文件:
Partition的Segment文件涉及到两个参数:
log.segment.bytes log.segment.ms
上面两个参数说明了,Partition的Segment文件可以有多个,当一个Segment的大小达到 log.segment.bytes
参数设置的大小后,关闭(不允许写入)这个Segment文件,并自动开启下一个Segment文件。如果一个Segment文件在 log.segment.ms
参数设置的时间内没有写满,那么也将自动关闭,并开启新的Segment文件。所以始终只会有一个处于活跃状态的Segment文件可以被写入。
log.segment.bytes
设置的越小,Partition的Segment文件数就越多,对关闭的 *.log
文件压缩操作就越频繁。 log.segment.ms
的值也同样影响文件压缩的频率。所以这两个参数要根据业务实际情况,对吞吐量的需求去合理设置。
在上图中,还看到 *.index
和 *.timeindex
两个文件,这两个都是帮助Kafka查找Message的索引文件:
*.index *.timeindex
这三个文件的名称是一样的,整个名称的长度为20位数字,第一个Segment文件从0开始,后续每个Segment文件的名称为上一个 *.log
文件中最后一条Message Offset,其他位数用0填充,比如:
0000000000000000000.index 0000000000000000000.log 0000000000000037489.index 0000000000000037489.log 0000000000005467283.index 0000000000005467283.log
用一张图来概括Partition和Segment文件的关系:
Delete Cleanup Policy
Kafka的Message既然是存在磁盘上的,那么必然会有数据回收或者数据清理的机制,这里涉及到一个参数 log.cleanup.policy
如果将值设置为 delete
,那么Partition中的Message会基于规则在一段时间后被删除。这里的规则有两个,一个是基于时间的,一个是基于Partition大小的。
log.retention.hours
log.retention.hours
参数的值默认是168小时,既1周时间,也就是Partition中的未处于活跃状态的Segment文件只保留一周,一周后会被自动删除。
这个参数如果设置的比较大,那么意味着Topic的历史数据会保留较长时间,Consumer丢失数据的容错率会高一些。同时会占用更多磁盘空间。如果设置的比较小,意味着Topic的历史数据保留的时间较短,Consumer丢失数据的潜在风险较大,但是占用的磁盘空间较小。所以该值需要根据实际情况设置。
log.retention.bytes
log.retention.bytes
参数的值默认是-1,也就是指Partition的大小是无穷大的,既不考虑Partition的大小。如果将其设置为524288000,那么就表示当Partition大小超过500MB时,会删除未处于活跃状态的Segment文件。
通常情况下,使用默认配置就好,既不考虑Partition大小,历史数据保留一周。但也可以根据业务自行设置,灵活组合。但有一点需要注意的是,这两个规则只要达到一个,就会启动清理数据的任务。
Compaction Cleanup Policy
另外一个策略是压缩策略, __consumer_offset
这个Topic默认采用的就是这种策略,我们先看一张图:
上图表示的应该比较清楚了,压缩模式就是把相同Key的旧数据删了,每个Key只留下最近的数据。这种模式相对DELETE策略,至少每个Key都会有数据,但是历史数据会丢失。
当 log.cleanup.policy=compact
时,有以下相关的一些参数需要我们注意:
segment.ms segment.bytes min.compaction.lag.ms delete.retention.ms min.cleanable.dirty.ratio
Cleanup Frequency
不论是删除策略还是压缩策略,都是针对Partition的Segment文件进行的,根本还是磁盘IO操作,所以这种清理工作不应该过于频繁,否则会对整个Broker造成性能方面的影响。对Segment文件的大小也要把控在合理的范围内。太小,太多的Segment文件肯定会使清理工作更加频繁。
另外还可以对 log.cleaner.backoff.ms
参数进行设置来控制清理频率,这个参数控制检测是否需要清理的时间,默认是15秒检查一次。将其设大一点,也可以降低清理频率。
以上所述就是小编给大家介绍的《Kafka从上手到实践-庖丁解牛:Partition》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Kafka从上手到实践-实践真知:搭建Zookeeper集群
- Kafka从上手到实践-实践真知:搭建单机Kafka
- Kafka从上手到实践-实践真知:Kafka Java Consumer
- Kafka从上手到实践-实践真知:Kafka Java Producer
- Nacos上手实践(基于Spring Cloud)
- Kafka从上手到实践-初步认知:Zookeeper
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
图论算法理论、实现及应用
王桂平//王衍//任嘉辰 / 北京大学 / 2011-1 / 54.00元
《图论算法理论、实现及应用》系统地介绍了图论算法理论,并选取经典的ACM/ICPC竞赛题目为例题阐述图论算法思想,侧重于图论算法的程序实现及应用。《图论算法理论、实现及应用》第1章介绍图的基本概念和图的两种存储表示方法:邻接矩阵和邻接表,第2~9章分别讨论图的遍历与活动网络问题,树与图的生成树,最短路径问题,可行遍性问题,网络流问题,支配集、覆盖集、独立集与匹配,图的连通性问题,平面图及图的着色问......一起来看看 《图论算法理论、实现及应用》 这本书的介绍吧!