关系数据库分片原则

本文主要讨论了两种数据库分片方式,基于业务的自然分表法和基于微服务的分片法。其实微服务的切分依据还是要首先找出业务数据的DDD聚合才能切分。

当数据库数据量很小时,很多问题可以通过硬件进行扩展。然而,随着数据表数量的增长,就需要考虑其他扩展数据库的方法了。

在某种程度上,分片Sharding是最好的扩展方式。分片让你将数据库切分成较小的部分,以实现数据库cpu、内存和磁盘资源的线性扩展。但是,分片是一个有争议性的话题。互联网上有关于分片截然相反的建议,从“ 将数据库基础设施扩展到必要”到“ 为什么你不要分片”。那么问题来了,你到底应该采纳哪个建议呢?

什么时候需要分片?答案是“依赖于具体情况”。

分片理论很简单:选择一个能均匀分布数据的键key(列)。确保大部分查询可以被该key定位到。这个理论很简单,但一旦你将其落地到你的数据库,实践问题就变得凌乱了。

在Citus,我们帮助了数百个团队研究如何分片数据库。在这个过程中发现了一些关键模式。

分片的成功取决于三个关键属性

三个关键属性会影响项目的成功:

1. 工作负载类型。从事务机制到CRUD到数据仓库。伸缩扩展时,这个维度是最被认可的。

2. 应用程序生命周期。您的数据库中有多少张表(10?,100?,1000?)或您的应用程序在生产环境中运行有多长时间?在PostgreSQL上运行几个月的应用程序将比运行很多年的应用程序更容易分片。

当您有成熟的应用程序时,这个因素变得至关重要。可悲的是,这个维度与其他两个方面并不一致。事实上,大多数关于分片文章之所以得出相互矛盾的结论,是因为他们都是基于特定的一种应用上下文中提供的建议。

3.最重要的是:应用类型(B2B或B2C)

B2B的数据模型更适合分片。B2C应用程序,如亚马逊和Facebook,分片则需要花费更多工作。接下来,我们选择三家知名公司,谈论他们的差异。

B2B示例:Salesforce

B2B应用的一个很好例子是CRM客户管理软件(Salesforce)。比如GE航空将成为Salesforce客户。

在GE航空公司,有以下几个数据表:
1. user是登陆用户表
2. leads 是需要直接做生意的人员
3. contacts 代表生意关系
4. account代表有业务关系的

这几个表看起来很复杂。如果你花更多的时间来研究它,那么你会发现大多数表来自于customer表。你可以向这些表添加customer_id列,就是这么简单的变化,您的数据库现在有了一个很好的分片键:customer_id。该分片键通常分布均匀; 并且对数据库的大多数查询都会使用customer_id。

换句话说,如果您是B2B应用程序,业务数据的性质可以为您提供分片的基本优势。

B2C示例:Amazon.com

Amazon.com是成熟B2C应用程序的一个很好的例子。如果您自己来建立Amazon.com网站,您可以考虑下面流程:

首先,用户来到您的网站可以查看您提供的产品,如书籍或电子产品。当用户访问产品页面时,他们会看到与该产品相关的目录信息。

当您的用户登录到您的网站时,他们就开始访问与用户相关的数据。用户需要进行身份验证,可以写评论他们喜爱的产品,并可以添加产品项目到他们的购物车。用户决定购买商品会下订单。订单处理完成,仓库发送货物。

这里涉及几个数据表:
1.catalog 是产品目录表
2.user是用户表
3.order是订单表
4.shipment是货运表

当您要分片这些B2C数据类型时,其中一个解决方式是将您的应用程序重构为微服务。例如,提供catalog目录数据的与目录相关服务,以及拥有身份验证和购物车数据的用户相关服务。每个微服务只能访问它们自己的数据库,因此这些服务之间边界其实定义了访问底层数据的边界。

这种分片方法与分割B2B应用程序在成本上相比是有明显的不同。


Principles of Sharding for Relational Databases