小蚂蚁说:算法
消息队列做为一个数据的集散中心,承载了愈来愈多的场景和数据,从最开始的 OLTP 到 OLAP,甚至再到物联网、人工智能、机器学习等场景,都有很大的想像空间。 在能力上,消息队列如今拥有了数据,拥有了算力,从承载数据走到理解数据。数据库
蚂蚁金服也在思考给消息队列加入算法的能力,让算法走进消息队列,走向下一个阶段 :洞察数据。把这些能力综合起来,打造一个智慧的传输计算服务平台。后端
还有一个好消息,消息队列做为 SOFA (Scalable Open Financial Architecture )技术体系比较核心的组成部分,后续也会积极拥抱开源和社区。缓存
本文根据蒋涛在 GIAC 2018 的主题分享《金融级消息队列的演进之路》整理编辑,将给你们分享蚂蚁金服消息队列发展过程当中的故事,以及这个过程当中的架构思考。网络
在蚂蚁金服,消息队列已经有十多年的历史了。在0七、08年时,咱们采用了 ESB 这样的方式来实现消息的机制。架构
那个时候遇到的最头疼的问题就是丢消息,排查和修复起来很是的痛苦。到了09年,和淘宝共建并上线了新的消息队列系统,丢消息的问题获得了有效的改善。框架
蚂蚁的业务具备金融级的属性,从这个角度,有哪些比较关键的需求呢? 集中表现为如下四点:运维
极高的可靠性机器学习
举个例子,经过消息去生成帐单,若是这个消息不可靠,消息丢了,这个时候会发生什么样的状况呢?客户付了一笔钱,可是在帐单或者消费记录里却看不到这笔记录,这个时候就很是困惑了。 所以极高的可靠性指的是:消息不能丢。分布式
极强的一致性
极强的一致性在金融业务当中是很是关键和重要的。 假如作一笔转帐操做,由于种种缘由,好比网络抖动,转帐失败了,若是一致性没有作好,可能还会收到一条作了一笔转帐的通知,这个时候系统的数据就不一致了。
持续的可用性
持续的可用性,是指在但愿用系统提供的服务能力的时候,这个服务必定是要可用的。 好比说双十一的时候,线上生成一笔订单须要支付,必定但愿它能很是顺利的支付完成。再一个,如今线下的场景很是火,到超市去买东西,结帐的时候也但愿扫码支付要很是顺畅,这都是对可用性的要求。
极高的性能
在蚂蚁金服,天天有千亿级的消息在流转,峰值的 TPS 也达到了千万级。在这么大的体量下,对性能的要求是很是高的。另外,从成本角度和用户的体验的角度,性能也是很是须要关注的地方。
刚刚提到了金融场景下的四个核心的性能要求,那么具体如何来知足呢?
1. 如何作到极高的可靠性?
ACK 的机制。ACK 机制借鉴了 TCP 里面的思路,经过发送阶段、持久化阶段、投递阶段的 ACK 机制,保证了消息在流转路径的各个环节上的可靠性。
重试的机制,保证了消息在投递出去后,当消费端消费不成功的时候,还能够再次去消费。
经过存储层的持久化机制和可靠性机制来保证消息数据自己的可靠性。
2. 采用两阶段事务消息机制来保证极强的一致性
在第一阶段里面,把发消息和业务本身的业务操做放到本地事务中,发出来的是带有未提交状态的消息。 在第二阶段,会根据本地事务执行的状况来决定一阶段发出来的消息是提交仍是回滚,若是是回滚,把消息删掉就行了,若是是提交,会去更新这个消息的状态,从未提交改为已提交,接着去作投递的动做。
若是第二阶段中的事务状态通知丢失了,消息服务端会去主动向消息发送端作事务状态回查,直到拿到明确的事务提交或者回滚的回查结果。
3. 持续的可用性的实现
在单机房的时代就在作提高可用性的事情。好比,在应用层面作了线程池的隔离,作了限流、熔断等等。在架构层面去作各类水平伸缩能力,在故障隔离层面作单点的隔离,作集群部署的隔离等等。这些手段提升了系统的可用性。
可是,因为受限于单机房部署的架构,当出现机房级别问题的时候,前面的手段就爱莫能助了。
固然,同城双活架构能够经过业务流量在两个机房之间作切换,也能够经过数据层面的切换等手段来有效的解决机房单点的问题。
可是,随着业务增加,同城双机房模式在容量和容灾能力上也逐渐没法知足业务发展需求了。
面对同城双活也没法解决的状况,蚂蚁金服沉淀出异地多活 LDC 架构:
以转帐为例,在异地多活的架构下,收款方跟转帐人可能在一个逻辑 Zone 里面,也可能不在一个逻辑 Zone 里面,甚至他们可能都不在一个城市。这样带来一个最重要、最核心的需求就是消息队列须要具备很是灵活、很是强大的路由能力,能够作Zone内的路由,能够作同城跨Zone的路由,也能够作跨城跨 Zone 的路由。
在实现上,若是发现这个消息是要作同城跨 Zone 的路由,在消息服务端作了一个打通,经过服务端作转发,当发现是跨城场景的时候,经过一个叫 MQ-router 的系统,对跨城的链路作了一个收敛,也对城市级部署的逻辑作了一个收口,全部须要通过跨城的逻辑所有收口到这样一个系统当中,统一并灵活的支撑了异地多活的架构。
有一类会员信息数据,比较有特色:
一、访问量很是大,把它放到缓存里面,下降对后端数据库的压力。
二、在一次业务请求当中,对这个数据可能有很是屡次的访问,因此对数据访问的延迟很是敏感。若是这类数据须要跨城才能访问到的话,跨城带来的延时对业务而言是很是难以接受的。所以就要求这类数据从本城市就可以访问到,每一个城市都须要有全量的这类数据。
三、这类数据对变动的时效性很是敏感。数据变动了,须要很是快的感知到。若是依靠数据库层面的复制机制来作这件事情,会有大概秒级的延迟。
因而,咱们设计了一个基于消息的方案,来实现一个城市级的缓存更新的机制。重点给 MQ-router 增长了广播的能力。当这类数据发生变动的时候,以消息的方式发出来,经过 MQ-router 以广播的形式发送到全部城市去,这样就达到了多个城市的缓存实时更新的效果。
4. 性能方面是持续在打磨的一件事情
消息队列基于 SEDA 模式来实现,引入了自研的高性能网络通讯层 SOFABolt来提升消息通讯的性能。除此传统的优化手段以外,也在调研和思考更先进的一些方式,好比硬件结合的方式,像DPDK、RDMA这样的技术,去追求更极致的性能。
有很长一段时间,消息队列的研发工做都是围绕着交易、支付、帐务等OLTP的业务展开。因此一直在打磨消息队列在OLTP场景下的功能。好比,经过数据库存储保证消息可靠性,经过推的模式提升消息的实时性等。 随着业务场景的扩展,特别是大数据时代的到来,愈来愈多的OLAP场景出现了。这个时候前面的这些作法,特别是推的这种模式就遇到不少的困难。
到了这个阶段,咱们去作了基于Log语义的拉模式的消息队列。 拉模式消息部署在物理机上,经过顺序写本地磁盘的方式去实现拉的语义。在必定时间内比较有效的支持了OLAP这种场景的需求。
随着拉模式的推广,不少 OLTP 的场景也逐渐的采用了拉模式,提出了不少新的需求。好比 OLTP 对数据可靠性要求比较高,对本地文件存储可靠性的问题就很是关注。
因为是基于物理机部署,也遇到不少运维上的难点,好比成本、机型等等的一些问题。特别是物理机机型变化很是多,每次采购可能都不同,很是难以作标准化。在作容量规划、缩容扩容这些事情时会遇到很是多的困难。
消息是比较重 IO 轻计算的模型,在物理机上就会表现出很是明显的资源配比不均衡的问题。每每是磁盘已经不够用了,但 CPU 还很空闲。基于物理机的运维也很复杂,资源利用率不高、容量规划很差作、扩容缩容困难等问题凸显。
在作这件事情的时候,咱们一开始采起了一种比较轻量的方式,称之为挂盘的模式。 经过挂载的方式,将分布式文件系统挂在消息队列应用上面。这个作法的好处是应用系统自己基本上不须要作什么改造。消息数据透明的写到了分布式文件系统上,依靠分布式文件系统提供的三副本高可靠的能力来保障消息数据的可靠性。
在这个阶段还作了一件事情,就是把消息应用的规格作了标准化。能够去制定相似8C、16G、1T 这样的规格,有了标准规格,就能够比较准确的测算某个规格能够顶多少TPS的消息量,这样作容量规划就很容易了。 这个模式上去以后,承载了一些业务,也接受了双十一大促的考验。
因而,咱们开始了计算存储分离的第二阶段:API 模式,在性能上有了一个比较明显的提高。 这个模式下,消息服务端要作比较大的改动,趁着这个机会,也作了不少功能方面的加强。好比,加入了对全局固定分区的支持,还有发送幂等与强顺序的能力等。 同时,把数据落地也作了一个改变,原先数据所有集中在一个commit log中,转移到了队列里面去。这样带来的好处是能够在队列级别作更细粒度的配置和管控。
这个架构总体而言是一个相对比较完善的计算存储分离的架构了。在应用层面也作了不少可扩展的设计。
总体上,计算存储分离的模式给消息队列打下比较好的基础,能够跟蚂蚁金服全站的运维模式作很好的适配。
消息队列承载了愈来愈多的消息数据,大量的数据流进来再流出去。都说在大数据时代,数据就是金钱,可是能够发现这么多的数据流过消息队列,却没有淘到金。
经过思考这个问题,发现很是关键的一点是由于一直在用一种比较传统的方式去看待消息队列,认为它是消息的一个通道,消息流进来再流出去,使命就结束了。在这样的思路下,着力打造的是它的传输能力,它的存储能力,它的可靠性等。可是却忽略了在大数据时代很是重要的一个能力,就是计算的能力。
带着这个问题去看业界的一些发展,获得了不少新的思路。特别是从Kafka身上获得了不少的启发。
因而咱们决定让计算走进消息队列,以 streaming 方式为消息队列增长了一种计算能力,实现了一个轻量级的非中心式的计算框架,既能够嵌入客户端,也能够嵌入消息的服务端,作一些轻量级的计算,支持一些比较通用和轻量的算子和多种计算窗口语义。
至此,消息队列有了传输、存储和计算的能力
基于这些能力,把消息队列往更大的层面上去推动,构建一个数据传输计算平台。不断丰富消息队列能力,不断拓展愈来愈丰富的数据源,获取愈来愈多样的数据,而且把消息投递到更多的目的地去。在传输过程当中对消息进行计算,以得到更多计算带来的价值。
经过前面的回顾,咱们能够看到,消息队列做为一个数据的集散中心,承载了愈来愈多的场景和数据。
在能力上,消息队列如今拥有了数据,拥有了算力,正在走过一条从承载数据到理解数据的道路。接下来,咱们也在思考给消息队列加入算法的能力,让算法走进消息队列。 这样就能够向下一个阶段 -- 洞察数据再迈出一步,就能够把这些能力综合起来,去打造一个智慧的传输计算服务平台。这样消息数据不只是流转过消息队列,还能够通过更多的计算和加工,更轻快更实时的发挥更大的价值。
本文做者:兔子酱
阅读原文本文为云栖社区原创内容,未经容许不得转载。