kafka深入理解

日志清除策略

对于传统的message queue而言,一般会删除已经被消费的消息,而Kafka集群会保留所有的消息,无论其被消费与否。当然,因为磁盘限制,不可能永久保留所有数据(实际上也没必要),因此Kafka提供两种策略去删除旧数据。一是基于时间,二是基于partition文件大小。可以通过配置$KAFKA_HOME/config/server.properties实现

Kafka中每一个分区partition都对应一个日志文件,而日志文件又可以分为多个日志分段文件,这样也便于日志的清理操作。
Kafka提供了两种日志清除策略:
(1)日志删除(Log Deletion)按照一定的保留策略来直接删除不符合条件的日志分段。
(2)日志压缩(Log Compaction)针对每个消息的key进行整合,对于有相同key的不同value值,只保留最后一个版本。

log.cleanup.policy来设置日志的清除策略,默认策略为delete,即采用日志删除的清除的策略。如果要采用日志压缩的清除策略,设置为compact,并且还需要将log.cleaner.enable(默认值为true)设定为true。

kafka 日志删除策略

在server.properity文件中设置

//topic的分区是以一堆segment文件存储的,这个控制每个segment的大小
log.segment.bytes=1073741824 
//启用删除策略,直接删除,删除后的消息不可恢复
log.cleanup.policy=delete 
//1、清理超过指定时间清理
log.retention.hours=16 
//2、超过指定大小后,删除旧的消息
log.retention.bytes=1073741824 
  • 基于时间的删除策略:删除修改时间在N天之前的日志。
log.retention.hours=168 //7d,再删除之前保存一个log segment 小时数,既,对所有topic默认数据保存时间。

每个segment的大小为1GB,每5分钟检查一次是否有segment已经查过了7d,如果有将其标记为deleted。
标记为deleted的segment默认会保留1天,清理线程会每隔15秒检查一次,是否有标记为deleted的segment的保留时间超过一天了,如果有将其从文件系统删除。

大家注意,kafka清理时是不管该segment中的消息是否被消费过,它清理的依据为是否超过了指定的保留时间,仅此而已。

  • 基于文件大小的删除策略:保留最后的Ngb的数据,即当日志数据超过指定的大小时,执行删除操作。
log.retention.bytes=1048576 // 1M

你可以同时指定log.retention.bytes和log.retention.hours来混合指定保留规则。log.retention.minutes和log.retention.bytes任意一个达到要求,都会执行删除。一旦日志的大小超过了log.retention.bytes就清除老的segment,一旦某个segment的保留时间超过了规定的值同样将其清除。

参考:

http://bigdata-star.com/archives/1479

https://www.cnblogs.com/JetpropelledSnake/p/11113617.html

https://blog.csdn.net/weixin_34216036/article/details/85838627

https://cloud.tencent.com/developer/article/1165361

partition(分区)

kafka通过分区策略,将不同的分区分配在一个集群中的broker上,一般会分散在不同的broker上,当只有一个broker时,所有的分区就只分配到该Broker上。

消息会通过负载均衡发布到不同的分区上,消费者会监测偏移量来获取哪个分区有新数据,从而从该分区上拉取消息数据。

分区数越多,在一定程度上会提升消息处理的吞吐量,因为kafka是基于文件进行读写,因此也需要打开更多的文件句柄,也会增加一定的性能开销。

如果分区过多,那么日志分段也会很多,写的时候由于是批量写,其实就会变成随机写了,随机 I/O 这个时候对性能影响很大。所以一般来说 Kafka 不能有太多的 Partition。

调整准则:

  • 一般来说,若是集群较小(小于6个brokers),则配置2 x broker数的partition数。在这里主要考虑的是之后的扩展。若是集群扩展了一倍(例如12个),则不用担心会有partition不足的现象发生
  • 一般来说,若是集群较大(大于12个),则配置1 x broker 数的partition数。因为这里不需要再考虑集群的扩展情况,与broker数相同的partition数已经足够应付常规场景。若有必要,则再手动调整
  • 考虑最高峰吞吐需要的并行consumer数,调整partition的数目。若是应用场景需要有20个(同一个consumer group中的)consumer并行消费,则据此设置为20个partition
  • 考虑producer所需的吞吐,调整partition数目(如果producer的吞吐非常高,或是在接下来两年内都比较高,则增加partition的数目)

replication-factor(副本)

此参数决定的是records复制的数目,建议至少 设置为2,一般是3,最高设置为4。更高的replication factor(假设数目为N)意味着:

系统更稳定(允许N-1个broker宕机)
更多的副本(如果acks=all,则会造成较高的延时)
系统磁盘的使用率会更高(一般若是RF为3,则相对于RF为2时,会占据更多50% 的磁盘空间)

调整准则:

  • 以3为起始(当然至少需要有3个brokers,同时也不建议一个Kafka 集群中节点数少于3个节点)
  • 如果replication 性能成为了瓶颈或是一个issue,则建议使用一个性能更好的broker,而不是降低RF的数目
  • 永远不要在生产环境中设置RF为1

Partition 数目与Replication Factor是在创建一个topic时非常重要的两个参数,这两个参数的取值会直接影响到系统的性能与稳定性。

尽量在第一次创建一个topic时就指定这两个参数,因为

如果Partition 数目在之后再次做调整,则会打乱key的顺序保证(同样的key会分布到不同的partition上)

如果Replication Factor在之后再次增加,则会给集群带来更大的压力,可能会导致性能下降

参考:

https://www.cnblogs.com/lgjlife/p/10569187.html

https://www.cnblogs.com/zackstang/p/11525919.html

日志存储

segment file由2大部分组成,分别为index file(后缀”.index”)和data file后缀(“.log”),此2个文件一一对应,成对出现,分别表示为segment索引文件、数据文件。

索引文件的命名规则就是根据offset。partion全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值。

数据文件就是用来存储消息的。

参考:

http://bigdata-star.com/archives/1479

https://segmentfault.com/a/1190000019147699

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值