循序漸進: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 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 AUTOTABLESPACE 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 ts1PARTITIONS AUTO; |
–根據關鍵字“PARENT Customers”指定了訂單表(Orders)的父表是客戶表(Customers)
CREATE SHARDED TABLE Orders( OrderNo NUMBER, CustNo NUMBER, OrderDate DATE)PARENT CustomersPARTITION BY CONSISTENT HASH (CustNo)TABLESPACE SET ts1PARTITIONS AUTO; |
–根據關鍵字“PARENT Customers”指定了訂單明細表(LineItems)的父表是客戶表(Customers)
CREATE SHARDED TABLE LineItems( LineNo NUMBER, OrderNo NUMBER, CustNo NUMBER, StockNo NUMBER, Quantity NUMBER))PARENT CustomersPARTITION BY CONSISTENT HASH (CustNo)TABLESPACE SET ts1PARTITIONS 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;
文章轉自數據和雲公眾號,原文鏈接
最後更新:2017-07-18 11:03:34