Database数据库切片模式
数据库切片模式关注的实现水平伸缩。切分是从单个数据库到平分数据访问两个或更多数据库切片。每个切片有和原始数据库相同的Schema。大多数据分布在每个切片每一行。从切片合并起来的数据和原始数据库一样。切片也被近似等同于水平分区(Horizontal Partitioning),网上很多地方也用水平分区来指代切片,二者之间实际上还是有区别的。的确,切片 的思想是从分区的思想而来,但数据库分区基本上是数据对象级别的处理,比如表和索引的分区,每个子数据集上能够有不同的物理存储属性,还是单个数据库范围内的操作,而切片是能够跨数据库,甚至跨越物理机器的。
上下文(Context)
数据库切片有效应对下面的挑战:
- 应用数据库查询超过单个数据库结点的查询能力.
- 应用数据库更新超过单个数据库事务处理能力,导致不可接受相应时间或超时。
- 应用数据库网络带宽超过单个数据库结点的带宽页导致不可接受相应时间或超时。
- 应用数据库存储需求已超过单个数据库结点容量。
机制
传统(非共享)数据库部署在单个服务器结点上。任何数据库运行在单个结点受限于当前结点容量。争夺的资源如CPU,内存,磁盘速度,数据尺寸,和网络带宽能损害数据库能力来处量相关的数据库活动。过分的争夺还可能使数据库承受不了。当单个结点不再够用时有很多潜在的方法为了实现一个应用数据库伸缩。一些例子包括:分布式查询加载到从结点,按数据类型拆分到多个数据库与垂直伸缩的数据库服务器。处理查询加载(非写/更新),从结点是从主数据复制;从结点是只读与典型事务一致。另一个选项是按数据类型拆分到多个数据库,如存货清单数据在一个数据库中,雇员数据在另一个数据库中。每个结点包含数据子集叫做切片。总体地,所有切片中数据呈现一个完整逻辑数据库。在数据库服务继承切片时,切片集合出现在单个数据库连接字符串中。这个抽象很好简化了应用程序编程模型。
如上图所示,数据行分布到切片,维护着相同的结构,上面一个切片存储id=1,2,另一个存储id=3,4,5的记录。
切分和策略
像很多其他技术一样,进行切分时也需要作出部分妥协。因为切片不是一项本地数据库技术 — 也就是说,必须在应用程序中实现 —在开始切片之前需要制定出您的切分策略。进行切分时主键和跨切分查询都扮演重要角色,主要通过定义您不可以做什么实现。
主键
切片利用多个数据库,其中所有数据库都独立起作用,不干涉其他切片。因此,如果您依赖于数据库序列(如自动主键生成),很有可能在一个数据库集中将出现同一个主键。可以跨分布式数据库协调序列,但是这样会增加系统的复杂程度。避免相同主键最安全的方法就是让应用程序(应用程序将管理切分系统)生成主键。
跨切片查询
大部分切分实现不支持跨切片查询,这就意味着,如果您想利用不同切分的两个数据集,就必须处理额外的长度。(有趣的是,Amazon 的 SimpleDB 也禁止跨域查询)例如,如果将美国客户信息存储在切片1中,还需要将所有相关数据存储在此。如果您尝试将那些数据存储在切片2中,情况就会变得复杂,系统性能也可能受影响。这种情况还与之前提到的一点有关 — 如果您因为某种原因需要进行跨切分连接,最好采用一种可以消除重复的方式管理键!
很明显,在建立数据库前必须全面考虑切分策略。一旦选择了一个特定的方向之后,您差不多就被它绑定了 — 进行切分后很难随便移动数据了。
一个策略示例
因为切分将您绑定在一个线型数据模型中(也就是说,您无法轻松连接不同切分中的数据),您必须对如何在每个切分中对数据进行逻辑组织有一个清晰的概念。这可以通过聚焦域中的主要节点实现。如在一个电子商务系统中,主要节点可以是一个订单或者一个客户。因此,如果您选择 “客户” 作为切分策略的节点,那么与客户有关的所有数据将移动至各自的切分中,但是您仍然必须选择将这些数据移动至哪个切分。对于客户来说,您可以根据所在地(欧洲、亚洲、非洲等)切分,或者您也可以根据其他元素进行切分。这由您决定。但是,您的切分策略应该包含将数据均匀分布至所有切分的方法。切分的总体概念是将大型数据集分割为小型数据集;因此,如果一个特定的电子商务域包含一个大型的欧洲客户集以及一个相对小的美国客户集,那么基于客户所在地的切分可能没有什么意义。
注意
比如类似交易记录的历史表信息,如果一条记录中既包含卖家信息与买家信息,如果随着时间推移,买、卖家会分别与其它用户继续进行交易,这样不可避免的两个买卖家的信息会分布到不同的数据库切片上,而这时如果针对买卖家查询,就会跨越更多的切片,开销就会比较大。
切片并不是数据库扩展方案的银弹,也有其不适合的场景,比如处理事务型的应用就会非常复杂。对于跨不同DB的事务,很难保证完整性,得不偿失。
在进行切分之前,一定要确定应用程序的规模和增长对其有利。切分的成本(或者说缺点)包括对如何存储和检索数据的特定应用程序逻辑进行编码的成本。进行切分后,您多多少少都被锁定在您的切分模型中,因为重新切分并非易事。
如果能够正确实现,切分可以用于解决传统 RDBMS 规模和速度问题。切分对于绑定于关系基础架构、无法继续升级硬件以满足大量可伸缩数据存储要求的组织来说是一个非常成本高效的决策。