十五、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++
吞吐量十万级别