4年 ORACLE SSC(方案解決中心)高級工程師工作經(jīng)驗,,6年 ORACLE Exadata 一體機產(chǎn)品維護經(jīng)驗;8年大型數(shù)據(jù)庫運維經(jīng)驗,曾負責華為,、工商銀行、廣東移動,、中國信托,、富邦證券等大客戶的核心系統(tǒng)數(shù)據(jù)庫維護;現(xiàn)任云和恩墨技術(shù)專家,,在數(shù)據(jù)庫疑難故障診斷,、數(shù)據(jù)庫架構(gòu)設計、數(shù)據(jù)遷移,、升級,、核心系統(tǒng)運維方面有豐富經(jīng)驗。
本文由恩墨大講堂151期線上分享整理而成,。課程回看可點擊文末“閱讀原文”,。 數(shù)據(jù)庫構(gòu)架設計中主要有 Shared Everthting、Shared Nothing 和 Shared Disk:
Shared Everthting:一般是針對單個主機,,完全透明共享 CPU/MEMORY/IO,,并行處理能力是最差的,例如 Oracle 的單機模式,。 Shared Disk:各個處理單元使用自己的私有 CPU和 Memory,,共享磁盤系統(tǒng)。典型的代表 Oracle RAC,, 它是數(shù)據(jù)共享,,可通過增加節(jié)點來提高并行處理的能力,擴展能力較好,。其類似于 SMP(對稱多處理)模式,,但是當存儲器接口達到飽和的時候,,增加節(jié)點并不能獲得更高的性能 。 Shared Nothing:各個處理單元都有自己私有的 CPU / 內(nèi)存 / 硬盤等,,不存在共享資源,,類似于 MPP(大規(guī)模并行處理)模式,各處理單元之間通過協(xié)議通信,,并行處理和擴展能力更好,。 各節(jié)點相互獨立,各自處理自己的數(shù)據(jù),,處理后的結(jié)果可能向上層匯總或在節(jié)點間流轉(zhuǎn),。
我們常說的 Sharding 其實就是 Share Nothing 架構(gòu),它是把某個表從物理存儲上被水平分割,,并分配給多臺服務器(或多個實例),,每臺服務器可以獨立工作,具備共同的 schema,,只需增加服務器數(shù)就可以增加處理能力和容量,。 Oracle Sharding 是 Oracle 12.2 版本推出的新功能,也稱為數(shù)據(jù)分片,,適用于 online transaction processing (OLTP),。Oracle Sharding 基于表分區(qū)技術(shù),是一種在數(shù)據(jù)層將數(shù)據(jù)水平分區(qū)存儲到不同的數(shù)據(jù)庫的技術(shù),。Sharding 可以實現(xiàn)將一個分區(qū)表的不同分區(qū)存儲在不同的數(shù)據(jù)庫中,,每個數(shù)據(jù)庫位于不同的服務器,每一個數(shù)據(jù)庫都稱為shard,,這些 shard 組成一個邏輯數(shù)據(jù)庫,,稱為 sharded database (SDB)。這個 table 也稱為 sharded table,,每個 shard 數(shù)據(jù)庫中保存該表的不同數(shù)據(jù)集(按照 sharding key 分區(qū)),,但是他們有相同的列 (columns)。
Shard 是一種 shared-nothing 技術(shù),,每個 shard 數(shù)據(jù)庫使用獨立的服務器硬件 (CPU,、內(nèi)存等)。Shard 可以運行在單機數(shù)據(jù)庫或者 DATAGUARD / ADG 數(shù)據(jù)庫,。 Sharding 其實需要解決三個問題: 數(shù)據(jù)的路由 數(shù)據(jù)路由是數(shù)據(jù)庫告訴應用程序,,你讓我查的數(shù)據(jù)目前在哪個分片上,這條路怎么走過去,。 數(shù)據(jù)的分片 數(shù)據(jù)分片就是實際數(shù)據(jù)的存放地點,,往往每個分片就是一臺單獨的服務器(含存儲)。 分片的元數(shù)據(jù)信息保存 由于分片的數(shù)據(jù)實際是被切割放在不同的機器上,,那么需要有個集中的地點存放數(shù)據(jù)分片的信息,,即分片元數(shù)據(jù)的信息,。
Oracle Sharding 主要包括下面組件:
Sharded database (SDB):邏輯上 SDB 是一個數(shù)據(jù)庫,但是物理上SDB包括多個物理獨立的數(shù)據(jù)庫,,SDB 類似一個數(shù)據(jù)庫池 (pool),,數(shù)據(jù)庫池 (pool) 中包括多個數(shù)據(jù)庫 (Shard)。目前版本最大支持1000個 shard,。 Shards:SDB 包括多個物理獨立的數(shù)據(jù)庫,,每一個數(shù)據(jù)庫都稱為shard,,每個 shard 數(shù)據(jù)庫位于不同的服務器,,他們不共享 CPU、內(nèi)存,、存儲等資源,。每個shard 數(shù)據(jù)庫中保存表的不同數(shù)據(jù)集, 但是每個 shard 中都有相同的列(columns)。Shard 數(shù)據(jù)庫可以是 Dataguard / ADG,,提供高可用性,,Shard 數(shù)據(jù)庫(單機或者 ADG)可以通過 GSM deploy 來自動創(chuàng)建,也可以將一個已經(jīng)通過 dbca 創(chuàng)建好的數(shù)據(jù)庫 add 到 SDB,。 Shard catalog:是一個 Oracle 數(shù)據(jù)庫,,用于集中存儲管理 SDB 配置信息,是 SDB 的核心,。SDB 配置變化,,比如添加/刪除 shard,Globalservice 等等,,都記錄在 Shard catalog,。如果應用查詢多個 shard 中的數(shù)據(jù),那么由 Shard catalog統(tǒng)一協(xié)調(diào)分配,。我們推薦將 Shard catalog 配置為 dataguard 環(huán)境,,這樣可以提供 HA 高可用。如果 Shard catalog 無法訪問,,那么只會影響一些維護操作和跨shard訪問,,而不會影響單獨的 shard 操作(通過 sharding key 的查詢 /DML)。 Shard directors:Global Data Service (GDS) 實現(xiàn)對 Sharding 的集中部署和管理,。GSM 是 GDS 的核心組件,。GSM 作為 Shard director。GSM 類似于監(jiān)聽器,,將客戶端對 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 內(nèi),。 Dataguard 可以級聯(lián),,那么我們可以把 primary 做為一個 shardgroup1,第一級的 dataguard 叫 shardgroup2,,第二級的 dataguard 叫 shardgroup2,。如下:
shardspace shardspace 的概念伴隨著綜合性分片的分片方法(compositesharding method)出現(xiàn)的;如果是系統(tǒng)管理分片方法(system-managed shardingmethod),,只有一個默認的 shardspace,。所以只有在 compositesharding 下,才有可能出現(xiàn)多個 shardspace,。
在 composite sharding 下,,數(shù)據(jù)首先根據(jù) list 或者 range,分成若干個shardspace,。然后再根據(jù)一致性 hash 進行分片,。 注:每個 shardspace 包含一個或者多個復制 shard for HA/DR。
我們可以按照服務級別來劃分 shardspace,,如硬件好的,,作為 shardspace_gold,硬件差一些的,,劃做 shardspace_silver:
Oracle Sharding 支持3種方法 shard / 分片方法:
System-Managed Sharding:這種方法用戶不用指定數(shù)據(jù)存放在哪個 shard 中,。Sharding 通過一致性哈希 (CONSISTENT HASH) 方法將數(shù)據(jù)分區(qū) (partitioning),并自動分布在不同的 Shard,。System-managed sharding 只能有一個shardspace,。 Composite Sharding:這種方法用戶創(chuàng)建多個 shardspaces ,每個 shardspaces 中存放一定范圍 (range) 或者列表 (list) 的數(shù)據(jù),。一般情況下,,Shardspace 按照區(qū)域來劃分,比如美國區(qū)域的 shard 屬于 shardspace cust_america,,歐洲的 shard 屬于 shardspace cust_europe,。 Subpartitions with Sharding:Sharding 基于表分區(qū),因此子分區(qū) (Subpartitions) 技術(shù)同樣適用于 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 的數(shù)據(jù)存儲在同一個 Chunk 中,這樣方便以后的數(shù)據(jù)移動,。
比如: 用戶表 – 訂單表 – 訂單明細表 就是一個表家族,,其中用戶表是 root table,訂單表和訂單明細表分別是子表,,他們都按照 sharding key (CustNo ) 分區(qū),。
可以通過如下兩種方式建立 table family:
通過CONSTRAINT [FK_name] FOREIGN KEY(FK_column) REFERENCES [R_table_name]([R_table_column]) —這種關系可以有級聯(lián)關系。
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 是根據(jù) CONSISTENT HASH,,對 CustId 進行分區(qū),;
下一級的表是 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 來顯式的說明父子關系,。這種關系只有父子一層關系,不能級聯(lián),。 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 字段,在每個表中都是有的,。而上面說的第一種的級聯(lián)關系的 tablefamily,,可以不在每個表中都存在 CustNo 字段。
上面創(chuàng)建在表,,都是 sharded table,,即表的各個分區(qū),,可以分布在不同的 shard node 上。各個 shard node 上的分區(qū),,是不同的,。即整個表的內(nèi)容,是被切割成片,,分配在不同的機器上的,。 而 duplicatedtable,是整個表達同樣內(nèi)容,,在各個機器上是一樣的,。duplicate table 在各個 shard node上,是以 read only mv 的方式呈現(xiàn):在 shardcat 中,,存在 mast table,;在各個shard中,存在 read only mv,。duplicated table 的同步:以物化視圖的方式同步,。
chunk 的概念和 table family 密不可分。因為 family 之間的各個表都是有關系的,,我們把某個 table family 的一組分區(qū)稱作一個 chunk,。
如 customers 表中的1號~100萬號客戶信息在一個分區(qū)中;在 order 表中,,也有1號~100萬號的客戶的 order 信息,,也在一個分區(qū)中;另外 LineItems 表中的1號~100萬號客戶的明細信息,,也在一個分區(qū)中,,我們希望這些相關的分區(qū),都是在一個 shard node 中,,避免 cross shard join,。所以,我們把這些在同一個 table family 內(nèi),,相關的分區(qū)叫做 chunk,。在進行 re-sharding 的時候,是以 chunk 為單位進行移動,。因此可以避免 cross shard join,。
注:chunk 的數(shù)量在 CREATESHARDCATALOG 的指定,如果不指定,,默認值是每個shard 120個chunk
chunk move 的條件:
re-sharding 發(fā)生,,即當 shard 的數(shù)量發(fā)生改變的時候,會發(fā)生 chunk move。 注:re-sharding 之后,,chunk 的數(shù)雖然平均,,但并不連續(xù)。 如:原來是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 上,。即:總是挪已經(jīng)存在的 shard node 上的后面部分 chunk。 DBA 手工發(fā)起: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 狀態(tài)。
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)->結(jié)束 FAN(等待幾秒)->刪除原 shard 上的老 chunk Oracle Sharding 路由選擇(Routing) --直接路由 應用程序初始化時,,在應用層/中間件層建立連接池,連接池獲取所有 shard 節(jié)點的sharding key 范圍,,并且保存在連接池中,形成 shard topologycache(拓撲緩存),,Cache 提供了一個快速的方法直接將請求路由到具體的 shard,。 客戶端請求時指定 shard key,直接從連接池獲取連接,,這種情況下不經(jīng)過 shard director / catalog 數(shù)據(jù)庫,,直接連接到對應的 shard。
--代理路由 如果客戶端執(zhí)行 select 或者DML 時不指定 shard key 或者執(zhí)行聚合操作(比如groupby),,那么請求發(fā)送到 Catalog 數(shù)據(jù)庫,,根據(jù) matadata 信息,SQL 編譯器決定訪問哪些 shards,。 為了實現(xiàn) sharding,,Oracle 在連接池和驅(qū)動方面都做了增強,提供了新的 API(UCP, JDBC, OCI 等等)在連接創(chuàng)建時來傳遞 sharding keys,。 Sharding 技術(shù)的優(yōu)點和缺點 增加了 SQL 的復雜性 因為開發(fā)人員必須要寫更復雜的 SQL 來處理 sharding 的邏輯,。 Sharding 本身帶來的復雜性 sharding 軟件需要照顧分區(qū),數(shù)據(jù)平衡, 訪問協(xié)調(diào),,數(shù)據(jù)完整性 單點故障 一個 shard 損壞可能導致整張表不可訪問,。失效接管服務器也更復雜。因為負責失效接管的服務器必須擁有任何可能損壞的 shard 上的數(shù)據(jù),。 備份也更復雜 多個 shard 可能都需要同時備份,。 維護也更復雜 比如增加刪除索引,增減刪除字段,,修改表定義等等,,都變得更困難 商業(yè) sharding 技術(shù)隨著節(jié)點數(shù)的增加,Licensing 費用也會大規(guī)模增加
在 Oracle12.2 Sharding 中都無需擔心,,Oracle 作為一個商業(yè)數(shù)據(jù)庫,,已通過底層開發(fā)規(guī)避了這些問題。
單點故障問題可以通過 RAC+Sharding,,ADG+Sharding 來規(guī)避,,但成本也會增加。 Oracle Sharding 技術(shù)提供線性擴展和失敗隔離的優(yōu)點 線性擴展 因為每個 shard 是一個獨立的數(shù)據(jù)庫,,通過增加新的 Shard 節(jié)點,,來線性擴展性能。自動 rebalance 數(shù)據(jù),。 失敗隔離 由于 Shard 是一種 shared-nothing 技術(shù),,每個 shard 使用獨立的硬件,因此一個 shard 節(jié)點出現(xiàn)故障,,只會影響到這個 shard 存放的數(shù)據(jù),,而不會影響到其他shard。 按照地理位置分布數(shù)據(jù) 可以選擇根據(jù)地理位置不同,,將數(shù)據(jù)存儲在不同的 shard,。 滾動升級 選擇不同時間升級不同的 shard。比如同一時間只升級一個或一部分 shard,,那么只有這些升級的 shard 中存儲的數(shù)據(jù)受到影響,,其他的 shard 不受到影響,可以繼續(xù)提供服務,。 云部署 Shard 非常適合部署在 cloud
戳原文,,回看視頻課程!
|