数据库 频道

为什么说集中管理数据是个坏主意?

  微服务架构是现代应用程序和系统的一个常见模型。其特点是把一个大型应用的业务责任分割成不同的、独立的组件,可以独立开发、管理、操作和扩展。

  微服务架构为应用程序本身的扩展提供了一个有效的模型,允许更大的、更不连贯的开发团队独立完成他们的部分工作,同时仍然参与大型应用程序的构建中。

  在一个典型的微服务架构中,单独的服务被创建,该服务包含了一个特定的业务逻辑子集。当相互连接时,整个微服务集形成一个完整的、大规模的应用程序,包含完整的业务逻辑。

  这种模式对代码来说是很好的,但对数据呢?通常,为特定业务逻辑创建单独服务的公司觉得有必要把所有的应用数据放到一个单一的、集中的数据存储中。这个想法是为了确保所有的数据对可能需要它的每个服务都是可用的。管理单个数据存储很容易,也很方便,而且数据建模对整个应用程序来说是一致的,与使用它的服务无关。

  不要这样做,集中你的数据是一个坏主意。这里有三个原因:

集中的数据很难扩展

  当整个应用程序的数据都在一个集中的数据存储中时,随着应用程序的增长,你必须扩展整个数据存储以满足应用程序中所有服务的需求。这显示在图1的左边。如果你为每个服务使用单独的数据存储,只有需求增加的服务需要扩展,而被扩展的数据库是一个较小的数据库。这在图1的右边显示。

  将小型数据库扩展到更大的规模要比将大型数据库扩展到更大的规模容易得多。 

图1. 按服务划分数据可以简化扩展

集中的数据以后很难分割

  新开发应用程序的开发者通常的想法是:“我现在不需要担心扩展的问题,在以后需要的时候再担心吧”。这种观点虽然很普遍,但在某些时候却会导致扩展问题。当应用程序变得流行时,你必须重新思考架构决策,以满足客户的增量需求。

  一个常见的架构变化是需要将你的数据存储分割成更小的数据存储。问题是,在应用程序刚创建时比在应用程序生命周期的后期更容易进行分割。当应用程序已经存在了几年,并且应用程序的所有部分都可以访问对应的数据时,要确定数据集的哪些部分可以被分割成一个单独的数据存储而不需要对使用数据的代码进行重大重写就变得非常困难。即使是简单的问题也变得很困难。哪些服务在使用Profiles表?是否有服务同时需要系统表和项目表?

  而且,更糟糕的是,是否有任何服务使用这两个表来执行连接?它的用途是什么?在代码中的什么地方完成的?我们怎样才能重构这种变化?

  一个数据集在一个数据存储中停留的时间越长,以后就越难把这个数据存储分成更小的部分。

  通过将数据按功能分成独立的数据存储,你可以避免以后将数据从连接的表中分离出来的相关问题,也可以减少代码中存在的数据之间意外关联的可能性。

集中的数据使数据所有权无法实现

  将数据划分为多个服务的一大优势是能够将应用所有权划分为不同的、可分离的部分。单个开发团队的应用程序所有权是现代应用开发的一个核心原则,它可以促进更好的组织扩展,并在问题发生时提高响应能力。这种所有权模式在面向单一团队的服务架构(STOSA)开发模式中进行了讨论。

  当你有大量的开发团队都在为一个大型的应用程序做贡献时,这种模式非常有效,但即使是有较小团队的小型应用程序也能从这种模式中受益。

  问题是,一个团队要拥有一个服务的所有权,他们必须同时拥有该服务的代码和数据。这意味着一个服务(服务A)不应该直接访问另一个服务(服务B)的数据。如果服务A需要存储在服务B中的东西,它必须调用服务B的一个服务入口点,而不是直接访问该数据。

图2. 服务A永远不应该直接访问服务B的数据

  这允许服务B对其数据、如何存储以及如何维护拥有完全的自主权。

  那么,有什么选择呢?当你构建面向服务的架构(SOA)时,每个服务应该拥有自己的数据。这些数据是服务的一部分,并被纳入服务中。

图3. 每个服务都有自己的数据

  这样,服务的所有者可以管理该服务的数据。如果需要对数据进行模式改变或其他结构性改变,服务所有者可以在没有任何其他服务所有者参与的情况下实现更改。随着应用程序(及其服务)的增长,服务所有者可以做出扩展决策和数据重构决策,以处理增加的负载和变化的需求,而无需其他服务所有者的参与。

  一个问题经常出现,那些真正需要在应用程序之间共享的数据怎么办?诸如用户配置文件数据,或其他在应用程序的许多常用的数据。一个诱人的快速解决方案可能是只在多个服务之间共享所需的数据,如图4所示。每个服务可能有它自己的数据,同时也可以访问共享的数据。

图4. 不建议在服务之间共享数据

  更好的方法是将共享数据放入一个由所有其他服务使用的新服务中,如图5所示。

图5. 使用服务是访问共享数据的正确方式

  服务C这一新的服务也应该遵循STOSA的要求。特别是,它应该有一个单一的、明确的团队来拥有该服务,从而拥有共享数据。如果任何其他服务,如图中的服务A或服务B,需要访问共享数据,它必须通过服务C提供的API来实现。这样,服务C的所有者是唯一负责共享数据的团队,可以就扩展、重构和更新方面做出适当的决策。只要维护一个一致的API供服务A和服务B使用,服务C就可以做出任何关于更新数据的决定。

  这与图4相反,图4中服务A和服务B都直接访问共享数据。在这个模型中,没有一个团队可以在不涉及直接访问数据的所有其他团队的情况下对数据的结构、布局、扩展或建模做出任何决定,这限制了应用程序开发过程的可扩展性。

  使用微服务或其他SOA是管理从事大型应用的大型开发团队的一个好方法。但是,服务架构也必须包含应用程序的数据,否则真正的服务独立性--也就是开发组织的扩展独立性--将不可能实现。

  作者:Lee Atchison是云计算和应用现代化领域公认的思想领袖。Lee在产品开发、架构、扩展和现代化方面有三十多年的经验,曾在亚马逊、亚马逊网络服务(AWS)、New Relic和其他现代应用组织工作。

0
相关文章