漫談OB | OceanBase 在海量資料和高併發下的應用實踐

OceanBase資料庫發表於2021-11-10
? 本文適用於 OceanBase 企業版和社群版。


原資料庫問題以及應對策略

> > > >

連線問題分析


這一類業務原資料庫一般是 ORACLE 資料庫。當業務量增長,應用規模變多,建立的資料庫連線也會很多,導致 DBA 不得不出規定限制一下應用的連線數。 連線數太多在 ORACLE 上會成為問題,主要原因還是業務增長太快,資料庫是集中式部署架構,並且每個連線就是一個程式。

在 OceanBase 裡,每個客戶端連線只是一個執行緒,內部實際工作的執行緒數跟 CPU 個數相關,連線很多時消耗的資源並不大。 所以,在 OceanBase 資料庫裡,連線數很難成為首要問題或者瓶頸。

> > > >

空間問題分析


這一類業務一般是運營商行業或者網際網路行業有面向終端消費者業務的。使用者量大,訪問量大,導致業務積累了上 T 的交易資料。資料量的急劇增長,導致查詢效能下降,資料維護成本變大,備份恢復時間變長。

在 OceanBase 裡,資料儲存時除了可以選擇壓縮演算法外,還可以選擇編碼技術,極大的降低了資料的儲存空間。 在 OceanBase 的客戶案例裡,ORACLE 資料遷移到 OceanBase ,單副本空間可以做到之前的 1/5 。MySQL 業務案例裡,近 20T 的 MySQL 資料在 OceanBase 裡單副本實際儲存空間大概 4.3 T 左右。而效能方面,透過編碼技術節省儲存空間這個資料並不需要解碼操作,不消耗 CPU ,所以整體效能差異並不大。OceanBase 企業版預設就開啟了高階壓縮特性。有關這個壓縮特性請參考《 戳: 2.0 解析系列 | OceanBase 2.0的高階資料壓縮特性 》。

> > > >

效能問題分析


在 ORACLE / MYSQL 裡,表資料量到了億級別繼續增長的話,效能上可能會變慢。其他維護操作(表結構變更、表備份恢復等)風險可能增加。

效能變慢也分讀變慢和寫變慢。

讀查詢通常能走索引,不過業務比較複雜,表上的索引也很多。尤其以單列索引居多。往往業務查詢條件很多,只是部分欄位能命中索引,然後還有大量的索引回表操作。隨著資料量的增長,資料儲存空間變大,回表的成本也在增長,效能會下降。部分場景下這些索引建的並不合適(單列索引值得商榷的空間最大)。寫操作通常也跟索引有關係。 update  和  delete  操作的條件要走索引,更新資料時還要更新索引資料。當表上索引數量很多(如超過10個)時,索引對資料更新的影響也是很明顯的。

由於索引很多都是業務開發建立的,每個業務的開發只管自己的查詢,並不一定能全盤考慮。索引是否最優是個未知數。但資料庫效能變慢是所有人都能看懂的事實。於是傳統資料庫背鍋,業務寄希望於分散式資料庫能解決。

分散式資料庫確實有很多辦法應對這個挑戰。

首先是透過水平拆分技術將一個大表的資料分散到多個例項多臺機器上(多臺機器是關鍵)。水平拆分技術有分庫分表、分割槽表和儲存切片三類技術。這裡主要討論 前兩者。

分庫分表技術將業務大表拆分多個分片,每個分片是一個實際存在的物理表。分割槽表拆分後的每一個分片是一個分割槽,是表的子集,不是分表。兩種技術的產品都呈現給業務的是一個業務表。前者呈現的是邏輯表,後者呈現的是物理表。這是二者原理的區別。不同的分片相比原表,不僅資料量小,儲存空間也小,很多小範圍的資料查詢和修改效能都會提升。此外,不同的分片如果落到不同的機器上,則可以將多臺機器的儲存能力和計算能力(CPU、記憶體和IO)都同時運用起來,總體處理能力也會提升。

不過, 分散式除了帶來好處,也帶來挑戰。那就是跨機的查詢和事務。

在分庫分表技術裡,這個處理複雜度很高,只有少數幾家廠商產品實現了這個功能。但是都有一個問題,就是資料強一致和讀寫效能方面要有取捨。資料強一致包含跨機的查詢資料都滿足MVCC、跨機的事務修改的資料要是強一致的(不能是最終一致性解決方案)。

在 OceanBase 裡,自 2.0版本後,跨機的分散式查詢和分散式事務都支援(指滿足強一致。1.4版本不支援跨機一致性快照讀),效能方面也不差。

> > > >

分庫分表問題分析


有些運營商業務和網際網路業務場景已經探索了分庫分表這種水平拆分技術。但是由於業務資料量大、以及訪問量大,也有很多痛點。

比如說:

  • 大表線上DDL導致從庫延時很大。分庫分表技術將一個大的DDL 拆分為多個分表的 DDL。表總體資料量很大的時候,ONLINE DDL會導致多個MySQL 的從庫出現不同程度的延遲。並且多個分表的DDL進度不一定完全一致。

  • 大表線上 DDL 可能阻塞 DML。在 MySQL 的 Online DDL的開始和結束階段,涉及到後設資料的變更時會嘗試加表鎖,會阻塞 DML。此外有些 DDL還不支援 Online,也會阻塞 DML。

  • 大表線上 DDL 在機器故障後處理過程比較麻煩。當 DDL 進行中,有 MySQL 機器出現故障。首先會話要報錯(DDL 部分成功部分失敗),失敗的 MySQL 要主從切換。主從切換時如果有 Binlog 丟失(非同步同步),則還需要修復主從同步。然後還要在新主上重新開始 DDL 。

  • 小表廣播故障時問題。廣播表適合那些不能做拆分的配置表,但是會頻繁的跟其他拆分過的分表做表連線,廣播表會把資料透過Binlog複製技術應用到所有例項的分庫中,這個同步是外部邏輯同步,其可靠性最高不超過 MySQL的Binlog複製。其麻煩也是在同步過程中出現機器故障後,處理過程比較麻煩。風險是故障後廣播表多個副本資料不一致。

  • 大量分庫拆分,導致MySQL例項和機器規模增長很快,運維成本和風險會增加,當然廠商產品也會有自動化運維平臺(DB PaaS 平臺)。其麻煩依然是在出現機器故障後。只要有三四個例項要修復主從同步,DBA 半天的時間就過去了。

在 OceanBase 裡,上面大部分問題會因為技術方案不同而有所改變。

  • 首先,OceanBase 每筆事務預設就是三副本強同步,Paxos協議會保證至少一半成員事務日誌落盤了,這個事務才會成功。這個對主副本的事務提交效能會有制約。此外,由於 OceanBase 事務日誌同步粒度是分割槽級別,多個分割槽獨立同步,DDL 也不阻塞 DML,所以 OB 整體的延時的水平很低。

  • 第二,OceanBase的三副本強同步的另外一個好處就是 OceanBase 的高可用能力會時刻處於可用狀態。只要發生少數派機器故障,內部就切換(選舉出新的主副本),並且OceanBase 保證資料跟故障前是絕對一致的(RPO=0)。故障機器恢復後,原來的DDL可以繼續,不需要運維介入處理。也沒有內部資料不一致。

  • 第三,OceanBase的資料讀寫模型是 LSM Tree,DDL 都是 Online DDL,不會阻塞 DML。當然,OceanBase 目前有一些 DDL 都不支援。這個預計在 3.2 後面版本會更豐富。

  • 第四,不能拆分的配置表可以在 OceanBase 裡配置為 複製表,OceanBase會自動將複製表的變更資料同步到例項所在的所有機器(也可以指定機器範圍)。這種同步是全同步策略,全部成功事務才提交,所以所有副本資料都是完全一致的。這種同步在機器故障的時候,會自動剔除故障節點,也不需要運維介入。故障機器恢復後,自動恢復資料同步,並自動恢復到全同步成員中。

  • 第五,OceanBase只要一個例項,例項裡表用分割槽表就可以替換原分庫分表架構。例項可以線上擴容和縮容,負載均衡和資料同步都是 OceanBase 內部邏輯,運維非常的“省心”。



OceanBase 分散式能力實踐


OceanBase的分散式能力包含: 高可用、多例項、多活、分割槽表、複製表

> > > >

高可用


高可用指的的分散式資料庫 OceanBase 叢集裡有機器故障的時候,資料庫訪問服務在中斷後能自動恢復。有些觀點可能不把高可用能力當作分散式能力,但這個是OceanBase 最核心叢集最基礎的能力(不可剝奪)。這裡就簡單提一下,OceanBase的高可用能力就是少數派機器故障,自動切換(RTO~30s),資料不丟(RPO=0)。故障恢復後,資料同步自動恢復,非常的省心。

> > > >

多例項


多例項就是多租戶,例項更通俗一些。OceanBase 以叢集形式部署,提供給業務的是例項。叢集在每個機器上只有一個程式,例項是邏輯例項,對業務完全透明,體感跟單例項一樣。例項提供原生的 SQL 能力和事務能力,分散式細節對使用者完全透明。

OceanBase 的多例項可以提高對機器資源的利用率,根據業務需求有多種使用方法。其關鍵點就是 例項的主副本位置策略( PRIMARY_ZONE )的設定。預設情況下設定為一個  zone ,以及  unit_num  設定為 1 。業務壓力大的例項,有很多分割槽表的例項,可以考慮將 unit_num  設定為 2 以及  PRIMARY_ZONE  設定為多個  zone ,以提升例項的總體處理能力。

OceanBase 多例項之間有資源隔離(CPU和記憶體),資料完全隔離。不過現在也支援 DBLINK 聯通不同 ORACLE 例項之間的資料。

> > > >

多活能力


OceanBase 可以很好的將叢集的多臺機器都提供服務,這就是多活能力。多例項和多活能力結合使用,將不同例項的壓力在叢集機器之間可以實現一定程度的錯開。

在 OceanBase 裡做讀寫分離也是很方便的。在三副本之外增加一個只讀副本,就可以專門用於只讀查詢業務。OceanBase 保證只讀副本的資料只會有延時,絕不會有錯誤。

> > > >

分割槽表


OceanBase 分散式最核心能力之一就是分割槽表,這個概念跟 ORACLE 分割槽表是一樣的。

分割槽表的用法就是選一個欄位當作分割槽欄位,按照某種策略(LIST\HASH\RANGE\二級分組組合)拆分表資料為多個分割槽。當業務表非常多的時候,比較麻煩的也是這個分割槽欄位的選擇。

精力有限的情況下,建議是抓住關鍵的表,有這麼些策略選擇表:

  • 業務主要流程的相關表。如訂單業務,那就是訂單表、訂單歷史表、會員表。支付業務就是支付訂單表、支付歷史表等等。每個表如果有透過業務外來鍵關聯的表都算上。

  • 業務資料量在 1 億以上的大表。或者業務訪問量(QPS)非常高的表。

  • 核心業務查詢很慢的 SQL 對應的表。

分割槽欄位選擇:


對於核心業務相關表,當表之間都遵循第三正規化設計的時候,有兩種做法。

一種做法就是加入冗餘列(比如說會員id)。如果所有表資料都是圍繞會員的,所有表都根據會員 ID 做 HASH 分割槽。這些相關的表就可以放到一個表分組中。這是最優的設計。

不過由於表很多的時候,老業務使用者可能不想改動。那就退而求其次,選第二個方案。每個表獨立的選擇分割槽欄位。對於主表,如果有自增 ID 做主鍵,簡單一點就使用自增 iD 作為分割槽鍵。更好的建議是用業務欄位。因為業務查詢帶上業務欄位的機率更高。使用相同分割槽欄位的分割槽表,儘量保證分割槽數(分片數)是一致的。

不同表的分割槽欄位不一樣,關聯查詢的時候可能會出現 1:N 或者 M:N 這樣的連線模型,這個在 OceanBase裡很可能是跨機的請求,但是這種查詢可以發揮多機並行能力,所以效能也比較好。

本地索引和全域性索引:


當分割槽表分割槽欄位定了後,總會有很多查詢是不帶分割槽鍵的,建議優先用本地分割槽索引。有些人瞭解 OceanBase 分割槽表原理後,可能會覺得本地索引很慢,用全域性索引會更好。實際上,用本地索引時,會掃描所有分割槽的本地索引,OceanBase可以在分割槽間並行,這個掃描也不會特別慢。當索引返回的資料量很少的時候,這個效能是很好的。

全域性索引對少量資料查詢場景是非常友好的。但是如果索引過濾資料不高返回很多資料的時候,全域性索引的效能有可能會比本地索引效能還要差。因為全域性索引是獨立的分割槽,本地索引跟資料是在一個分割槽上的。查詢時使用全域性分割槽索引,在索引回表的時候很有可能是分散式查詢,回表資料量很大的時候,這個效能會有不確定性。

此外,正如索引會降低資料修改(DML)的效能,全域性索引對資料修改(DML)的影響會更明顯一些。因為這個修改很可能就是一個跨機的分散式事務。這也是一個考慮因素。

索引是為最重要的查詢場景服務的,其代價就是寫入的效能,全域性索引更是如此。如果一定要用,要控制數量,要控制使用場景一定是非常重要且必要的場景。要避免濫用索引包括全域性索引。這就是業務開發建索引不是很好的地方。重要表的索引的建立應該由專業的DBA來稽核或者建立。

表分組:


例項架構是  1-1-1   的時候,例項所在的每個機器上都擁有該例項的全部資料(分割槽)。再透過設定例項的  PRIMARY_ZONE 為具體的值將例項的全部分割槽主副本約束在該區域( ZONE  )的機器上。如果例項架構是 2-2-2  的時候,即使設定了 PRIMARY_ZONE  ,全部主副本也是分散在某個區域的 2 臺機器上。業務可能會有分散式查詢或事務。表分組可以將分割槽位置控制策略細化到一組分割槽。

表分組的詳細使用介紹請參考《 戳: OCEANBASE TABLEGROUP 用法介紹 》。通常有兩種場景。

第一種簡單一些,大部分表都是普通非分割槽表。根據業務屬性將全部表劃分為幾個子集,每個子集裡的表設定為一個獨立的表分組。那麼 OceanBase 的負載均衡策略會保證在一個表分組中的分割槽在穩定的時候在一個節點內部。這樣同一個表分組內部的表之間的連線或者事務,都是本地連線或本地事務。這樣效能最優。

第二種複雜一點,有很多分割槽表,並且很多分割槽表的分割槽策略相同(分割槽欄位、分割槽數相同)。把這些表放到一個表分組裡,它們的同號分割槽就形成一個分割槽組。OceanBase 的負載均衡策略會保證在一個分割槽組中的分割槽在穩定的時候在一個節點內部。這樣對於一些有分割槽欄位作為連線條件的查詢,很容易實現一些本地表連線或者多個本地表連線並行的局面。這樣也效能最優。

表分組是 OceanBase 提供給業務架構師干預 OceanBase 負載均衡的一個精細化手段(OceanBase 負載均衡排程會考慮分割槽組),需要對業務和 OceanBase 都很瞭解。這個設計如果使用不當也可能會削弱 OceanBase 的分散式能力。

> > > >

複製表


跟索引的使用思想一樣,複製表是另外一個需要權衡考慮的方案。複製表跟表分組不能同時使用。

複製表主要解決一些表業務上決定了不能拆分(分割槽)或者沒有必要拆分,但它又頻繁的跟分割槽表有關聯關係。為了減少不必要的跨機分散式查詢,複製表將自己的資料強同步到例項的所有機器上,所以不管分割槽表的分割槽的主副本在哪個機器上,它都可以在 同機跟複製表的副本做表連線。

OceanBase 裡普通的表多是三副本,但是在一個 2-2-2 的租戶(例項)裡,複製表的副本可以是六副本,並且還是全同步,六個副本事務日誌同時落盤事務才提交。所以複製表的寫效能會比 Paxos協議強同步策略要慢一些,適合寫入TPS 不高的業務表(如配置表、參數列)。這就是複製表的代價。

以上是複製表常用用法。

普通表到複製表的轉換可以線上做,也很方便,就是改變表的一個屬性。運維也是相當簡單。擴充副本( 3 副本到 6 副本)的時候會需要一些資料遷移時間。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69909943/viewspace-2841461/,如需轉載,請註明出處,否則將追究法律責任。

相關文章