开源数据库Sharding技术[1]

开源数据库Sharding技术[1],第1张

从 Shard 到 Sharding

Shard 这个词英文的意思是 碎片 而作为数据库相关的技术用语 似乎最早见于大型多人在线角色扮演游戏(MMORPG)中的 Sharding 姑且称之为 分片

Sharding 不是一门新技术 而是一个相对简朴的软件理念 如您所知 MySQL 之后才有了数据表分区功能 那么在此之前 很多 MySQL 的潜在用户都对 MySQL 的扩展性有所顾虑 而是否具备分区功能就成了衡量一个数据库可扩展性与否的一个关键指标(当然不是唯一指标) 数据库扩展性是一个永恒的话题 MySQL 的推广者经常会被问到 如在单一数据库上处理应用数据捉襟见肘而需要进行分区化之类的处理 是如何办到的呢? 答案是 Sharding

Sharding 不是一个某个特定数据库软件附属的功能 而是在具体技术细节之上的抽象处理 是水平扩展(Scale Out 亦或横向扩展 向外扩展)的解决方案 其主要目的是为突破单节点数据库服务器的 I/O 能力限制 解决数据库扩展性问题

事关数据库扩展性

说起数据库扩展性 这是个非常大的话题 目前的商业数据都有自己的扩展性解决方案 在过去相对来说比较成熟 但是随着互联网的高速发展 不可避免的会带来一些计算模式上的演变 这样很多主流商业系统也难免暴露出一些不足之处 比如 Oracle 的 RAC 是采用共享存储机制 对于 I/O 密集型的应用 瓶颈很容易落在存储上 这样的机制决定后续扩容只能是 Scale Up(向上扩展) 类型 对于硬件成本 开发人员的要求 维护成本都相对比较高

Sharding 基本上是针对开源数据库的扩展性解决方案 很少有听说商业数据库进行 Sharding 的 目前业界的趋势基本上是拥抱 Scale Out 逐渐从 Scale Up 中解放出来

Sharding 的应用场景

任何技术都是在合适的场合下能发挥应有的作用 Sharding 也一样 联机游戏 IM BSP 都是比较适合 Sharding 的应用场景 其共性是抽象出来的数据对象之间的关联数据很小 比如IM 每个用户如果抽象成一个数据对象 完全可以独立存储在任何一个地方 数据对象是 Share Nothing 的 再比如 Blog 服务提供商的站点内容 基本为用户生成内容(UGC) 完全可以把不同的用户隔离到不同的存储集合 而对用户来说是透明的

这个 Share Nothing 是从数据库集群中借用的概念 举例来说 有些类型的数据粒度之间就不是 Share Nothing 的 比如类似交易记录的历史表信息 如果一条记录中既包含卖家信息与买家信息 如果随着时间推移 买 卖家会分别与其他用户继续进行交易 这样不可避免的两个买卖家的信息会分布到不同的 Sharding DB 上 而这时如果针对买卖家查询 就会跨越更多的 Sharding 开销就会比较大

Sharding 并不是数据库扩展方案的银d 也有其不适合的场景 比如处理事务型的应用就会非常复杂 对于跨不同DB的事务 很难保证完整性 得不偿失 所以 采用什么样的 Sharding 形式 不是生搬硬套的

Sharding与数据库分区(Partition)的区别

有的时候 Sharding 也被近似等同于水平分区(Horizontal Partitioning) 网上很多地方也用 水平分区来指代 Sharding 但我个人认为二者之间实际上还是有区别的 的确 Sharding 的思想是从分区的思想而来 但数据库分区基本上是数据对象级别的处理 比如表和索引的分区 每个子数据集上能够有不同的物理存储属性 还是单个数据库范围内的 *** 作 而 Sharding 是能够跨数据库 甚至跨越物理机器的

lishixinzhi/Article/program/SQL/201311/16326

2015年8月份内部release了Oracle 12.2 Beta版本(目前内部最新release的版本是2016年2月份发布的,windows和Linux都有了),目前根据12.2beta文档的介绍,Oracle推出了sharding的功能,跟其他NOSQL型的sharding结构相比,Oracle Sharding提供的是企业级的RDBMS的分片技术。

Oracle Sharding的优点:

? Relational schemas

? Database partitioning

? ACID properties and read consistency

? SQL and other programmatic interfaces

? Complex data types

? Online schema changes

? Multi-core scalability

? Advanced security

? Compression

? High Availability features

? Enterprise-scale backup and recovery

在Oracle RDBMS 12.2.0.1中最多支持1000个shards。

Oracle Sharding使用GDS(Global Data Services)架构来自动部署和管理sharding和复制技术。GDS(GDS是Oracle RDBMS 12.1的新特性)也提供负载均衡和SDB(sharded database)中的基于位置的路由功能。

Shard目录(Shard directors)使用GDS framework的全局服务管理组件(global service manager component)来提供应用层请求到shard的直接路由。shard目录(Shard directors)是一个单独的数据库,它用来保存SDB(Sharding database)配置数据和提供其他相关功能,比如shard的交叉查询和集中管理。可以使用GDS是GDSCTL工具可以用来配置SDB。

Oracle Sharding的分区架构(Partitioning Infrastructure)分区在表空间级别跨Shards分布,每个表空间关联一个特定的shard。一个shard表的每一个分区放单独的表空间,并且每个表空间关联到一个特定的shard。根据不同的sharding方法,这个关联可以自动建立或者根据定义创建。尽管一个shard表的多个分区放在多个单独主机的数据库上(这些数据库完全独立,不共享CPU、内存等软件和硬件),但是应用访问表时就如同访问一个单独数据库中的分区表一样。应用发出的SQL语句不需要依赖shard号和shard的物理配置。

Oracle Sharding 使用 familiar SQL 语法创建表分区,指定分区表的每行数据如何分片。

一个shard表的分区键叫做sharding key,例如,下面的语法是典型的用来创建sharding表的:

CREATE SHARDED TABLE customers

( cust_id NUMBER NOT NULL

, name VARCHAR2(50)

, address VARCHAR2(250)

, region VARCHAR2(20)

, class VARCHAR2(3)

, signup DATE

CONSTRAINT cust_pk PRIMARY KEY(cust_id)

)

PARTITION BY CONSISTENT HASH (cust_id)

TABLESPACE SET ts1

PARTITIONS AUTO

这个数据分片(shard)就是基于键值cust_id,分区采用“CONSISTENT HASH”,这是一个特定的hash分区类型,通常用在分布式系统上。

.

Sharding a Table Family

一个表家族(Table Family)中没有任何父表的表叫做根表(root table),每个表家族中只能有一个根表。

表家族中所有的表按照根表的主键进行sharding,根据各级表的结构,相关数据可以被存储在同一个shard上。

在12.2,在一个SDB中只支持一个表家族。

.

以下面的例子说明,这里一共3张表组成的表家族(Table Family):客户表,订单表和订单明细表。

每个客户可以有多个订单,每个订单中可以有多个商品,因此订单明细中就记录了每个订单中的多个商品,他们的具体数据如下:

在这个表族中,客户编号为123的数据如下:

将一个表族(Sharded Table Family)分片通常使有下面两种方法创建:

方法1:不显示指定父子关系,而是通过表之间主外键关系创建表族。

这种方式创建的表族是一个多级的树形结构。

根表(root table)是客户表:

–客户表的主键是CustNo,分区方式是“CONSISTENT HASH (CustNo)”

–保存再表空间集ts1中

CREATE SHARDED TABLE Customers ( CustNo NUMBER NOT NULL , Name VARCHAR2(50) , Address VARCHAR2(250) , CONSTRAINT RootPK PRIMARY KEY(CustNo) ) PARTITION BY CONSISTENT HASH (CustNo) PARTITIONS AUTO TABLESPACE SET ts1 –订单表是客户表的字表,子表(订单表)根据CustNo关联父表(客户表):

–订单表的主键是(CustNo, OrderNo),外键(CustNo)引用了主表Customers(CustNo)–分区方式是按照订单表的外键约束(CustFK)CREATE SHARDED TABLE Orders ( OrderNo NUMBER NOT NULL , CustNo NUMBER NOT NULL , OrderDate DATE , CONSTRAINT OrderPK PRIMARY KEY (CustNo, OrderNo) , CONSTRAINT CustFK FOREIGN KEY (CustNo) REFERENCES Customers(CustNo) ) PARTITION BY REFERENCE (CustFK) –订单明细表是订单表的字表,子表(订单明细表)根据CustNo关联父表(订单表)–订单明细表的主键是(CustNo, OrderNo, LineNo),外键(CustNo, OrderNo)引用了父表Orders(OrderNo)和Orders(CustNo, OrderNo)–分区方式是按照订单明细表的外键约束(LineFK)CREATE SHARDED TABLE LineItems ( CustNo NUMBER NOT NULL , LineNo NUMBER(2) NOT NULL , OrderNo NUMBER(5) NOT NULL , StockNo NUMBER(4) , Quantity NUMBER(2) , CONSTRAINT LinePK PRIMARY KEY (CustNo, OrderNo, LineNo) , CONSTRAINT LineFK FOREIGN KEY (CustNo, OrderNo) REFERENCES Orders(OrderNo) REFERENCES Orders(CustNo, OrderNo) ) PARTITION BY REFERENCE (LineFK) 因此,上面的例子中,这个表家族的所有数据都保存在同一个表空间集ts1中。当根表中增加一个分区的时候,那么相关联的表中都会自动增加相应的分区。

.

方法2:在分区表中显示指定父子关系的方法创建表家族这种分区方法只支持两级的表家族(two-level table families),所有的子表必须有相同的父表,父表的分区列在每个子表中都存在,例如下面的CustNo.

.

–没有关键字“PARENT”(也没有上面引用约束关键字)的是根表,即客户表(Customers)CREATE SHARDED TABLE Customers ( CustNo NUMBER NOT NULL , Name VARCHAR2(50) , Address VARCHAR2(250) , region VARCHAR2(20) , class VARCHAR2(3) , signup DATE ) PARTITION BY CONSISTENT HASH (CustNo) TABLESPACE SET ts1 PARTITIONS AUTO –根据关键字“PARENT Customers”指定了订单表(Orders)的父表是客户表(Customers)CREATE SHARDED TABLE Orders ( OrderNo NUMBER , CustNo NUMBER , OrderDate DATE ) PARENT Customers PARTITION BY CONSISTENT HASH (CustNo) TABLESPACE SET ts1 PARTITIONS AUTO –根据关键字“PARENT Customers”指定了订单明细表(LineItems)的父表是客户表(Customers)CREATE SHARDED TABLE LineItems ( LineNo NUMBER , OrderNo NUMBER , CustNo NUMBER , StockNo NUMBER , Quantity NUMBER ) ) PARENT Customers PARTITION BY CONSISTENT HASH (CustNo) TABLESPACE SET ts1 PARTITIONS AUTO Creating a Duplicated Table Using CREATE TABLE复制表可以被复制到所有的shard上,这种在每个shard上有相同内容的表叫做复制表(Duplicated Table),需要经常跟shard表关联的小表适合于作为复制表(Duplicated Table),适用于:

(1)只读表

(2)大量跨shard的读 *** 作

Oracle Sharding使用Materialized View Replication来同步复制表(duplicated tables)的内容,每个shard上的duplicated tables的内容是一个只读物化视图(read-only materialized view)。

物化视图(materialized views)的主表保存在一个专门的数据库中,叫做Shard Catalog。

所有shard上的物化视图(materialized views)会根据配置的频率自动刷新。

创建复制表的语句“CREATE DUPLICATED TABLE”会自动创建master表,物化视图和其他物化视图复制所需要的对象。

还是以上面的客户订单关系为例,这里定义产品表(Products)为复制表:

CREATE DUPLICATED TABLE Products ( StockNo NUMBER PRIMARY KEY , Description VARCHAR2(20) , Price NUMBER(6,2)) ) 根据sharding的机制,sharding的设计对后续系统性能影响是非常大的。一旦sharding创建完成,并已经有很多数据,相关的属性就不能再修改了,比如某个表是复制表,还是sharding表,sharding key等等,因此,SDB的设计是至关重要的,在设计sharding时需要考虑的有:

哪些表需要被设计为sharding表;

哪些表需要做复制表;

哪些shard表是根表;

使用什么方法来关联一个表到其他表或者根表;应该使用哪种sharding方法;

使用哪个作为sharding key;


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/6624998.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-25
下一篇 2023-03-25

发表评论

登录后才能评论

评论列表(0条)

保存