作者:neoremind
出处:http://neoremind.com/2018/03/...
音讯队列作为服务/利用之间的通信中间件,能够起到业务耦合、播送音讯、保障最终一致性以及错峰流控(克服短板瓶颈)等作用。本文不打算具体深刻解说音讯队列,而是体系化的梳理音讯队列可能波及的技术点,起到提纲挈领的作用,结构一个宏观的概念,应用思维导图梳理。
再介绍之前,先简短比拟下RPC和音讯队列。RPC大多属于申请-应答模式,也包含越来越多响应式范式,对于须要点对点交互、强事务保障和提早敏感的服务/利用之间的通信,RPC是优于音讯队列的。那么音讯队列(下文也简称MQ,即Message Queueu)能够看做是一种异步RPC,把一次RPC变为两次,进行内容转存,再在适合的机会投递进来。音讯队列中间件往往是一个分布式系统,外部组件间的通信依然会用到RPC。
目前开源界用的比拟多的选型包含,ActiveMQ、RabbitMQ、Kafka、阿里巴巴的Notify、MetaQ、RocketMQ。下文的技术点梳理也是学习借鉴了这些开源组件,而后萃取出一些通用技术点。
对于音讯队列的体系化认知,见下方的思维导图。
1. 整体架构
个别分为producer,broker,consumer三者。
2. RPC通信
具体参考《体系化意识RPC》(http://www.infoq.com/cn/artic...)。
3. 高性能保障
次要思考MQ的提早和吞吐。
高性能投递方面,分为producer和broker思考。producer能够同步变异步、单条变批量保障发送端高性能,批量发送的触发条件能够分为buffer满或者工夫窗口到了。broker能够进行多topic划分,再多分区/queue来进行分治(Divide and Conquer)策略,加大并行度,扩散投递压力。另外broker对于须要长久化的音讯,能够应用程序IO,page cache,异步刷盘等技术进步性能,然而异步刷盘在掉电的状况下,可能会失落数据,能够联合上面的高可用计划,在数据严格不丢和高性能吞吐之间做折中。
高性能生产,即consumer和broker通信,进行推、拉音讯。应用consumer group程度扩大生产能力,须要依照业务场景应用分区有序或者无序生产。零拷贝技术节俭broker端用户态到内核态的数据拷贝,间接从page cache发送到网络,从而最大化发送性能。consumer批量pull,broker批量push。broker端还能够做音讯过滤,可通过tag或者插件实现。
4. 高可用保障
次要针对broker而言。
集群高可用,producer通过broker投递音讯,所以必然有且仅有一个broker主负责“写”,选主策略分为主动选主和非被动抉择,主动选主应用散布一致性组件实现,例如Kafka应用zookeeper,非主动选主,例如RocketMQ依赖多个无状态的name server。
数据高可用,针对broker长久化积压音讯场景。可借助分布式存储实现,然而往往性能上是个短板,所以大多数主流产品都进行本地IO程序写,进行主从备份,多正本拷贝保障可用性,例如RocketMQ分为同步双写和异步复制,前者像HDFS一样,写完多个正本再返回producer胜利,有肯定性能损失,但不大,后者最大化性能,然而当主挂的时候,数据有失落危险。
同样,MQ集群也须要思考跨机房高可用(非“异地多活”),broker的写高可用,要思考最小化MTTR,同时不阻塞consumer生产。
5. 扩展性保障
采纳分治(Divide and Conquer)策略,加大投递和生产的并行度,多个topic、多个分区/queue、多个正本、多个slave或者镜像。
6. 协定
producer、consumer和broker通信的协定,包含AMQP、STOMP、MQTT、HTTP、OpenWire(ActiveMQ)、XMPP、自定义等等。
AMQP是比拟全面和简单的一个协定,包含协定自身以及模型(broker、exchange、routing key等概念),目前RabbitMQ是AMQP音讯队列最有名的开源实现,有十分多语言曾经反对基于AMQP协定与音讯队列通信,同时还能够通过插件反对STOMP、MQTT等协定接入。Kafka、RocketMQ均应用自定义的协定。
7. 生产关系
包含三种
1) 点对点,也就是P2P,FIFO的队列,能够看做单播。
2) Topic模式,Pub/Sub公布订阅。
3) fanout播送模式。
8. 音讯沉积能力
长久化音讯,如果存储在本地磁盘,能够应用同步刷盘和异步刷盘两种策略。磁盘不能有限沉积,会有清理策略,例如Kafka、RocketMQ都依照工夫、数据量进行retention。
非长久化,仅放在内存,消费者解决完可抉择删除掉。
9. 牢靠投递
对于producer,从API和I/O层面可应用同步、异步,对于吞吐层面可应用单条、批量。fire-and-forget模式,相似UDP,只管发送即可。针对可能产生的谬误,例如连贯broker失败,RPC超时、公布音讯失败、公布后无响应,可抉择疏忽或者重发,所以往往反复投递的状况不可避免。
对于broker,如果要保证数据100%不丢,是可能的,然而须要就义下性能和吞吐,应用同步多写、多正本策略+同步刷盘长久化音讯,能够严格保障不丢。另外,broker对于写入音讯的payload,也会做完整性校验,例如CRC等。
10. 牢靠生产
生产次数,包含at most once、at least once、exactly once,其中前两个比拟好做到,最初的exactly once须要streaming consumer零碎和broker端合作实现,例如storm的trident和flink。
推拉模式,push or pull。推模式最小化投递提早,然而没有思考consumer的承载能力,拉个别是轮询接管broker的数据,依照consumer本人的能力生产。
生产记录点,个别每个音讯都有一个offset、ID或者工夫戳,consumer能够依照这个offset来进行定点生产以及音讯重放。
音讯确认,consumer生产实现ACK回调broker或者集群高可用中间件(zk)告诉生产进度。
错误处理,对于生产失败的状况,能够回复NACK,要求重发/requeue音讯,当谬误超多肯定阈值时候,放到死信队列中。
音讯反复生产,这和生产次数有关系,consumer在某些时候须要做到幂等性,保障反复生产不会引起业务异样。
11. 音讯类型
程序音讯,有序的话,分为分区有序或者全局有序,前者能够依照某个业务ID取模,在发送端发到不同的分区/queue即可,后者往往须要单个队列才能够满足。无序生产则可最大化吞吐。
定时音讯,事务音讯,例如RocketMQ均反对。
12. 音讯查问
目前RocketMQ反对音讯依据msgId查问。
13. 生态交融
客户端语言的丰富性,与其余零碎的集成度,例如Kafka和大数据技术栈交融很严密,Spark、Storm、Flink、Kylin都有对应的connector。
14. 管理工具
分布式系统的治理是进步生产效率的必备保障,一个好的零碎,如果周边工具不欠缺,对于使用者会很不敌对,推广也会有艰难。
对于音讯队列,能够从topic治理、broker治理、集群治理、权限/配额治理、多租户、客户端工具、监控、报警、控制台Console UI来全方位进行治理。