天天看點

循序漸進:Oracle 12.2的Sharding基礎概念解讀

循序漸進:Oracle 12.2的Sharding基礎概念解讀

張大朋(lunar)oracle 工程師

lunar 擁有超過十年的 oracle support 從業經驗,曾經服務于oracle acs部門,現就職于 oracle sales consultant 部門,負責的産品主要是 exadata,golden gate,database 等。

編輯說明:感謝lunar授權我們轉載其原創文章,文章插入了一些我們以前分享的圖檔,作為配合解讀。

2015年8月份内部release了oracle 12.2 beta版本(目前内部最新release的版本是2016年2月份釋出的,windows和linux都有了),目前根據12.2beta文檔的介紹,oracle推出了sharding的功能,跟其他nosql型的sharding結構相比,oracle sharding提供的是企業級的rdbms的分片技術。

循序漸進:Oracle 12.2的Sharding基礎概念解讀

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)中的基于位置的路由功能。

循序漸進:Oracle 12.2的Sharding基礎概念解讀

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):客戶表,訂單表和訂單明細表。

每個客戶可以有多個訂單,每個訂單中可以有多個商品,是以訂單明細中就記錄了每個訂單中的多個商品,他們的具體資料如下:

循序漸進:Oracle 12.2的Sharding基礎概念解讀

在這個表族中,客戶編号為123的資料如下:

循序漸進:Oracle 12.2的Sharding基礎概念解讀

将一個表族(sharded table family)分片通常使有下面兩種方法建立:

方法1:不顯示指定父子關系,而是通過表之間主外鍵關系建立表族。

這種方式建立的表族是一個多級的樹形結構。

根表(root table)是客戶表:

–客戶表的主鍵是custno,分區方式是“consistent hash (custno)”

–儲存再表空間集ts1中

<code>create sharded table customers</code>

<code>( custno number not null</code>

<code>, name varchar2(50)</code>

<code>, address varchar2(250)</code>

<code>, constraint rootpk primary key(custno)</code>

<code>)</code>

<code>partition by consistent hash (custno)</code>

<code>partitions auto</code>

<code>tablespace set ts1</code>

<code>;</code>

–訂單表是客戶表的字表,子表(訂單表)根據custno關聯父表(客戶表):

–訂單表的主鍵是(custno, orderno),外鍵(custno)引用了主表customers(custno)

–分區方式是按照訂單表的外鍵限制(custfk)

<code>create sharded table orders</code>

<code>( orderno number not null</code>

<code>, custno number not null</code>

<code>, orderdate date</code>

<code>, constraint orderpk primary key (custno, orderno)</code>

<code>, constraint custfk foreign key (custno) references customers(custno)</code>

<code>partition by reference (custfk)</code>

–訂單明細表是訂單表的字表,子表(訂單明細表)根據custno關聯父表(訂單表)

–訂單明細表的主鍵是(custno, orderno, lineno),外鍵(custno, orderno)引用了父表orders(orderno)和orders(custno, orderno)

–分區方式是按照訂單明細表的外鍵限制(linefk)

<code>create sharded table lineitems</code>

<code>, lineno number(2) not null</code>

<code>, orderno number(5) not null</code>

<code>, stockno number(4)</code>

<code>, quantity number(2)</code>

<code>, constraint linepk primary key (custno, orderno, lineno)</code>

<code>, constraint linefk foreign key (custno, orderno) references orders(orderno)</code>

<code>references orders(custno, orderno)</code>

<code>partition by reference (linefk)</code>

是以,上面的例子中,這個表家族的所有資料都儲存在同一個表空間集ts1中。

當根表中增加一個分區的時候,那麼相關聯的表中都會自動增加相應的分區。

方法2:在分區表中顯示指定父子關系的方法建立表家族

這種分區方法隻支援兩級的表家族(two-level table families),所有的子表必須有相同的父表,父表的分區列在每個子表中都存在,例如下面的custno.

–沒有關鍵字“parent”(也沒有上面引用限制關鍵字)的是根表,即客戶表(customers)

<code>, region varchar2(20)</code>

<code>, class varchar2(3)</code>

<code>, signup date</code>

–根據關鍵字“parent customers”指定了訂單表(orders)的父表是客戶表(customers)

<code>( orderno number</code>

<code>, custno number</code>

<code>parent customers</code>

–根據關鍵字“parent customers”指定了訂單明細表(lineitems)的父表是客戶表(customers)

<code>( lineno number</code>

<code>, orderno number</code>

<code>, stockno number</code>

<code>, quantity number</code>

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)為複制表:

循序漸進:Oracle 12.2的Sharding基礎概念解讀

<code>create duplicated table products</code>

<code>( stockno number primary key</code>

<code>, description varchar2(20)</code>

<code>, price number(6,2))</code>

根據sharding的機制,sharding的設計對後續系統性能影響是非常大的。一旦sharding建立完成,并已經有很多資料,相關的屬性就不能再修改了,比如某個表是複制表,還是sharding表,sharding key等等,是以,sdb的設計是至關重要的,在設計sharding時需要考慮的有:

哪些表需要被設計為sharding表; 哪些表需要做複制表; 哪些shard表是根表; 使用什麼方法來關聯一個表到其他表或者根表; 應該使用哪種sharding方法; 使用哪個作為sharding key;