第七章:基于空间的架构
大多数基于web的业务应用程序遵循相同的通用请求流程:首先,web服务器接收来自web浏览器的请求;然后,应用服务器处理该请求;最后,数据库服务器提供所需数据。尽管这种类型的请求流对于少数用户非常有效,但随着用户负载增加,瓶颈开始出现。首当其冲的是web服务器,其次是应用服务器,并最终影响到数据库。
针对用户负载增加引起的瓶颈问题,一般常见的解决方案是扩展web服务器规模。这种方法相对容易且经济实惠,在某些情况下可以缓解部分瓶颈问题。然而,在大多数高用户负载情况下,仅仅扩展web服务器只会将瓶颈转移到应用服务器上。扩展应用服务器可能比扩展web服务器更为复杂、昂贵,并且通常只能将瓶颈问题转移至数据库层面。而在数据库层面进行扩展则更加困难和昂贵。即使你可以扩展数据库规模,最终得到的拓扑结构仍呈三角形形态(如图7-1所示),其中最宽部分为web服务器(最容易进行规模化),而最窄部分则为数据库(最难进行规模化)。
Figure 7-1. The database is usually the ultimate bottleneck for highly scalable systems
在高并发用户负载极大的大规模应用中,数据库通常是限制同时处理事务数量的最终瓶颈。尽管各种缓存技术、数据库扩展和分片产品有助于解决这些问题,但实际情况仍然存在:当涉及到数据库时,在极端负载下对应用进行横向扩展是一项非常具有挑战性的任务。
基于空间的架构风格是专门设计用来解决高可扩展性和并发性问题的。它也是一种适用于具有变化和不可预测的并发用户量(称为弹性系统)的应用程序架构风格。基于空间的架构关注解决极端和多变的可扩展性需求。
拓扑结构和组件
基于空间的架构风格通过将数据库从系统的事务处理中剥离,以解决应用程序扩展性的限制。因此,该架构被称为空间型架构。这个风格得名于计算机科学术语元组空间,即具有共享内存的多个并行处理器概念。通过使用在事务处理期间复制到内存中的数据网格来替代数据库,实现了高度可扩展性。应用程序数据保存在内存中,并在所有活动处理单元之间进行复制,并使用数据泵异步与后台数据库同步(下一节将详细介绍)。
随着用户负载增加和减少,可以动态启动和关闭处理单元,从而实现可变可伸缩性。由于系统的事务处理过程中没有涉及数据库,因此消除了数据库瓶颈,在应用程序内提供近乎无限的可扩展性。图7-2说明了空间型架构风格的拓扑结构。
Figure 7-2. The space-based architecture style
在这种架构风格中,服务被正式称为处理单元。一个处理单元(如图7-3所示)包含业务功能,并且从单一目的函数到整个应用程序功能的粒度不等。每个处理单元都包括业务逻辑、内存数据网格以及可选的基于Web的组件来容纳事务数据。同时,处理单元可以通过虚拟化中间件的处理网格直接或间接地相互通信(在下一节中描述)。
Figure 7-3. The processing unit contains the application functionality and an in-memory data grid
这种架构风格所涉及的复杂性是通过虚拟化中间件来进行管理。该中间件负责处理请求和会话管理、数据同步、处理单元之间的通信和编排,以及动态地关闭和启动处理单元以实现弹性和用户负载管理。虚拟化中间件包含四个主要的架构组件:消息网格、数据网格、处理网格和部署管理器。
消息网格负责管理输入请求和会话信息。当一个请求进入虚拟化中间件组件时,消息网格组件确定可用于接收该请求的活跃处理单元,并将其转发给其中之一。消息网格的复杂性可以从简单的轮询算法到更为复杂的下一个可用算法,该算法追踪正在处理哪个请求以及由哪个处理单元执行。通常情况下,传统Web服务器被用作实现消息网格。
数据网格组件是这种架构中最重要和关键的组件之一。当数据更新发生时,数据网格与每个处理单元中的数据复制引擎进行交互,以管理处理单元之间的数据复制。由于消息网格可以将请求转发到任何可用的处理单元,因此每个处理单元在其内存中的数据网格中都必须包含完全相同的数据。通常通过缓存产品(如Hazelcast、Apache Ignite和Oracle Coherence)来实现数据网格,这些产品负责管理着数据网格的同步和复制。当内存中的数据网格发生更新时,该同步通常在后台异步进行。
数据网格还有一个附加元素是一个异步发送更新到数据库的“data pump”。可以通过多种方式实现“data pump”,但通常使用消息传递或流式传输来管理持久队列。“data writers”组件会异步监听这些更新,并相应地更新数据库。“data writers”可以以多种方式实现,在粒度上从应用程序级别自定义“data writers”或者针对每个处理单元类型专门设计不等。
在系统崩溃或部署导致冷启动时,“data readers”会利用反向“data pump”从数据库检索并将数据泵送到处理单元。然而,一旦至少有一个具有相同内存中的已填充了 的 数据 网 格 ,则 可 以 启 动 并 填 充 其 他 处 理 单 元 而 无 需 从 数 据 库 检 索 数 据 。 “图7-4”说明了包含 内 存 中 数 据 网 格 、数 据 泵、数 据 写入器 和数 据 阅读器 的 数据 网 格。
虚拟化中间件的处理网格组件是一个可选组件,用于协调或编排不同处理单元类型之间的请求分布式处理。通过处理网格进行协调,也可以直接以编舞方式在多个处理单元之间进行。
Figure 7-4. The data grid contains the in-memory data grid, data pumps, and data writers
最终,部署管理组件根据负载条件动态地启停处理单元。该组件持续监测响应时间和用户负载,在负载增加时启动新的处理单元,并在负载减少时关闭处理单元。它是满足应用程序可扩展性需求的关键组件,通常通过容器编排产品(如Kubernetes)来实现。
示例
基于空间的架构是一种高度复杂且专门化的架构风格,主要应用于需要具备高容量、高弹性系统以及卓越快速性能的场景。
一个典型的空间型架构示例是音乐会售票系统。设想当您最喜欢的摇滚乐队宣布演出并开始售票时,将发生什么情况。在短短几秒内,成千上万人同时涌入购票网站,每个人都渴望获得同样优质位置上的座位。对于如此规模和性能要求之高、具备弹性特征的系统而言,持续地读写数据库根本不可行。
另一个从空间架构中获益的弹性系统的例子是在线拍卖和竞标系统。在大多数情况下,卖家无法预知参与竞标的人数,并且竞标过程总是在最后阶段变得迅速而激烈,显著增加了并发请求的数量。一旦竞标结束,请求量就会降至最低,并且整个过程会在接近结束时再次重复——这是弹性系统的又一个典型案例。
高流量的社交媒体网站是另一个适合基于空间架构的典型案例。在短短几秒钟内处理数十万甚至数百万条帖子、点赞、踩和回复,数据库显然会成为这种规模的挑战(无论其弹性行为如何)。而将数据库从事务处理中分离出来,并通过空间架构最终实现数据持久化,是解决这一复杂问题的一种可行方案。
斟酌和分析
基于空间架构是一种复杂且昂贵的实施方式,因此不适合像本报告中审查的其他通用架构那样广泛应用。相反,它更适用于特定情况,如高可扩展性、高弹性和高性能。
基于空间架构的一个独特特点是其部署模型。整个架构可以完全基于云端、完全在本地(on prem)或两者兼而有之。这种后一种部署模型对于基于云端的数据同步尤为有效,其中主要的事务处理在云端进行,但数据必须保留在本地。在这种模型中,数据写入和读取通常与数据库一起驻留在本地,并且异步数据泵将来自云端处理单元的数据发送给数据写入者。
基于空间架构被视为一种技术上的分区架构,因为领域功能分布在多个技术组件中,包括处理单元、内存数据网格、数据泵、数据写入器和数据读取器。一个基于领域的变更(尤其是涉及到数据的变更)通常会对所有这些组件产生影响。
什么时候考虑这种风格
这种架构风格非常适用于需要高并发可扩展性或弹性的情况。当涉及到数据库时,处理成千上万个甚至更多的并发请求变得极具挑战性,而该架构风格将数据库从可扩展性方程中剔除,提供了近乎无限的可扩展性。
另一个考虑使用该架构风格的用例是那些需要非常高性能和响应能力的系统。由于该架构依赖内存缓存,数据更新和检索通常以纳秒为单位进行测量,因此它是本报告审查过的所有架构风格中最具响应能力和高性能特点。
什么时候不要考虑这种风格
即使您具有高度可扩展的性事务处理能力和大规模数据量,这种架构可能并不适合考虑。由于所有事务数据都存储在内存中,因此整体数据大小成为空间型架构的限制因素。试想一下将45TB的关系数据库放入内存中!
鉴于该架构风格技术上的复杂性,如果预算紧张且时间有限,则不宜选择该架构。此外,在测试环境中实现非常高负载用户既昂贵又耗时,这使得难以测试应用程序在可扩展性方面表现如何。因此,该架构风格相对整体敏捷性(快速响应变化能力)较低。
由于空间型架构始终是最终一致性的,在内存数据网格更新达到数据库之前可能需要很长时间。因此,对于那些需要系统之间高水平数据一致性的系统来说,并不适合考虑使用空间型架构。
架构特征
图7-5中的图表概括了基于空间的架构在星级评分方面的整体能力(架构特征)。一颗星表示该架构特征得到支持不足,而五颗星表示其非常适合该特定的架构特征。
附录
风格分析总结
图A-1总结了本报告中描述的各种架构风格的架构特征评分。一个点表示该架构风格对该架构特征的支持较弱,而五个点表示该风格对其有良好的支持。
这个摘要将帮助您确定哪种风格可能最适合您的情况。例如,如果您主要关注可扩展性,您可以查看此图表,并发现事件驱动式、微服务式和基于空间的风格可能是不错的架构选择。同样地,如果您选择分层体系结构风格用于应用程序,则可以参考图表以了解部署、性能和可扩展性可能是您架构中存在潜在问题领域。
虽然这张图表和报告将帮助指导您选择正确的风格,但在选择一种架构风格时还有更多需要考虑的因素。你必须分析环境的所有方面,包括基础设施支持、开发人员技能集、项目预算、项目截止日期和应用程序大小等等。选择正确的架构风格至关重要,因为一旦建立起一个架构,在改变它时非常困难(也很昂贵)。
Figure A-1. Architecture styles rating summary