【消息队列面试】15-17:高性能和高吞吐、pull和push、各种MQ的区别

十五、kafka高性能、高吞吐的原因

1、应用

日志收集(高频率、数据量大)

2、如何保证

(1)磁盘的顺序读写-pagecache关联

rabbitmq基于内存读写,而kafka基于磁盘读写,但却拥有高性能

传统磁盘读写都是随机读写,数据没有存到一起,浪费了寻址时间和旋转时间

如果是顺序读写:无需寻址 ,一次往后读,同时还有按page预读到内存的机制

容量大,消息堆积能力比内存更强大

(2)零拷贝技术-Linux支持(kafka高性能的原因)

传统方式:用户访问网卡

需要将用户态切换到内核态,由内核线程操作磁盘

使CPU存在上下文切换

此外,读取数据是将文件读到内核缓冲区,并拷贝到用户缓冲区,最后拷贝到内核态的socket缓冲区,将数据发到网卡,响应到客户端(用户态和内核态的两次切换)

零拷贝方式:

磁盘文件--内核缓冲区--网卡接口--消费者进程(不存在CPU的切换,直接在内核态完成消息的读取)

(原因:消息没有必要读到用户,消息只负责传递,无需读到用户缓冲区)【与java应用程序进行数据传递不同】

(3)分区分段+索引

partition可以保证topic的消息堆积,分区可以分散到多个broker,减轻了消息堆积

partition也是逻辑概念,实际存储:多个segment文件存储,针对segment又包含索引文件,提升读取效率,提高了读取数据的并行度(分段加锁)

(4)批量压缩

把多条消息使用gzip压缩,对压缩后的数据进行传输

(5)批量读写

堆积到一定的数量再进行发送,可以节省带宽,并提高效率

(6)直接操作页存

直接操作pagecache(页存),而不是jvm-不需要创建对象等操作

避免了对象创建及GC的耗时,读写速度会更快,进程重启时,数据也不会丢失【堆中的数据会丢失】

pagecache的刷盘时间由操作系统完成,基于内存,效率高

十二、kafka的pull和push各有什么优缺点

1、pull-主动拉取

由消费者根据处理能力,自己控制

按需所取,但不实时

2、push-推送

实时发送消息

缺点:可能会导致消费者压力大,可能会压垮

十三、Kafka、ActiveMQ、RabbitMQ、RocketMQ对比

 

1、ActiveMQ-半死不活

生产环境中较少,支持的数据量较小

遵循JMS消息中间件的规范,支持事务的ACID特性

支持XA协议(两段式提交,MySQL也支持)

官方维护少,社区不活跃

万级别吞吐量

2、RabbitMQ

基于AMQP协议

使用erlang开发,性能比较好,支持高并发

客户端支持多种语言

社区活跃、文档全面

但erlang语言对java不友好,不利于二次开发

学习成本高、架构复杂

万级别吞吐量,不适用于高并发

3、kafka-高性能、高并发

高可用

生产环境大量使用

ELK使用kafka收集日志

缺陷:单机容量有限,一台broker能放的partition数量有限,64以内最好

社区更新慢,部分代码使用java开发,二次开发有限制

吞吐量百万级别,Apache大数据标配

4、RocketMQ-基于阿里-火箭

性能和吞吐较高,高可用

基于java,利于二次开发

☆高可靠,消息零丢失(适用于互联网金融)

已经被捐赠给阿帕奇,社区活跃度一般

支持语言比较少-java、c++

吞吐量十万级别

posted @ 2022-01-15 21:20  哥们要飞  阅读(326)  评论(0编辑  收藏  举报