kafka

本文详细阐述了Kafka的消息生产和消费过程,包括producer推送到broker、消息持久化策略以及可能遇到的安全问题如重复提交和消息遗漏。还比较了Kafka与RocketMQ在不同场景下的优劣,强调Kafka在大数据量场景下的优势。
摘要由CSDN通过智能技术生成

主要概念

  • 生产者push消息到kafka,消费者pull拉取消息
  • kafka集群中的每个实例作为kafka的一个broker
  • kafka中topic为逻辑概念,topic可分为多个partition
  • partition为物理概念,表现为一台broker上面的一个文件夹,一个partition中的消息是分segment存储的
  • 每个segment包含一个log文件和一个index文件,log文件为真正的消息存储文件,index文件为稀松索引

生产及持久化

流程
  1. 生产者生成消息key
  2. 生产者根据消息key获取partition-leader所在的broker
  3. 生产者push消息到partition-leader,artition-leader持久化成功
  4. 其余partition在partition-leader拉取消息同步到本地,如果成功,通知到partition-leader
  5. 所有的partition均成功了,partition-leader回复生产者成功

对于上述步骤,partition-leader回复生产者成功的触发条件是可以配置的,有三种策略:只要leader持久化成功就返回、至少一个从partition成功就返回、全部partition成功才返回

潜在的安全问题
  1. 重复提交消息1

如果采取的成功触发条件为至少一个从partition成功就返回或者全部partition成功才返回
上述步骤中,假设步骤4进行到通知的partition-leader时候partition-leader所在的broker挂掉了,同时选取了已经持久化成功的从partition作为新的leader,就会出现重复消息,因为这时生产者会重新上报这条消息。

解决方式:kafka提供了配置,同一个生产者提交的重复key对应的消息会被忽略。

  1. 重复提交消息2
    问题1的解决方式看起来很不错,但是如果生产者本身挂掉了再重启,kafka会为它生成新的PID,这样就有概率出现重复数据。

解决方式:kafka提供了事务功能,我们可以为生产者指定一个事务ID,生产者重启后去根据事务ID获取自身的PID。

  1. 消息遗漏
    如果选择策略为只要leader持久化成功就返回同时从partition未同步partition-leader就挂掉了,这条消息就遗漏了。

解决方式:没有太好的办法,尽量不选择这个策略吧。

消费

  • 每个消费者都在一个消费者组中,同一个消费者组中的消费者无法消费同一个partition,所以kafka支持广播和独播。
  • 每个partition仅可供一个消费者消费,这就意味着partition的数量要至少比消费者多几倍才能尽可能均匀分布。
  • 消费者每次pull一批数据。
  • 消费者消费数据后可选择是否自动提交偏移量。如果选择是,那么kafka会定时提交偏移量,如果存在未到提交时间就挂了重启,会带来重复消费的问题;如果选择否,那么手动提交,如果拿到数据就提交偏移量存在消息未消费的问题,如果执行完成再提交存在重复消费的问题。

这个问题只能通过幂等性解决。

  • 消费者如果发生变更,或者partition变更,或者消费者对应的topic变更,都会触发rebalance,过程中消费是停止的。
  • 如果生产者开启了事务,消费者可以配置是否读取具备事务的生产者push但没有commit的数据。

为什么kafka快

  • 写操作都是磁盘顺序写
    当然,这个概念并不是说磁头不用动,每次写直接写磁盘就行了,实际上第一次寻址是避免不了的,只不过后续的写操作都是顺序io,不能神话这个特性,其实本身就是不需要随机写操作的,毕竟只是消息队列不用改消息。
  • 读操作都是索引加顺序读
    这个是正经的顺序读,首先读取一个序号为n的消息会现在稀松索引二分查找到小于等于n的索引,然后直接用文件的初始地址加上索引增量作为寻找起始点,后续只要顺序读,知道找到n对应的消息为止即可,这里可以用上磁盘的页缓存,是非常快的。
  • 零拷贝
    零拷贝是不可能的,严格来讲应该说是用户态无需拷贝,直接内核态直接拷贝至socket,java中的api为FileChannal.transferTo()。

为什么选择kafka

目前主流的队列是kafka和rocketmq。

kafkarocketmq
横向拓展支持支持
持久化性能非常快一般
广播支持支持
单播支持支持
分区支持支持较少分区支持大量分区
可靠性一般优秀
消费失败重试不支持支持
消息有序单partition全局
消息查询不支持支持
消息者数量小于等于partition数量无限制

可以看到kafka除了大数据量的场景其它方面都是被rocket爆金币的,所以一般是用在数据真的非常大,比如日志这种场景下。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值