为什么使用消息队列,具体使用场景
解耦、异步、削峰
Kafka rocketMq ActiveMq RabbitMq技术选型
ActiveMq:吞吐万级,小概率丢消息,官方维护慢
RabbitMq:吞吐万级,erlang开发,不方便做二次开发维护
Kafka:吞吐10万级,适合大数据开发、日志采集 分布式。多broker,每个broker一个节点,topic内容保存在多个partition存在于多个broker。leader、follower,数据写入leader,follower主动从leader pull数据。通过配置可以做到0丢失消息
ack 0|1|all
0:生产者发送即成功
1:leader写入成功才算成功
all:所有节点写入成功才算成功
RocketMq:吞吐10万级,功能丰富,支持多种消息方式:顺序消息、延迟消息、事务消息
Kafka为什么快
1、消息只做追加操作 充分利用了磁盘的顺序写
2、分片命名 采用包含的第一消息的offset,消费数据时可以快速定位到分片
3、分片内索引 分片内快速定位,对单个分片建立了索引文件,通过索引文件可以快速定位指定消息在分片上的位置
4、消息格式使用二进制编码,编码在生产者、broker、消费者之间保持一致,不用额外的编解码
5、零copy,消息不用从内核空间copy到用户空间
6、可以做批量发送 批量消费
零拷贝
正常拷贝
mmap
应用程序调用了 mmap() 之后,数据会先通过 DMA 拷贝到操作系统内核的缓冲区中去。接着,应用程序跟操作系统共享这个缓冲区,这样,操作系统内核和应用程序存储空间就不需要再进行任何的数据拷贝操作。
sendfile
利用 DMA 引擎将文件中的数据拷贝到操作系统内核缓冲区中,然后数据被拷贝到与 socket 相关的内核缓冲区中去。接下来,DMA 引擎将数据从内核 socket 缓冲区中拷贝到协议引擎中去。
消息可靠性保证(高可用)
RocketMQ
生产者发送失败
1、channel事务消息,同步发送,影响性能
2、Confirm模式,二次ACK确认,异步非阻塞,不太影响性能
MQ自己丢失数据
1、同步刷盘
2、异步刷盘
消费者消费失败
mq重发
Kafka
生产者发送失败
1、ack=all肯定不会丢
MQ自己丢失数据
1、replication.factor>1 至少2个副本
2、min.insync.replicas 至少感知有一个follower
3、ack=all 写入所有replica 才算成功
4、retries=MAX 写入失败无限重试
消费者消费失败
取消自动offset,手动确认,接口幂等
消息顺序性
分区顺序性:同一个key(如订单id)下单、支付、取消保证顺序性
思路:相同key保存在同一个queue(如kafka同一个partion,内存队列)