36 云原生:业界MQ的计算存储分离
存算分离架构
存算一体架构如下
存算分离架构则是目前实现弹性消息队列集群的主要技术方案
存算分离架构的优点是计算层为无状态,因此计算层的扩缩容就很方便。缺点是架构变复杂,代码实现难度也提升很多,日常的运维、研发的学习成本也会相应提高。另外计算层和存储层的交互从本地调用变为了网络协议的调用,性能上会有一些下降。
存算分离架构最大的好处就是集群变得更加弹性。从终态来说,没有存算分离,消息队列架构就无法 Serverless 化,也就无法做到快速扩缩容。从成本结构的角度来看,没法快速扩缩容,那么就无法提高集群的利用率,也就无法很好地降低成本。
实现存算分离架构的技术思考
如何选择合适的存储层引擎
因为分布式存储服务一般会提供多语言的流式写入的 API 进行数据读写,读写性能较高,比较适合消息队列的数据特点。所以从业界落地的角度来看,分布式存储服务用得比较多。比如 Pulsar 的存储层使用的是 BookKeeper,RocketMQ 5.0 的存储层用的是原先的 Broker 集群。
存储层:分区存储模型的设计
但是在存算分离的架构中,基本都是每个分区一个“文件”的方案。主要是出于数据的读写性能考虑。在存算分离的架构中,我们是通过网络协议从存储层读取数据的。
如果数据存储在一份文件中,则存储层在读取数据时就需要维护二级索引,并启动随机读,在性能上会有一定的降低
所以合理的方案如下图所示,不同的分区在存储层有独立的“文件”存储,然后顺序读写不同的段文件
计算层:弹性无状态的写入
分区的数据写入到存储层,依赖存储层多副本存储的能力实现数据的可靠存储。从技术来看,副本并没有被省掉,只是将副本概念下沉到了存储层而已
业界主流存算分离架构分析
RocketMQ 5.0 就是在原先 Broker 集群的基础上添加了一个 Proxy 组件。
前的 Proxy 组件只是转发层,不处理任何计算和存储的逻辑。集群实际意义上的计算和存储逻辑,都是在 Broker 集群上完成的。这就是我们前面所说的,当前 RocketMQ 5.0 的架构不是真正意义上的存算分离架构的原因。更准确的说法是,RocketMQ 5.0 只是从当前存算一体的架构往存算分离架构演化走出了第一步。
Pulsar 存算架构分析
Pulsar 计算层的分区都是单副本的,即没有副本的概念。每个 Pulsar 分区底层由多个 Ledger 组成,每个 Ledger 只包含一个分区的数据。每个 Ledger 有多个副本,这些 Ledger 副本分布在 BookKeeper 集群中的多个节点上
因为计算层就都是无状态的,迁移起来就很快,直接修改元数据即可
同时,为了提高负载均衡和迁移的效率,Pulsar 引入了 Bundle 的概念。参考图示,Bundle 是处于 Namespace 和 Topic 之间的一个概念,它是用来组织多个 Topic 的一个逻辑概念。即一个 Namespace 有多个 Bundle,一个 Bundle 里面有多个 Topic。
37 MQ的分层存储架构
什么是分层存储
为了降低存储成本,消息队列参考了冷热数据分离的思路,提出了分层存储的概念。如下图所示,写入数据的时候还是将数据写入到本地,然后通过在 Broker 中设置一定的策略将 Broker 上的老数据上传到远程的分布式文件系统中。在消费的时候,再从远程拉取数据到本地,给消费端消费。
分层存储就是指在不改动本地存算一体架构的前提下,通过一定的策略将本地的数据存储到远程,从而降低本地硬盘的负载压力。在消费的时候,再从远端文件系统下载对应的数据,提供给消费者消费
分层存储的应用和局限
生产性能优化
从生产的角度来看,因为数据是写入到本地文件,然后再通过异步线程上传到远端文件系统,所以从性能的角度看,写入性能基本不受影响。只有异步线程上传或下载文件时,对资源的占用(比如对 CPU、内存、网卡、硬盘等),可能导致写入性能受到影响
消费性能优化
消费请求只从本地的硬盘读取数据,同时有一个异步线程根据设置好的预读策略,提前调度,从远程下载接下来可能会消费的数据,再写入到本地,供消费请求读取。这里的核心就是预读算法的设计
从技术上来看,消息队列的预读算法比较好实现,因为消息队列都是顺序消费的模型,所以消费时我们自然就知道接下来消费哪些数据,只要提前下载好下一份数据分段即可
该方案的优点是,可以通过预读、批量读等手段提前将数据下载到本地,从而保证原先的消费流程不变,理论上如果全部命中热读,性能可以和非分层架构保持一致。缺点是下载数据写入到硬盘,可能会占用硬盘空间,影响 IOPS 性能,并且会占用 Broker 节点的带宽,此时可能会影响读写的性能。因为理论上会有冷启动的情况,所以此时消费性能就会低于非分层。
38 Serverless架构实现流式数据处理
典型的数据流场景
Serverless 的定义
Serverless 从语义上来讲是“无服务器”。从技术架构和底层技术运行的角度看,服务运行不可能没有服务器。实际上,无服务器是从客户的角度来理解的,指的是客户不需要关心服务器。某种意义上看,不关心相当于没有,因此是 Serverless 平台来负责服务器资源管理及运行。
Serverless Function
基于 Serverless 实现数据处理
底层架构和技术原理
数据源触发方式
两种方案的优劣势对比
日志清洗场景
事件流处理
之前的课程中,我们讲过推模型的一个缺点,那就是在业务高峰的时候,如果下游的处理系统有瓶颈,就会处理不过来,导致数据反压,影响服务端推的性能。而这种场景正是 Serverless 平台能发挥优势的地方,容量近乎无限(依赖平台储备),弹性扩缩容,按量付费。整体算下来,更省成本,也更及时。
39 基于MQ和Serverless设计事件架构
事件驱动架构
什么是 CloudEvents
CloudEvents 是一个开源项目,它的目的是定义通用的、标准化的事件格式。用来简化事件驱动架构中的事件发布、订阅和处理流程。它规范定义了事件的结构和元数据,使得不同的事件源、中间件和消费者之间可以更容易地进行相互操作
如何构建事件处理平台
事件处理平台分为接入层、缓存层、运行层、分发层四个部分
运行层执行完计算、处理、过滤的逻辑后,就会调用分发层触发具体的操作,比如调用 HTTP API、将数据写入到 DB 等等
40 利用MQ搭建数据集成架构
消息队列连接器的其中一端一定是消息队列
数据集成和连接器
数据集成是一个概念,不是具体的功能组件。它是将数据从数据源搬到数据目标这个功能的描述,数据从源到目标的过程就称为数据集成
将 MySQL 中的数据实时同步到 Elasticsearch
第一种方案适合数据源和数据目标是一对一的场景,第二种方案适合数据源和数据目标是一对多的场景。
Apache Kafka Connector
41 实现跨地域、跨可用区的容灾和同步
双向同步
Apache Kafka MirrorMaker
Apache Kafka 官方提供的主备集群复制方案,叫做 MirrorMaker,它的功能是实现主备集群之间消息数据和元数据的复制。
42 消息中台
统一的消息服务
PaaS 化和中台化
如果一个企业只有少数消息队列需求,且在使用、运维、升级方面的成本不高的情况下,用 PaaS 化的方案就够了。这也是为什么一般只有一些大企业才会建设自己的中台化消息服务。
所以总结来看,消息中台的必要性是根据企业的规模、使用量、对稳定性的需求来评估的。是一个可选项,而不是一个必选项。
中台化的技术实现分析
存储引擎的选择
接入层协议设计
接入层开发
从技术上看,消息中台接入层的开发用的是代理(Proxy)的思路
接入层主要由网关(如 Nginx)、元数据模块、接入层集群三部分组成。网关用于流量接入、拦截和分发;元数据模块用来存储接入层相关的元数据信息;接入层集群用于接收流量,然后转发到存储层