审校 | 重楼
数据库设计是微服务和云原生解决方案中的一个关键因素,因为基于微服务的架构会导致出现分布式数据。多个进程可以操作数据,而不是在单个进程中进行数据管理。云计算的兴起使得数据更加分散。
为了应对这种复杂性,针对微服务和云原生解决方案的数据管理已经出现了几种模式。本文将介绍可以帮助企业在分布式环境中管理数据的重要模式。
面向微服务和云的数据库设计的挑战
在深入研究具体的数据管理模式之前,先了解微服务和云数据库设计面临的关键挑战:
- 在微服务架构中,数据分布在不同的节点上。其中一些节点可能位于世界各地完全不同地理区域的不同数据中心。在这种情况下,很难保证跨所有节点的数据一致性。在任何给定的时间点,不同节点之间的数据状态可能存在差异。这也被称为最终一致性问题。
- 由于数据是分布式的,因此没有像单节点整体系统那样的中央机构来管理数据。对于各个参与系统来说,使用一种机制(例如共识算法)进行数据管理是很重要的。
- 在微服务架构中,恶意行为者的攻击面更大,因为有多个活动部分。这意味着开发人员需要在构建微服务时建立一个更健壮的安全态势。
- 微服务和云计算的主要承诺是可扩展性。虽然扩展应用程序进程变得更容易,但横向扩展数据库节点就不那么容易了。如果没有适当的可扩展性,数据库可能会变成性能瓶颈。
深入研究数据管理模式
考虑到相关的挑战,有几种模式可用于管理微服务和云原生应用程序中的数据。这些模式的主要工作是帮助开发人员解决以下提到的各种挑战。以下逐一看看这些模式。
1.每个微服务的数据库
顾名思义,这种模式建议每个微服务管理自己的数据。这意味着没有其他微服务可以直接访问或操作由另一个微服务管理的数据。任何数据交换或操作都只能通过使用一组定义良好的API来完成。下图显示了每个微服务的数据库模式的示例。
图1每个微服务数据库模式
从表面上看,这个模式似乎很简单。当从一个全新的应用程序开始时,它可以相对容易地实现。然而,当将现有的单片应用程序迁移到微服务架构时,服务之间的界限就不那么清晰了。
大多数功能都是以一种方式编写的,即系统的不同部分可以非正式地从其他部分访问数据。
在使用数据库服务模式时,需要关注两个主要方面:
- 为每个微服务定义有界场景。
- 管理跨多个微服务的业务事务。
2.共享数据库
下一个重要的模式是共享数据库模式。尽管这一模式支持微服务架构,但它采用了一种更为宽松的方法,即使用可被多个微服务访问的共享数据库。对于正在向微服务架构过渡的现有应用程序,这是一种更安全的模式,因为可以在不改变数据库设计的情况下慢慢地发展应用层。然而,这种方法剥夺了微服务的一些好处:
- 跨团队的开发人员需要协调表的模式更改。
- 当多个服务试图访问相同的数据库资源时,可能会出现运行时冲突。
3.CQRS和事件溯源
在命令-查询-责任分离(CQRS)模式中,应用程序侦听来自其他微服务的域事件,并更新单独的数据库以支持视图和查询。然后,可以从这个单独的数据库中提供复杂的聚合查询,同时优化性能并根据需要进行扩展。
事件溯源通过将实体或聚合的状态存储为事件序列而更进一步。每当对对象进行更新或插入操作时,就会创建一个新事件并将其存储在事件存储库中。你可以一起使用CQRS和事件溯源来解决事件处理和维护独立查询数据方面的许多挑战。这样,就可以根据各自的需求分别扩展写操作和读操作。
图2事件溯源和CQRS一起行动
对于大多数开发人员来说,不利的一面是,这是一种不熟悉的构建应用程序的风格,并且需要管理更多的活动部分。
4.Saga模式
Saga模式是跨多个微服务处理业务事务的另一种解决方案。例如,在快餐配送应用程序上下订单是一种商业交易。在Saga模式中,将这一业务事务分解为由不同服务处理的本地事务序列。对于每个本地事务,执行该事务的服务都会发布一个事件。
该事件触发另一个服务中的后续事务,该链将会继续,直到整个业务事务完成。如果链中的任何特定事务失败,则通过执行一系列补偿事务来回滚,这些事务撤消所有先前事务的影响。
有两种类型的Saga实现:
- 基于编配的Saga
- 基于Choreography的Saga
5.分片
分片有助于构建云原生应用程序。它涉及到将一个表的行分成多个不同的表。这也被称为水平分区,但是当分区位于不同的节点上时,它们被称为分片。分片帮助开发人员提高数据库的读写可扩展性。此外,它还提高了查询的性能,因为由于分片,特定查询必须处理更少的记录。
6.复制
复制是一种非常重要的数据管理模式。它涉及到创建数据库的多个副本。每个副本都是相同的,并且在不同的服务器或节点上运行。对一个副本所做的更改将传播到其他副本。这就是所谓的复制。有几种类型的复制方法,例如:
- 单领导者复制
- 多领导者复制
- 无领导者复制
复制帮助实现高可用性和提高可靠性,并且它允许扩展读取操作,因为读取请求可以转移到多个服务器。图3显示了分片和复制的组合工作。
图3同时使用分片和复制
云原生环境中数据库设计的最佳实践
虽然这些模式在解决微服务和云原生架构中的数据管理问题方面大有帮助,但还需要遵循一些最佳实践,以使工作和生活更轻松。
以下是一些最佳实践:
- 必须设法设计一个具有弹性的解决方案。这是因为故障在微服务架构中是不可避免的,设计应该适应故障,并在不中断业务的情况下从中恢复。
- 当转换到其中一种模式时必须实现适当的迁移策略。可以评估的一些常见策略是模式优先与数据优先、蓝绿部署或使用扼杀模式。
- 不要忽视备份和经过良好测试的灾难恢复系统。即使对于单节点数据库,这些也很重要。然而,在分布式数据管理方法中,灾难恢复变得更加重要。
- 在微服务或云原生应用中,持续监控和可观察性同样重要。例如,分片之类的技术可能导致分区和热点不平衡。如果没有适当的监控解决方案,对这种情况的任何反应都可能来得太晚,并可能使业务面临风险。
结论
因此可以得出结论,良好的数据库设计在微服务和云原生环境中绝对是至关重要的。由于分布式数据固有的复杂性,如果没有适当的设计,应用程序将面临多种问题。有多种数据管理模式能够以更可靠和可扩展的方式处理数据。然而,每种模式都有自己的挑战以及优点和缺点。没有任何一种模式能够适合所有可能的场景,开发人员应该在进行各种权衡之后选择一个特定的模式。
原文Designing Databases for Distributed Systems,作者:Saurabh Dashora