• 循序渐进:Oracle 12c新特性Sharding技术解读


    640?wx_fmt=gif

    作者简介

    640?wx_fmt=png邝志辉

    4年 ORACLE SSC(方案解决中心)高级工程师工作经验,6年 ORACLE Exadata 一体机产品维护经验;8年大型数据库运维经验,曾负责华为、工商银行、广东移动、中国信托、富邦证券等大客户的核心系统数据库维护;现任云和恩墨技术专家,在数据库疑难故障诊断、数据库架构设计、数据迁移、升级、核心系统运维方面有丰富经验。


    本文由恩墨大讲堂151期线上分享整理而成。课程回看可点击文末“阅读原文”。 

    引言


    数据库构架设计中主要有 Shared Everthting、Shared Nothing 和 Shared Disk:


    • Shared Everthting:一般是针对单个主机,完全透明共享 CPU/MEMORY/IO,并行处理能力是最差的,例如 Oracle 的单机模式。

    • Shared Disk:各个处理单元使用自己的私有 CPU和 Memory,共享磁盘系统。典型的代表 Oracle RAC, 它是数据共享,可通过增加节点来提高并行处理的能力,扩展能力较好。其类似于 SMP(对称多处理)模式,但是当存储器接口达到饱和的时候,增加节点并不能获得更高的性能 。

    • Shared Nothing:各个处理单元都有自己私有的 CPU / 内存 / 硬盘等,不存在共享资源,类似于 MPP(大规模并行处理)模式,各处理单元之间通过协议通信,并行处理和扩展能力更好。 各节点相互独立,各自处理自己的数据,处理后的结果可能向上层汇总或在节点间流转。


    我们常说的 Sharding 其实就是 Share Nothing 架构,它是把某个表从物理存储上被水平分割,并分配给多台服务器(或多个实例),每台服务器可以独立工作,具备共同的 schema,只需增加服务器数就可以增加处理能力和容量。

    Oracle Sharding 简介


    Oracle Sharding 是 Oracle 12.2 版本推出的新功能,也称为数据分片,适用于 online transaction processing (OLTP)。Oracle Sharding 基于表分区技术,是一种在数据层将数据水平分区存储到不同的数据库的技术。Sharding 可以实现将一个分区表的不同分区存储在不同的数据库中,每个数据库位于不同的服务器,每一个数据库都称为shard,这些 shard 组成一个逻辑数据库,称为 sharded database (SDB)。这个 table 也称为 sharded table,每个 shard 数据库中保存该表的不同数据集(按照 sharding key 分区),但是他们有相同的列 (columns)。


    Shard 是一种 shared-nothing 技术,每个 shard 数据库使用独立的服务器硬件 (CPU、内存等)。Shard 可以运行在单机数据库或者 DATAGUARD / ADG 数据库。

     

    Sharding 其实需要解决三个问题:

    1. 数据的路由

      数据路由是数据库告诉应用程序,你让我查的数据目前在哪个分片上,这条路怎么走过去。

    2. 数据的分片

      数据分片就是实际数据的存放地点,往往每个分片就是一台单独的服务器(含存储)。

    3. 分片的元数据信息保存

      由于分片的数据实际是被切割放在不同的机器上,那么需要有个集中的地点存放数据分片的信息,即分片元数据的信息。


    640?wx_fmt=png

    Oracle Sharding 组成


    Oracle Sharding 主要包括下面组件:


    • Sharded database (SDB):逻辑上 SDB 是一个数据库,但是物理上SDB包括多个物理独立的数据库,SDB 类似一个数据库池 (pool),数据库池 (pool) 中包括多个数据库 (Shard)。目前版本最大支持1000个 shard。

    • Shards:SDB 包括多个物理独立的数据库,每一个数据库都称为shard,每个 shard 数据库位于不同的服务器,他们不共享 CPU、内存、存储等资源。每个shard 数据库中保存表的不同数据集, 但是每个 shard 中都有相同的列(columns)。Shard 数据库可以是 Dataguard / ADG,提供高可用性,Shard 数据库(单机或者 ADG)可以通过 GSM deploy 来自动创建,也可以将一个已经通过 dbca 创建好的数据库 add 到 SDB。

    • Shard catalog:是一个 Oracle 数据库,用于集中存储管理 SDB 配置信息,是 SDB 的核心。SDB 配置变化,比如添加/删除 shard,Globalservice 等等,都记录在 Shard catalog。如果应用查询多个 shard 中的数据,那么由 Shard catalog统一协调分配。我们推荐将 Shard catalog 配置为 dataguard 环境,这样可以提供 HA 高可用。如果 Shard catalog 无法访问,那么只会影响一些维护操作和跨shard访问,而不会影响单独的 shard 操作(通过 sharding key 的查询 /DML)。

    • Shard directors:Global Data Service (GDS) 实现对 Sharding 的集中部署和管理。GSM 是 GDS 的核心组件。GSM 作为 Shard director。GSM 类似于监听器,将客户端对 SDB 的请求路由到对应的 shard,负载均衡客户端的访问。

    • Shardgroup:在逻辑上,将一组相同复制属性的 shard 称作 shard group。如有8台主机,其中4台是 shard node 的 primary,另外4台是 shard node 的 standby。那么,我们可以把4台 primary 定义成一个shardgroup,叫 primary_shardgroup,另外4台 standby 定义成另外一个shardgroup,叫 standby_shardgroup。

      注:一个 shardgroup 通常是在一个 datacenter 内。

      Dataguard 可以级联,那么我们可以把 primary 做为一个 shardgroup1,第一级的 dataguard 叫 shardgroup2,第二级的 dataguard 叫 shardgroup2。如下:

    640?wx_fmt=png

    • shardspace shardspace 的概念伴随着综合性分片的分片方法(compositesharding method)出现的;如果是系统管理分片方法(system-managed shardingmethod),只有一个默认的 shardspace。所以只有在 compositesharding 下,才有可能出现多个 shardspace。


    在 composite sharding 下,数据首先根据 list 或者 range,分成若干个shardspace。然后再根据一致性 hash 进行分片。

    注:每个 shardspace 包含一个或者多个复制 shard for HA/DR。


    640?wx_fmt=png

    我们可以按照服务级别来划分 shardspace,如硬件好的,作为 shardspace_gold,硬件差一些的,划做 shardspace_silver:

    640?wx_fmt=png

    Oracle Sharding 方法


    Oracle Sharding 支持3种方法 shard / 分片方法:


    • System-Managed Sharding:这种方法用户不用指定数据存放在哪个 shard 中。Sharding 通过一致性哈希 (CONSISTENT HASH) 方法将数据分区 (partitioning),并自动分布在不同的 Shard。System-managed sharding 只能有一个shardspace。

      640?wx_fmt=png

    • Composite Sharding:这种方法用户创建多个 shardspaces ,每个 shardspaces 中存放一定范围 (range) 或者列表 (list) 的数据。一般情况下,Shardspace 按照区域来划分,比如美国区域的 shard 属于 shardspace cust_america,欧洲的 shard 属于 shardspace cust_europe。

    • Subpartitions with Sharding:Sharding 基于表分区,因此子分区 (Subpartitions) 技术同样适用于 Sharding

    Oracle Sharding 对象


    被 Shard/分片的表我们成为 shardedtable,这些 sharded table 的集合称为表家族(TableFamily)。


    所谓表家族(Table Family)就是指 sharded table 之间是父-子关系,一个表家族(Table Family)中没有任何父表的表叫做根表(root table),每个表家族中只能有一个根表。


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


    在表家族(Table Family)中的所有 sharded table 都按照相同的 sharding key (主键)来分片,主要是由 root table 的 shardingkey 决定的。表家族(Table Family)中有相同 shardingkey 的数据存储在同一个 Chunk 中,这样方便以后的数据移动。


    比如: 用户表 – 订单表 – 订单明细表 就是一个表家族,其中用户表是 root table,订单表和订单明细表分别是子表,他们都按照 sharding key (CustNo ) 分区。


    640?wx_fmt=png

    可以通过如下两种方式建立 table family:

    通过CONSTRAINT [FK_name] FOREIGN KEY(FK_column) REFERENCES [R_table_name]([R_table_column]) —这种关系可以有级联关系。


    SQL> CREATE  SHARDED TABLE Customers

      2  (

      3  CustId  VARCHAR2(60) NOT NULL,

      4  FirstName  VARCHAR2(60),

      5  LastName  VARCHAR2(60),

      6  Class  VARCHAR2(10),

      7  Geo  VARCHAR2(8),

      8  CustProfile  VARCHAR2(4000),

      9  Passwd  RAW(60),

    10  CONSTRAINT  pk_customers PRIMARY KEY (CustId),

    11  CONSTRAINT  json_customers CHECK (CustProfile IS JSON)

    12  )  TABLESPACE SET TSP_SET_1

    13  PARTITION  BY CONSISTENT HASH (CustId) PARTITIONS AUTO;


    可以看到上面根表(root table)是 customer 表,主键是 CustId,partition 是根据 CONSISTENT HASH,对 CustId 进行分区;


    下一级的表是 order 表,主键是 CustId+OrderId,外键是 CustId 且 references Customers 表,partition 是参考外键;


    SQL> CREATE  SHARDED TABLE Orders

      2  (

      3  OrderId  INTEGER NOT NULL,

      4  CustId  VARCHAR2(60) NOT NULL,

      5  OrderDate  TIMESTAMP NOT NULL,

      6  SumTotal  NUMBER(19,4),

      7  Status  CHAR(4),

      8  constraint  pk_orders primary key (CustId, OrderId),

      9  constraint  fk_orders_parent foreign key (CustId)

    10  references  Customers on delete cascade

    11  ) partition  by reference (fk_orders_parent);


    再下一级表是 LineItems 表,主键是 CustId+OrderId+ProductId,外键是 CustId+OrderId,即上一层表达主键,partition 是参考外键

     

    SQL> CREATE  SHARDED TABLE LineItems

      2  (

      3  OrderId  INTEGER NOT NULL,

      4  CustId  VARCHAR2(60) NOT NULL,

      5  ProductId  INTEGER NOT NULL,

      6  Price  NUMBER(19,4),

      7  Qty  NUMBER,

      8  constraint  pk_items primary key (CustId, OrderId, ProductId),

      9  constraint  fk_items_parent foreign key (CustId, OrderId)

    10  references  Orders on delete cascade

    11  )  partition by reference (fk_items_parent);


    方法2:同关键字 PARENT 来显式的说明父子关系。这种关系只有父子一层关系,不能级联。

     

    SQL>  CREATE  SHARDED TABLE Customers

    2  (  CustNo NUMBER NOT NULL

    3  , Name  VARCHAR2(50)

    4  ,  Address VARCHAR2(250)

    5  ,  region VARCHAR2(20)

    6  , class  VARCHAR2(3)

    7  ,  signup DATE

    8  )

    9  PARTITION  BY CONSISTENT HASH (CustNo)

    10 TABLESPACE SET  ts1

    11 PARTITIONS AUTO

    12 ;

     

    SQL> CREATE  SHARDED TABLE  Orders          

    2  (  OrderNo  NUMBER                      

    3  ,  CustNo  NUMBER                      

    4  ,  OrderDate  DATE                      

    5  )                                    

    6  PARENT  Customers                      

    7  PARTITION  BY CONSISTENT HASH (CustNo)

    8  TABLESPACE  SET  ts1                    

    9  PARTITIONS  AUTO                      

    10 ;

     

    SQL> CREATE  SHARDED TABLE LineItems

    2  (  LineNo NUMBER

    3  ,  OrderNo NUMBER

    4  ,  CustNo NUMBER

    5  ,  StockNo NUMBER

    6  ,  Quantity NUMBER

    7  )

    8  PARENT  Customers

    9  PARTITION  BY CONSISTENT HASH (CustNo)

    10 TABLESPACE SET  ts1

    11 PARTITIONS AUTO

    12 ;


    • 注意上面的 order 表和 LineItems 表,都是属于同一个父表,即 customers 表。

    • 另外,也注意上面的 CustNo 字段,在每个表中都是有的。而上面说的第一种的级联关系的 tablefamily,可以不在每个表中都存在 CustNo 字段。

     

    上面创建在表,都是 sharded table,即表的各个分区,可以分布在不同的 shard node 上。各个 shard node 上的分区,是不同的。即整个表的内容,是被切割成片,分配在不同的机器上的。


    而 duplicatedtable,是整个表达同样内容,在各个机器上是一样的。duplicate table 在各个 shard node上,是以 read only mv 的方式呈现:在 shardcat 中,存在 mast table;在各个shard中,存在 read only mv。duplicated table 的同步:以物化视图的方式同步。

    640?wx_fmt=png

    chunk


    chunk 的概念和 table family 密不可分。因为 family 之间的各个表都是有关系的,我们把某个 table family 的一组分区称作一个 chunk。


    如 customers 表中的1号~100万号客户信息在一个分区中;在 order 表中,也有1号~100万号的客户的 order 信息,也在一个分区中;另外 LineItems 表中的1号~100万号客户的明细信息,也在一个分区中,我们希望这些相关的分区,都是在一个 shard node 中,避免 cross shard join。所以,我们把这些在同一个 table family 内,相关的分区叫做 chunk。在进行 re-sharding 的时候,是以 chunk 为单位进行移动。因此可以避免 cross shard join。


    640?wx_fmt=png


    注:chunk 的数量在 CREATESHARDCATALOG 的指定,如果不指定,默认值是每个shard 120个chunk

    chunk move


    chunk move 的条件:

    1. re-sharding 发生,即当 shard 的数量发生改变的时候,会发生 chunk move。
      注:re-sharding 之后,chunk 的数虽然平均,但并不连续。

      如:原来是2个 shard,1~6号 chunk在 shard 1,7~12号 chunk 在 shard2。加多一个 shard 后,1~4号 chunk 在 shard 1,7~10号 chunk 在 shard 2,那么5~6,11~12号 chunk 在 shard 3 上。即:总是挪已经存在的 shard node 上的后面部分 chunk。

    2. DBA 手工发起:move chunk-chunk 7 -source sh2 -target sh1。将 chunk 7 从 shard node sh2 上,挪到 shard node sh1 上。


    chunk move 的过程:

    在 chunk migration 的时候,chunk 大部分时间是 online 的,但是期间会有几秒钟的时间 chunk 中的 data 处于 read-only 状态。

    chunk migration 的过程就是综合利用 rman 增量备份和 TTS 的过程:
    level 0 备份源 chunk 相关的 TS,还原到新 shard->开始 FAN(等待几秒)->将源 chunk 相关的 TS 置于 read-only->level 1 备份还原->chunk up(更新 routing table 连新 shard)->chunk down(更新 routing table 断开源 shard)->结束 FAN(等待几秒)->删除原 shard 上的老 chunk

    Oracle Sharding 路由选择(Routing)


    --直接路由
    应用程序初始化时,在应用层/中间件层建立连接池,连接池获取所有 shard 节点的sharding key 范围,并且保存在连接池中,形成 shard topologycache(拓扑缓存),Cache 提供了一个快速的方法直接将请求路由到具体的 shard。


    客户端请求时指定 shard key,直接从连接池获取连接,这种情况下不经过 shard  director / catalog 数据库,直接连接到对应的 shard。


    --代理路由
    如果客户端执行 select 或者DML 时不指定 shard key 或者执行聚合操作(比如groupby),那么请求发送到 Catalog 数据库,根据 matadata 信息,SQL 编译器决定访问哪些 shards。

     

    为了实现 sharding,Oracle 在连接池和驱动方面都做了增强,提供了新的 API(UCP, JDBC, OCI 等等)在连接创建时来传递 sharding keys。

    Sharding 技术的优点和缺点


    • 增加了 SQL 的复杂性

      因为开发人员必须要写更复杂的 SQL 来处理 sharding 的逻辑。

    • Sharding 本身带来的复杂性

      sharding 软件需要照顾分区,数据平衡, 访问协调,数据完整性

    • 单点故障

      一个 shard 损坏可能导致整张表不可访问。失效接管服务器也更复杂。因为负责失效接管的服务器必须拥有任何可能损坏的 shard 上的数据。

    • 备份也更复杂

      多个 shard 可能都需要同时备份。

    • 维护也更复杂

      比如增加删除索引,增减删除字段,修改表定义等等,都变得更困难

    • 商业 sharding 技术随着节点数的增加,Licensing 费用也会大规模增加

     

    在 Oracle12.2 Sharding 中都无需担心,Oracle 作为一个商业数据库,已通过底层开发规避了这些问题。


    单点故障问题可以通过 RAC+Sharding,ADG+Sharding 来规避,但成本也会增加。

     

    Oracle Sharding 技术提供线性扩展和失败隔离的优点

    • 线性扩展

      因为每个 shard 是一个独立的数据库,通过增加新的 Shard 节点,来线性扩展性能。自动 rebalance 数据。

    • 失败隔离

      由于 Shard 是一种 shared-nothing 技术,每个 shard 使用独立的硬件,因此一个 shard 节点出现故障,只会影响到这个 shard 存放的数据,而不会影响到其他shard。

    • 按照地理位置分布数据

      可以选择根据地理位置不同,将数据存储在不同的 shard。

    • 滚动升级

      选择不同时间升级不同的 shard。比如同一时间只升级一个或一部分 shard,那么只有这些升级的 shard 中存储的数据受到影响,其他的 shard 不受到影响,可以继续提供服务。

    • 云部署

      Shard 非常适合部署在 cloud


    资源下载

    关注公众号:数据和云(OraNews)回复关键字获取

    ‘2017DTC’,2017 DTC 大会 PPT

    ‘DBALIFE’,“DBA 的一天”海报

    ‘DBA04’,DBA 手记4 经典篇章电子书

    ‘RACV1’, RAC 系列课程视频及 PPT

    ‘122ARCH’,Oracle 12.2 体系结构图

    ‘2017OOW’,Oracle OpenWorld 资料

    ‘PRELECTION’,大讲堂讲师课程资料

    640?wx_fmt=png


    640?wx_fmt=gif  戳原文,回看视频课程!

  • 相关阅读:
    Asp.Net Core 2.0 项目实战(7)MD5加密、AES&DES对称加解密
    Asp.Net Core 2.0 项目实战(8)Core下缓存操作、序列化操作、JSON操作等Helper集合类
    Java后端开发-SSM框架的图片上传
    个人作业——软件工程实践总结&个人技术博客
    个人作业——软件评测
    结对第二次作业——某次疫情统计可视化的实现
    结对第一次—疫情统计可视化(原型设计)
    软工实践寒假作业(2/2)
    my codestyle
    alibaba-java-style-guide
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13312416.html
Copyright © 2020-2023  润新知