在分布式缓存方面,redis独占鳌头。但是对于消息队列mq来说,还处于百花齐放的时代。缓存系统基本上解决了一个访问问题,万事大吉,调用是同步的。对于消息队列,情况就不一样了。它具有多种使用场景和可变的可靠性级别,并且从生产端到消费者端的过程是异步的。消息系统的设计点很多。现在,很难有一个消息系统能够兼顾下面提到的设计要点。如果它说是,那就是矩阵吹了。所以很多时候,流行的Kafka、RabbitMQ、RocketMQ等都会同时用到。如果你在做相关的选择,下面的技术点就是权衡。那句话的名字是什么:鸡在早上醒来,回家的必经之路。Keypoints本文将从整体上抽象出这些mq的一些共同特征。包括:协议、类型、消费方式、堆叠容量、高可用、高可靠、高性能、可扩展性和生态性。如果想深挖某个mq,这里也有几篇关于kafka的文章。高可用高可用主要解决集群中单个节点在异常情况下的故障转移和HA。解决高可用问题的总体思路是复制机制。通过添加副本,数据的风险可以分散到多台机器上。这就要求当主分片出现问题时,能够找到其中一个副本作为新的主分片。这样的协调工具有很多,比如zk。还有mq自己实现这个过程。有的模式是比较浪费资源的,比如rocketmq,就是使用standbyslave机来保证高可用,有问题再回来top。高可靠消息系统的可靠性和性能是矛盾的。对于一般的mq,可以调整可靠性级别,但是性能会有相反的联动。从消息层面来看,大致的路线是:发送出去并忽略它->单节点确认->多节点确认->多节点确认同步闪现->所有节点同步闪现->交易消息等。单机高可靠集群的高可靠性会通过ack机制和多副本机制来保证。对于单个节点来说,断电或者主机异常都会是一个比较大的挑战。为了应对这种情况,需要有磁盘刷新机制或者其他持久化机制。同时还需要进行数据完整性校验,这也是为什么像Kafka这样的消息系统在数据量大的时候启动时间会很长的原因。生产端除了bufferloss,生产端还需要考虑一些传输错误,包括与集群通信的超时和重试处理。消费者使用消息确认机制来确保消息被正确消费。由于中间可能发生的许多异常,大多数消息系统至少保证一次语义。即保证消息至少被消费一次。言外之意就是消息会重复,消费者需要做到幂等,保证重复消费不会导致业务异常。消费者端也会出现一些错误。有的MQ可以在多次消费失败后自动进入死信队列,有的MQ需要自己设计topic进行规划。高性能作为数据传输通道,性能是一个非常重要的考虑因素。其中两个比较重要的指标,一个是消息的延迟,一个是消息的吞吐量。从生产者发送消息到消费者处理消息之间的过程不应该太长。对于使用pull方式消费的mq,需要加快轮询速度,使用零拷贝等技术来加快数据传输。对于消息吞吐量,是生产端、mq节点、消费端联合优化的结果。目前主要有以下几种方式:异步消息异步发送,发送端不需要同步等待,加快了处理速度。Batch分批发送,减少网络传输次数,方便数据压缩。一般在内存中缓存一个buffer,如果buffer满了,或者到达了时间窗口,则进行一次传输。这可以显着提高传输速度,但如果处理不当,可能容易丢失数据。SequentialIOxjjdog在很多文章中都提到过,磁盘的顺序操作比内存的随机操作要快很多。这也是Kafka等消息队列速度快的原因之一,但是要注意topic的数量(想想why)。除此之外,还有其他手段。比如优化操作系统参数,使用分片提高并行度等等。Message类型的消息是点对点的,一条消息只会被消费一次。Pub/Sub采用发布/订阅模型,一个消息可以被多个消费者消费。还有一种消息是通过广播方式广播的,即生产者发送一条消息,所有的消费者都会收到。除了正常发送的消息外,还有一些特殊用途的消息。顺序消息分为全局顺序和分区顺序,一般用于对顺序要求严格的业务。通过业务的设计,可以避免全局排序这种非常耗性能的操作。有的mqs还支持定时消息(个人觉得这种业务系统比较好)。事务消息消耗更多性能,因此请谨慎使用。还有一些mq提供了打标签和消息过滤的功能。例如,订单信息发送到一个主题,消费者只订阅相关产品的订单。在某些需要隔离的情况下非常有用。消费模式消费模式主要包括推模式和拉模式。拉模式最为实用和流行,因为消费处理速度可以由消费者自行调整。推送模式的实时性更好,但消费者端的能力不好评估,很容易被压垮。同时在处理pub/sub、失败重试等方面也有很多挑战。大家都知道java有一个JMS规范,但是和kafka类似,并没有实现这个规范。因此,一些协议,如amqp、openwire等,具有更明显的定制性。此传输协议与功能无关。比如有基于http协议的,也有基于redis协议的,甚至还有stomponwebsocket的。mqtt是物联网的应用协议,你会发现基于它的大型消息队列。积累能力现在的数据这么大,mq的积累能力是非常非常重要的。以redis这种内存型队列为例,分分钟爆。mq除了作为消息处理的通道,还可以作为备份存储。积累能力体现在海量存储上,比如存储在数据库中(矛盾转移),挂载非常大的磁盘等。但是不要太兴奋,启动和加载大型集群和重新平衡通常需要很长时间故障。积累能力的另一个体现是对历史新闻的清洗。一般有磁盘上线和过期清理两种策略,可以根据需要灵活设置。生态一个开源软件生态很重要,mq也是如此。主要体现在两个方面,一是支持的开发语言多样(需要提供生产者和消费者包),二是对周边软件的支持。如spring、spark、hadoop、flink等,降低集成成本。在这方面,除了mq系统比较新之外,他们都做得很好。消息系统的作用消息系统在当前分布式系统的设计中扮演着越来越重要的角色。其使用场景包括但不限于:调峰用于接受超过业务系统处理能力的请求,使业务平稳运行。这样可以节省很多成本。例如,某些限时抢购活动并非针对高峰容量而设计。Buffering作为缓冲层存在于服务层和慢速登陆层,作用类似于调峰,但主要用于服务内部的数据流转。比如群发短信。解耦项目启动,具体需求无法确定。消息队列可以作为接口层来解耦重要的业务流程。您只需要遵守数据的协议和程序,就可以获得可扩展性。冗余的消息数据可以被多个不相关的服务以一对多的方式使用。健壮性消息队列可以积累请求,所以即使消费端业务短时间挂掉,也不会影响主业务的正常进行。End根据消息的体积和用途,目前分布式MQ大致可以分为两类。一种用于业务系统中,以确保极高的可靠性。要求消息不能丢失,如订单、支付等,具有较高的SLA服务水平。这样的话,对mq的功能需求就更多了,包括消息的溯源。另一种用于大数据的系统通常具有非常大的吞吐量。在异常情况下,丢失几条消息并没有什么坏处。但是消息系统可能只关注mq本身。如何保证生产端、消费端和MQ本身的可用性,需要业务进行权衡。比如前段时间xjjdog开源的okmq用于解决特定场景的高可用问题。开源一个kafka增强:okmq-1.0.0
