将消息丢进消息队列,不需要同步等待同步处理成功,所以请求和处理时间。比如对于一个处理过程,将其划分为同步和异步处理的几个模块,将同步处理完之后的结果丢尽消息队列之后就可以返回了,缩短了处理时间,提高了并发处理能力。
其实就是一个削峰填谷的作用。当日志的生产速度远大于消费的速度时,消息队列就会起到一个类似蓄水池的作用,当然如果蓄水池也满了那还是会出问题。
但是使用消息队列就多了一个链路,增大响应时延,并且需要将前后链路从同步处理改为异步,增大了系统的复杂性。
一个核心功能模块,随着业务的发展,与其交互的模块会越来越多,如果每接入一个模块,就修改代码或者配置,耦合性太高。这是就可以将核心功能对应的处理结果放入消息队列中,谁要对接该功能,只需要消费处理消息队列的结果消息即可,从而实现了解耦。
发布订阅功能、消息功能、日志传递的通道,连接流计算任务和数据
增加处理链路,带来响应时延
同步改异步,增加系统的复杂度
分布式的消息队列会带来消息丢失、数据不一致等新的问题
轻量、易于使用
支持AMQP协议,支持的客户端也很多
在生产者和消息队列之间有一个exchange,可以实现灵活的路由配置
对消息队列积压支持不好,如果出现大量积压,会造成性能的急剧下降
性能较差,每秒仅支持几万到十几万的消息量
开发语言使用的时Erlang,冷门并且学习门槛较高,碰到问题很难解决。
使用Java开发,源码易于看懂,中文文档很全,并且时延较低。每秒的吞吐量有几十万条
不仅是一个日志引擎系统,还是一个分布式流处理系统,甚至时一个分布式存储系统
使用批量和异步的思想,使得日志的吞吐量很高
与其他中间件的兼容性最好
因为采用批量和异步的方法,会造成日志的响应时延较高,是太适合实时的场景,但是Kafka是支持灵活配置的,可以设置成产生条新消息就立即发送。
采用全异步的线程模型和传输方式、在发送一条消息时,不是把它立即发送出去,而是写到缓存队列中,然后再由另外的线程负责发送
异步的网络模型
采用批量发送,不是一条消息就发送一次,而是等攒够多少条之后发送一次;并且服务端在收到一批消息之后,也是一批消息为单位来进行存储、同步和消费的,消费的客户端是先拉取一批消息,然后解析成一条条的消息,再交给用户代码处理,这样就大大降低了请求和处理的次数
自定义的传输协议、序列化、反序列化实现:使用存储密度高的协议,抛弃可读性,不传输字段名,同时固定字段顺序,采用变长存储,定义每个字段的长度和实际的存储内容。
高效的内存管理:避免重复创建临时对象,而是只使用一个对象;对于大对象,使用对象池,可以重复使用,避免频繁的创建和回收
使用顺序读写提高磁盘IO性能:机械硬盘的随机读和顺序读的性能差距有几十倍,固态硬盘也有几倍,Kafka采用顺序写文件大大的提高了IO性能
使用pagecache加速文件读写:内存的随机读写速度是磁盘的十万倍,使用文件在内存中的缓存,尽量避免直接与磁盘IO打交道。
使用zero-copy技术,减少数据的拷贝次数
使用数据压缩,节省存储空间,提高网络存储性能。压缩其实就是一个时间换空间的方案,解压缩都需要消耗CPU的时间,但是却减小了存储空间。因此对于IO密集的应用可以开启压缩,而计算密集的应用的慎重使用压缩。在Kafka中,数据是以一批为单位进行解压缩的,并且解压缩是分散在客户端进行的。
采用计算和存储分离的设计,这样即使在节点或者请求量很多时,也不会出现性能瓶颈
多出一个系统,设计复杂
原文:https://www.cnblogs.com/suntp/p/12830481.html