回覆列表
  • 1 # 使用者4631824322

    OceanBase是以叢集形式執行的,由一堆伺服器組成。機器會分為三組,每組一個區域(稱為Zone),各個機器透過網路互相訪問。沒有光纖交換機、共享儲存以及直連網線等。

    伺服器通常建議CPU、記憶體和磁碟儘可能的大,磁碟建議用普通SSD盤。普通伺服器的好處是便宜,劣勢是可靠性和效能可能不如小型機那麼高。也就是說OceanBase可以部署在一組可靠性和效能不是特別高的普通伺服器上,卻提供了高效能、高可用和高可靠、彈性伸縮等多項能力。

    以上是一個OceanBase叢集的外觀和能力,但是提供給業務的並不是這個叢集的全部資源和能力,而是其子集,即租戶(Tenant)。

    OceanBase多租戶特性

    OceanBase定義了一些基本的資源規格(Resource unit config,如4CPU8Gmem500Gdisk等),然後選取某類資源規格建立一組資源池(Resource Pool),此時叢集資源就有一部分被分配出去了。最後將這個資源池關聯到一個新建租戶,則租戶就可以使用這個資源池的能力。

    OceanBase預設有個sys,管理整個叢集。使用者租戶必須在sys內部建立。

    #sys登入方法

    $mysql -hxxx.xx.11.11 -uroot@sys#obdemo -P2883 -proot oceanbase -A

    #資源規格(UnitConfig)

    create resourceunit S0_uc max_cpu=2,max_memory="5G",…

    資源單元(Unit)

    create resourcepool Pool_01 unit="S0_uc",unit_num=2,...

    (Tenant)

    create tenant test_ins resource_pool_list= ("Pool_01"),...

    OceanBase相容了大部分MySQL連線協議和語法,租戶的使用體驗跟MySQL例項很像。研發可以在租戶裡建立資料庫(Database)、表(Table)。還包括分割槽表等。

    OceanBase裡描述資料的最小粒度是分割槽。普通的表(非分割槽表)就是一個分割槽,分割槽表則包含多個分割槽。

    資料是絕對隔離,資源有一定程度隔離。研發可以將業務先垂直拆分為多個獨立的子業務,分別使用不同的租戶或者叢集。

    OceanBase資源單元

    不知道資料具體在哪個機器上,也可以說沒必要知道。只是租戶的效能還取決於運維為租戶規劃的資源池分佈情況,所以瞭解一下資源單元的分佈特點對效能規劃也是有意義的。

    資源池(Resource Pool)是由一組資源單元(Resource Unit)組成。資源單元數量預設跟Zone的數量一致或者是它的倍數(可以配置具體分佈在哪些Zone以及每個Zone裡的Unit數量)

    資源單元具備一定的資源能力,是資料的容器。租戶擁有的資源單元規格和數量決定了這個租戶最大效能。資源單元可以在同一個Zone的不同節點之間自由遷移,OceanBase藉此來維持各個節點的資源利用率儘可能維持一個均衡狀態。

    OceanBase拆分設計

    資料庫拆分

    資料庫拆分有兩種。

    一是垂直拆分。即按業務模組拆分到不同的例項或庫裡。為了模組之間互不影響,拆分到不同的例項比較好。

    一是水平拆分

    。將一個業務表拆分到N個相同結構的物理表中。中介軟體做業務表(邏輯表)到分表(物理表)的對映路由以及其他相關操作(如結果聚合計算)等。這個N個物理表可以在不同例項的不同分庫中。分庫的維度和分表的維度可以不一樣,比較靈活。

    分割槽表。將一個物理表設計為分割槽表,拆分到N個分割槽。分割槽表的各個分割槽結構是資料庫內部保證一致。OceanBase選擇的是分割槽表的水平拆分方式,並且支援二級分割槽表(即有2個不同的拆分維度疊加使用)。

    業務表order先經過中介軟體拆分為100個分表(存在10個分庫裡),每個分表在OceanBase內部又是一個分割槽表(100個分割槽)。分庫分表的維度和分割槽表分割槽的維度都是一致的,根據使用者ID。

    分庫分表和分割槽各有利弊。

    分庫分表的好處是各個分表的結構一致性是在中介軟體層保證,比較好控制,比較適合灰度變更(允許部分分表結構不一致,最終必須全部一致)。此外更大的好處是,分庫分表是實現異地多活單元話架構的必不可少的條件。缺點是中介軟體的SQL支援範圍有限。

    分割槽的好處是在資料庫內部解決了拆分問題。針對分割槽表的SQL功能是資料庫SQL引擎的本質工作,相關特性(全域性索引、二級分割槽等)會持續開發完善。

    分割槽

    分庫分表架構設計,需要確定機器數、例項數、分庫數和分表數的拓撲,效能理論上限取決於主例項所處的機器節點數。此後要做擴充套件就要調整這四個元素的數目及其聯絡。這種擴充套件很可能涉及到分表資料的遷移,需要藉助外部工具或產品實現。

    分割槽架構設計,研發確定分割槽策略和分割槽數,運維確定租戶的資源單元數量,OceanBase確定資源單元(Unit)在哪些機器節點上以及分割槽(Partition)在哪些資源單元裡。同一個分割槽不能跨節點儲存此後要做擴充套件就是調整資源單元的規格、數量。

    OceanBase在確定Unit裡的分割槽的位置時會盡量讓每個節點的負載維持均衡。這個負載的計算方式比較複雜,會綜合考慮OB節點內部CPU、記憶體和空間利用率等。分割槽隨意分佈對應用效能很可能有負面影響。當業務上有聯絡的兩個表的分割槽分佈在不同的資源單元裡(同時也分佈在不同的節點裡),這兩個表的連線就難以避免跨節點請求資料,網路上的延時會影響這個連線的效能。

    每個分割槽在集群裡資料實際有三份,即三副本(Replica)。忽略了Zone2和Zone3的細節。三副本之間的資料同步靠把Leader副本的事務日誌同步到其他Follower副本中。Paxos協議會保障這個事務日誌傳輸的可靠性(事務日誌在一半以上成員裡落盤,剩餘成員最終也會落盤),同時還有個以分割槽為粒度的選舉機制,保障Leader副本不可用的時候,能快速從現有兩個Follower副本里選舉出新的Leader副本,並且資料還絕對不丟。這裡就體現了故障切換時兩個重要指標:RPO=0, RTO<30s。

    Locality

    t0和t1業務上是有聯絡的表(如主表和詳情表),兩者都是分割槽表,分割槽策略和分片數都相同,OceanBase提供了一個表屬性“表分組”(TableGroup)。設定為同一個表分組的不同表的分割槽數一定一樣,並且同號分割槽組成一個“分割槽分組”(PartitionGroup)。同一個分割槽分組的分割槽一定會分配在同一個資源單元(Unit)內部(也就是會在同一個節點內部),彼此的連線邏輯就避免了跨節點請求。另外一個效果是如果一個事務同時修改兩個有業務關聯的分割槽,使用分割槽分組也可以規避跨節點的分散式事務。這個表分組屬性的設定就是OceanBase的Locality特性之一——影響相關分割槽的分佈。

    實際上每個分割槽都有三副本(Replica, 本文例子),省略了t0(p0)和t1(p0)的其他兩個副本都分別會在同一個Unit裡分配。不僅如此,每個分割槽的三副本里都會有leader副本預設提供讀寫服務。leader副本是選舉出來的。t0(p0)和t1(p0)的leader副本也一定會在同一個Unit裡(即在同一個Zone裡)。這樣才徹底的避免了連線的時候跨節點請求。

    OceanBase的Locality特性還可以指定租戶/資料庫/表的預設Zone,這樣下面的表的leader副本會優先被選舉為這個Zone裡副本。

    資料庫和表會繼承租戶的預設設定,當然也可以自己修改primary_zone或者locality屬性覆蓋上層設定。:

    create tenant obtrans0primary_zone="hz1";

    create table item (…)locality = "F@hz1, F@hz2, F@hz3,R{all_server}@hz1, R{all_server}@hz2, R{all_server}@hz3"

    注:F表示全功能副本,R表示只讀副本。

    設定primary_zone後單個租戶的所有表的讀寫都集中到一個Zone裡,該租戶在其他zone裡的Unit就沒有讀寫壓力。通常這樣做是源於業務應用的要求。如應用的請求都是來自於這個Zone,為了規避應用跨Zone讀寫資料效能下降。不過primary_zone更大的意義在於當集群裡有很多租戶的時候,可以將不同業務租戶的讀寫壓力分攤到不同Zone的機器,這樣叢集整體資源利用率提升,所有應用的總體效能也得到提升。後面要介紹的異地多活架構就充分利用OceanBase這個特性,在資料庫層面將拆分的表的業務讀寫點儘可能分散到所有Zone的所有機器上。

    除了表與表之間可能有聯絡,業務模組之間也可能有聯絡。一個業務過程可能會橫跨多個業務模組,前面這些模組的資料被垂直拆分到多個租戶裡。OceanBase的Locality特性“租戶分組”(TenantGroup)還可以設定不同租戶之間的聯絡。如下租戶交易訂單和支付訂單在業務上是先後發生。

    create tenantgroup tgtrade tenant_array=("obtrade0", "obpay0");

    租戶分組的意義依然是為了在分散式架構下儘可能將一個業務流程內多次資料庫請求都約束在同一個Zone或者Region(注:OceanBase將地域相鄰的Zone定義為一個Region)裡。

    OceanBase異地多活架構

    異地多活概念

    異地多活資料庫有狀態,傳統資料庫只有主庫可以提供讀寫,備庫最多隻能提供只讀服務(如ORACLE的Active Dataguard):

    1. 應用雙活,資料庫A地讀寫,B地不可讀寫。這種只有應用多活,資料庫是異地備份容災(無併發)。

    2. 應用雙活,資料庫A地讀寫,B地只讀。這種也是應用雙活,資料庫讀寫分離(例項級併發)。

    3. 應用雙活,資料庫雙活,兩地應用同時讀寫不同表。這種資料庫雙向同步,應用同時錯開寫不同的資料(表級併發)。

    4. 應用雙活,資料庫雙活,兩地應用同時讀寫相同表不同記錄。這種資料庫雙向同步,應用同時錯開寫不同的資料(行級併發)。

    5. 應用雙活,資料庫雙活,兩地應用同時讀寫相同表相同記錄。這種資料庫雙向同步,應用同時寫相同的資料,最終會因為衝突一方事務回滾(行級併發寫衝突)

    上面第1種情形,B地應用是跨地域遠端讀寫資料庫。兩地距離較大的時候效能會很不好。2的B地應用是本地訪問資料庫。3,4,5三種情形兩地資料庫都提供讀寫服務,對應用而言是本地訪問資料庫,但到分散式資料庫內部,其要讀寫的資料是否正好在本地就取決於業務和資料庫的拆分設計。有這麼一種情形,B地應用訪問B地資料庫例項,請求的資料的寫入點恰好是A地,這樣會走分散式資料庫內部路由遠端A地例項中拿到資料,效能上會有些下降,而業務可能不知道為什麼。

    OceanBase水平拆分方案

    為了避免在分散式資料庫OceanBase內部發生跨Zone請求,應用的請求流量的水平拆分規則和資料的水平拆分規則要保持一致並聯動,就可以實現真正的應用向本地例項請求讀寫的資料恰好就是在本地例項種。這就是Locality的用途所在。

    首先業務架構層面能根據使用者ID(uid)做拆分,將使用者拆分為100分。x和y是使用者直接相關的表,都根據uid拆分為100個分表,分佈在5個不同的租戶裡。x[00-19]表示20個分表。每個租戶的Leader分別分佈在不同的Zone。uid:00-19表示 分到這20個分片的使用者資料和使用者流量。

    應用層面在某個環節能根據UID將使用者請求轉發到對應的機房(Zone),應用服務之間的請求資訊都有這個UID資訊,後面應用請求都在本機房流轉,並且訪問資料庫時透過分庫分表中介軟體(DBP)和OceanBase的反向代理(OBProxy)就路由到本機房的業務租戶上。

    實際使用這個架構時,有幾個隱含的前提,Zone1和Zone2是同城雙機房,Zone3和Zone4是同城雙機房,兩個城市靠的比較近,Zone5 實際很遠,所以一般不提供寫入。為節省空間,Zone5裡的副本放的是日誌副本。

    應用異地多活架構

    實現OceanBase在每個Zone的應用寫入都是恰好是本地訪問,關鍵點就是應用流量水平拆分規則跟資料水平拆分規則保持一致。而應用要維持這樣一個規則,需要很多產品都要支援水平拆分等。

    流量接入層的“負載均衡”環節負責調整使用者流量到對應的機房(Zone),此後的應用之間的請求就都是本地訪問。

    能使用這個解決方案的業務都是能按使用者維度做水平拆分。有些業務的拆分維度跟使用者維度是衝突的,或者有些業務的資料只支援集中寫入等,不能做到上面這種多活,但也可以使用OceanBase,實現單點寫入,多點讀取的功能。

  • 中秋節和大豐收的關聯?
  • 想物件的說說短句高冷?