共享数据库 vs 消息架构

23

昨天我和一个朋友在酒吧谈起了他所在公司正在使用的架构,我们主要讨论了共享数据库架构与分布式独立应用程序架构之间的利弊,但最终没有达成共识。因此,我想听听大家对这两种方法的优缺点有何看法。

基本上,他所在的公司具有许多不同应用程序的大型架构。某些应用程序在它们之间共享单个数据库。例如,有一款提供用户调整参考数据的 UI 的应用程序。另一个应用程序也访问相同的数据。我认为代码实际上是编写为共享库(即两个应用程序都将使用共同的代码集,该代码集对于每个应用程序都会进行重新部署(其中一个应用程序将其作为依赖项))。

还有其他应用程序具有数据库,该数据库也由其他应用程序通过直接 JDBC 连接和数据访问代码使用(两个应用程序之间不共享 - 重复!! 难以忍受!)。

我的问题是关于这种架构与每个应用程序将其“主数据”保存在存储区内的架构之间的利弊。如果应用程序 X 需要来自应用程序 Y 的数据,则使用 Web 服务或某些消息技术接收该数据。

消息传递方法会引入一个问题,即其他应用程序数据库中使用的参考数据代码(或外键)现在必须从另一个源中获取。在当前架构中,这些代码的“解码”可以随时更改并立即反映在外部应用程序中,而无需具有主 / 从关系,其中数据被复制 - 或者是另一种替代方案,即应用程序 X 必须查询应用程序 Y 才能显示解码值。

我曾阅读过《企业集成模式》,尽管它确实提供了消息传递的优点示例,但我不太确定。

谢谢,艾恩


嗨,艾恩,你在这个话题上有更多的了解吗?我想知道你是否有兴趣进行线下讨论。我相信共享数据库的优点超过了缺点,但是我认为当前技术思维方式的流行与我的总体感觉不兼容。我对理想架构有一些想法,特别是针对大型组织,并寻找能够诚实反馈而不被部落思维所影响的人... - Quicker
@Quicker 我是一家初创公司的联合创始人之一,我们对共享数据集成模式很感兴趣。如果您仍然愿意离线讨论您的想法,我们很乐意分享这个话题的想法。请联系dave@yodata.io,我们可以找时间交流。 - Brian Shamblen
4个回答

30

基于消息的集成相较于共享数据库的优势难以表述,但我们将在此尝试:

不可避免地会出现争论,DBA希望对实体之间的所有关系进行建模,以便数据始终100%一致。另一方面,开发人员警告DBA关于紧耦合单片式架构中出现的问题,以及绑定到主表的应用程序无法轻松更改。

我认为这两个论点都只是表面上的,构建一个易于更改的系统具有挑战性,无论您如何进行集成。我想提出SOA和基于消息的集成的另一种论点。

归根结底,问题在于:

  1. 共享数据库集成通常是由"大系统"视角驱动的。
  2. 基于消息的集成通常是由"小系统"视角驱动的。

有多少次你遇到过拥有数百用户,支持多种不同业务功能的大型系统?我经常遇到这样的系统。它们似乎是企业软件的主要组成部分。

所有这些系统似乎都有一个共同点,那就是它们改变起来非常昂贵。其中一个原因是,正如Joe R在his answer中所说,紧密耦合。

然而,耦合是一个危言耸听的术语,我认为我们需要考虑两种非常不同的耦合类型。

第一种可以被看作是技术耦合,这意味着技术栈内的垂直耦合,通常在一个层和另一个层之间。

因此,应用程序的数据库和数据访问层之间存在耦合,数据访问层和业务逻辑层之间也存在耦合。普遍认为将这种耦合视为不好或错误的,但理性思考后,我们难道不应该期望或甚至欢迎,例如User DTO、UserRepository类和User数据库表之间高度耦合吗?

让我们考虑一下在实现层面上耦合实际上意味着什么。当多个层基本上相互交谈同一个业务实体时,概念“属于”一个东西泄漏到另一个东西中时就会发生耦合。

第二种类型的耦合是我想要解决的,可以被视为业务能力耦合,也称为水平耦合。这是指属于一个业务能力的概念渗入到另一个业务能力中。

我断言使用数据库作为集成平台鼓励了这种水平耦合

举个例子,想象一下支持电子商务网站系统的典型后端系统。通常会有库存、订单、定价和CRM作为核心功能。

如果我们在单个数据库内建模这个领域,实际上就将不同的功能联系在一起。每个外键约束都可能增加这些功能之间的耦合度。事实上,到了这一步,系统已经可以被认为是通过共享数据库集成的几个不同的“服务”。
这是“大系统”世界的图景,通过使用超过500个表的巨型数据库将企业不同领域联系在一起得到支持和鼓励。
相比之下,“小系统”世界的图景与之不同,在我们的示例后端Web应用程序中,库存、订购、定价和CRM是完全独立的应用程序,具有自己的技术堆栈、项目团队、发布计划和数据库。
每个应用程序或“服务”将拥有自己对给定实体的理解,并根据其支持的业务能力来定义该实体。
其中一个例子就是“用户”。 CRM对用户的定义与订购或履行存在非常不同的定义。订购只关心用户正在购买的东西。CRM关心其他方面,如客户购买模式,履行关注姓名、地址等。在共享数据库中使用单个用户表不容易实现这一点。
这张图片对我来说比共享数据库更可取的原因是,生成的系统将更好地模拟它应该支持的实际业务流程。DDD 的主要原则之一是,系统应尽可能地类似于拥有它的业务。在典型的企业中,这些各种能力不是由跨越大型企业的团队层实现的,而是由小型垂直团队实现的,这些团队通常完全自治,他们相互之间和与其他垂直团队沟通,通常通过发送请求、指令或让其他团队知道某个进程或任务已经开始/完成等方式。
好的,但没有共享数据库,网站现在依赖于来自所有这些不同服务的数据来更新其UI。它仍然需要在同一屏幕上显示这些内容。网站“呈现”层如何组装所有这些并将其呈现给UI?
更重要的是,如果CRM想知道客户何时订购了东西怎么办?如果订单想知道产品价格何时变化,或者库存中的产品缺货怎么办?如果这些服务完全独立,则它们如何交换数据?
首先解决用户界面问题,可以使用组合用户界面。有许多技术可供选择,但可以说这是一个相对熟知的领域,不是我们关注的重点。
第二个问题是这些服务如何通信,它们通过交换事件来实现。什么样的事件呢?事件由一个系统发布,以便任何其他对该事件感兴趣的系统消费。
在我们的电子商务示例中,事件的种类可能包括:
  1. 下单
  2. 客户升级为金牌会员
  3. 产品打折
  4. 库存耗尽
这些事件具有业务含义。这意味着我们可以通过小型系统方法获得额外的好处,即集成媒介本身具有业务含义,并且可以用业务语言表达,这非常适合Scrum和敏捷方法论。
因此,最终回答OP的问题,我认为从技术角度来看,共享数据库与消息集成方法之间没有太大的区别。两种方法都需要相同类型的抽象和语义。但我认为它们背后的驱动力和采用更小系统思维的结果有很大的差异,这提供了更好的整体业务价值。

1
谢谢您分享您的想法。所以,我理解并倾向于同意“小系统”世界——根据您的例子,一些主要部门被分隔成具有自己的数据库和业务规则的独立系统。数据不被视为重复,因为每个系统为不同的目的保留了数据的不同表示。那么交叉实体呢,比如基于角色的访问控制?它是自己的系统,其他系统通过API和MQ消息进行通信吗? - diegohb
1
你提出了一个有趣的问题 - 老实说我没有想太多关于跨领域问题,然而像基于声明的身份验证这样的范例(它被Sharepoint 2013使用并且非常“独立的系统”)可能会填补这些空白。 - tom redfern
谢谢!这很有道理 - RBAC(通过声明)管理,用户配置和身份验证/授权都是它自己的子系统,通过API暴露给其他子系统。 - diegohb
嗨,艾恩,你在这个话题上有更多的了解吗?我想知道你是否有兴趣进行线下讨论。我相信专业人士的优点超过了共享数据库的缺点,但是我认为当前技术思维方式的流行与我的一般感觉不兼容。我对理想架构有一些想法,特别是针对大型组织,希望找到一个可以诚实反馈而不被部落思维所影响的人... - Quicker
谢谢Tom。实际上,我在stackoverflow中没有找到好的离线讨论支持。你有任何地方可以做到这一点吗?任何开放的论坛之类的东西?事实上,我对一个结构化和优先级排序的参数列表很感兴趣,我想开始着手处理这个问题。然而,我相信我自己无法完成。我认为我们在两个答案中看到了一些争论。但是我不确定那是否真的是全部内容。例如,现在你可以在RAM中存储6TB的数据,管理大量表格是治理而不是技术问题... - Quicker
显示剩余7条评论

6
我正在工作中处理这个问题。我认为使用其中一个的原因非常清晰(还有一些尚未提及的点)。 数据库集成 优点
  • 真相唯一
  • 交易性
  • 无需管理新技术或中间件
  • 独特的键很容易
缺点
  • 不易扩展。你最终会得到一个单个的数据库运行各种工作负载,如事务和报告,或者你最终会得到数据库复制以分发生产负载。

  • 广域分发很困难。多站点架构更加困难。

  • 技术是固定的,并且供应商被锁定
  • 在数据库中进行硬排版(假设为SQL),强制对系统进行全局更新,以进行像更改列大小这样的小更改
消息传递系统 优点
  • 可以分布负载并使用专门针对各种任务进行优化的系统
  • 可以与现有系统并行部署替代系统。
  • 消息格式(即网络数据模型)可以进行版本控制,并且多个版本可以同时运行
  • 支持复杂的广域拓扑结构——例如,具有中央枢纽的多个实例,具有在每个实例上共享所有数据的多个实例。
  • 相对容易地适配遗留系统,并且这些系统随后可以集成而不需要进行大量工作
缺点
  • 需要部署和管理新系统。
  • 很难保证事务性。

4

以下是共享数据库架构的一个缺点,足以避免使用它:

紧密耦合 - 如果一个应用程序需要更改主数据库表,则其他应用程序将需要重新测试并可能需要更改以适应这些更改。

共享数据库架构最终会避免对模式进行重大更改。主数据库和相关应用程序往往停滞不前,导致公司无法提供创新的新产品。

此 MSDN 文章之一解释了如何通过松散耦合的服务来帮助处理上述情况。松散耦合的系统可以进行创新和更改,而不必要求公司同时进行更改,从而使公司能够很好地响应客户需求。


我认为这是一种谬论。如果所有东西都绑定到表格上,那么你的说法就是正确的。但这正是存储过程和视图所用的,对吧?这样,如果底层表格发生变化,也不会影响到依赖系统。 - tom redfern
谢谢您的评论 - 您不认为如果基础表发生更改,存储过程需要重新测试吗? - Joe Ratzer
是的,我想是这样。它们需要重新测试。但是如果更改消息模式,情况也是如此 - 这意味着使用此消息的所有系统都可能受到影响。 - tom redfern
我认为你的观点基本上是正确的 - 我在这里与许多DBA就垂直耦合问题进行过争论,以及如何通过消息传递来解决它,但实际上并没有。我认为消息传递的好处更深入 - 请参见下面我的回答。 - tom redfern
我看到过紧/松耦合的争议在很多地方都有讨论。实践证明,如果您需要更改服务导向设置中某个位置的数据关系,则需要调整所有接口和所有依赖系统。大多数情况下,属性也是如此。那么问题来了?在共享数据库环境中,您可以仅为架构拥有一个质量/门卫。因此,通过四眼原则更容易实现治理执行。即使从成本方面考虑,维护数百个接口的成本也难以低于承担数据库模式质量管理者的费用。 - Quicker

0
两者并不互斥。您可以使用消息来同步数据库,同时仍然拥有共享的数据库。
在我看来,消息传递的重点与大型数据库无关。消息传递不会使您与存储模式或解决方案解耦,因为消息模式不会改变。它提供的是时间上的解耦,即通过消息传递,应用程序知道如何创建新的事实,而不知道如何更改现有的事实,因此它们甚至可能不依赖于应用程序和数据库同时运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接