OceanBase-【OBCP】認證-第二章 OB 儲存引擎高階技術

上帝_BayaiM發表於2024-08-26
第二章 OB 儲存引擎高階技術

記憶體管理
記憶體資料落盤策略-合併和轉儲

LSM Tree 技術簡介

LSM Tree(The Log-Structured Merge-Tree)核心特
點是利用順序寫來提高寫效能
◼ 將某個物件(Partition)中的資料按照“key-value”
形式在磁碟上有序儲存(SSTable)
◼ 資料更新先記錄在MemStore中的MemTable裡,然後
再合併(Merge)到底層的SSTable裡
◼ SSTable和MemTable之間可以有多級中間資料,同樣以
key-value形式儲存在磁碟上,逐級向下合併



基於LSM Tree 的實踐:合併

OceanBase中最簡單的LSM Tree只有C0層(MemTable)和C1層(SSTable)。兩層資料的合併過程如下:
1. 將所有observer上的MemTable資料做大版本凍結(Major Freeze),其餘記憶體作為新的MemTable繼續使用
2. 將凍結後的MemTable資料合併(Merge)到SSTable中,形成新的SSTable,並覆蓋舊的SSTable
3. 合併完成後,凍結的MemTable記憶體才可以被清空並重新使用


合併的細化
合併按照合併的宏塊的不同,可以細化為全量合併、增量合併,漸進合併三種方式:
◼ 全量合併:合併時間長,耗費IO和CPU。把所有的靜態資料都讀取出來,和動態資料歸併,再寫到磁碟中
◼ 增量合併:只會讀取被修改過的宏塊資料,和動態資料歸併,並寫入磁碟,對於未修改過的宏塊,則直接重用
◼ 漸進合併:每次全量合併一部分,若干輪次後整體資料被重寫一遍



基於LSM Tree 的實踐:轉儲
為了解決2層LSM Tree合併時引發的問題(資源消耗大,記憶體釋放速度慢等),OB引入了“轉儲”機制(C1層):
◼ 將MemTable資料做小版本凍結(Minor Freeze)後寫到磁碟上單獨的轉儲檔案裡,不與SSTable資料做合併
◼ 轉儲檔案寫完之後,凍結的MemTable記憶體被清空並重新使用
◼ 每次轉儲會將MemTable資料與前一次轉儲的資料合併(Merge),轉儲檔案最終會合併到SSTable中


分層轉儲
為了最佳化轉儲越來越慢的問題,引入了“分層轉儲”機制:
◼ 多層compaction策略:新增L0 層:被凍結的MemTable 會
直接flush 為Mini SSTable,可同時存在多個Mini SSTable。
◼ 架構變化: 3層Vs 4層
⚫ 3層架構:memtable + minor sstable(L1) + major
sstable (L2)
⚫ 4層架構:memtable + mini sstable(L0) + minor
sstable(L1) + major sstable (L2)
◼ 引數minor_compact_trigger 控制L0層Mini SSTable 總數
◼ 引數major_compact_trigger 控制memtable dump flush次
數達到時觸發major compaction


--------------------------------------------------------------

轉儲的基本概念
轉儲功能的引入,是為了解決合併操作引發的一系列問題
◼ 資源消耗高,對線上業務效能影響較大
◼ 單個租戶MemStore使用率高會觸發叢集級合併,其它租戶成為受害者
◼ 合併耗時長,MemStore記憶體釋放不及時,容易造成MemStore滿而資料寫入失敗的情況
轉儲的基本設計思路
◼ 每個MemStore觸發單獨的凍結(freeze_trigger_percentage)及資料合併,不影響其它租戶
◼ 也可以透過命令為指定租戶、指定observer、指定分割槽做轉儲
◼ 只和上一次轉儲的資料做合併,不和SSTable的資料做合併



轉儲相關引數
minor_freeze_times
◼ 控制兩次合併之間的轉儲次數,達到此次數則自動觸發合併(Major Freeze)
◼ 設定為0表示關閉轉儲,即每次租戶MemStore使用率達到凍結閾值(freeze_trigger_percentage)都直接觸發叢集合併

minor_merge_concurrency
◼ 併發做轉儲的分割槽個數;單個分割槽暫時不支援拆分轉儲,分割槽表可加快速度
◼ 併發轉儲的分割槽過少,會影響轉儲的效能和效果(比如MemStore記憶體釋放不夠快)
◼ 併發轉儲的分割槽過多,同樣會消耗過多資源,影響線上交易的效能



【轉儲適用的場景】

轉儲功能比較適用於以下場景

1. 批處理、大量資料匯入等場景,寫MemStore的速度很快,需要MemStore記憶體儘快釋放
2. 業務峰值交易量大,寫入MemStore的資料很多,但又不想在峰值時段觸發合併(Major Freeze),希望能將合併延後

【轉儲場景的常用配置方法】

1. 減小freeze_trigger_percentage的值(比如40),使MemStore儘早釋放,進一步降低MemStore寫滿的機率
2. 增大minor_freeze_times的值,儘量避免峰值交易時段觸發合併(Major Freeze),將合併的時機延後到交易低谷時段的每日合併(major_freeze_duty_time)



轉儲對資料庫的影響
轉儲的優勢
◼ 每個租戶的轉儲不影響observer上其它的租戶,也不會觸發叢集級轉儲,避免關聯影響
◼ 資源消耗小,對線上業務效能影響較低
◼ 耗時相對較短,MemStore更快釋放,降低發生MemStore寫滿的機率
轉儲的副作用
◼ 資料層級增多,查詢鏈路變長,查詢效能下降
◼ 冗餘資料增多,佔用更多磁碟空間



手動觸發轉儲

ALTER SYSTEM MINOR FREEZE
[{TENANT[=] (‘tt1' [, 'tt2'...]) | PARTITION_ID [=] 'partidx%partcount@tableid‘}]
[SERVER [=] ('ip:port' [, 'ip:port'...])];

◼ 可選的控制引數
	⚫ tenant : 指定要執行minor freeze的租戶
	⚫ partition_id : 指定要執行minor freeze的partition
	⚫ server : 指定要執行minor freeze的observer
	
◼ 當什麼選項都不指定時,預設對所有observer上的所有租戶執行轉儲
◼ 手動觸發的轉儲次數不受引數minor_freeze_times的限制,即手動觸發的轉儲次數即使超過設定的次數,也不會觸
發合併(Major Freeze)



檢視轉儲記錄
MemStore使用率達到freeze_trigger_percentage而觸發的租戶級轉儲,在__all_server_event_history表中


轉儲相關引數

major_compact_trigger /minor_freeze_times

• 控制兩次合併之間的轉儲次數,達到此次數則自動觸發合併(Major Freeze)。
• 設定為 0表示關閉轉儲,即每次租戶MemStore使用率達到凍結閾值(freeze_trigger_percentage)
都直接觸發叢集合併。

minor_merge_concurrency
• 併發做轉儲的分割槽個數;單個分割槽暫時不支援拆分轉儲,分割槽表可加快速度。
• 併發轉儲的分割槽過少,會影響轉儲的效能和效果(比如MemStore記憶體釋放不夠快)。
• 併發轉儲的分割槽過多,同樣會消耗過多資源,影響線上交易的效能。





OB合併觸發方式-定時合併

由major_freeze_duty_time引數控制定時合併時間,可以修改引數控制合併時間:
alter system set major_freeze_duty_time='02:00';


OB合併觸發方式-MemStore使用率達到閾值自動合併

當租戶的MemStore記憶體使用率達到freeze_trigger_percentage引數的值, 並且轉儲的次數已經達到了minor_freeze_times引數的值,會自動觸發合併。
◼ 透過查詢(g)v$memstore檢視來檢視各租戶的memstore記憶體使用情況
◼ 查轉儲次數:gv$memstore, __all_virtual_tenant_memstore_info 中freeze_cnt 列

OB合併觸發方式-手動合併

可以在"root@sys"使用者下,透過以下命令發起手動合併(忽略當前MemStore的使用率):
alter system major freeze;


◼ 合併發起以後,可以在"oceanbase"資料庫裡用以下命令檢視合併狀態:
select * from __all_zone; 或者select * from __all_zone where name = 'merge_status';


三種合併觸發方式

• 定時合併 (自動合併)
• MemStore使用率達到閾值自動合併 (自動合併)
• 手動合併



OB合併方式:MemStore使用率達到閾值自動合併

當租戶的 MemStore記憶體使用率達到freeze_trigger_percentage引數的值, 並且轉儲的次數已經達到了
major_compact_trigger/minor_freeze_times引數的值,會自動觸發合併:

• 透過查詢(g)v$memstore檢視來檢視各租戶的memstore記憶體使用情況。

• 可以修改以下引數的值來影響觸發合併的時機:

alter system set freeze_trigger_percentage = 40;
alter system set major_compact_trigger = 100;





OceanBase每日合併策略
合併排程
手動合併自動合併
自動輪轉合併自動非輪轉合併
智慧輪轉合併指定順序的輪轉合併

可透過以下幾項控制每日合併的策略
◼ enable_manual_merge: OB的配置項,
指示是否開啟手動合併
◼ enable_merge_by_turn: OB的配置項,
指示是否開啟自動輪轉合併
◼ zone_merge_order: 指定自動輪轉合
並的合併順序

OB輪轉合併示例
假設叢集中的設定是zone_merge_order = 'z1,z2,z3,z4,z5',zone_merge_concurrency = 3,一次輪轉合併的大概
過程如下:

合併版本
設定SSTable中保留的資料合併版本個數
◼ 由引數max_kept_major_version_number控制,預設值為2。
◼ 調大引數值可以保留更多歷史資料,但同時佔用更多的儲存空間。
◼ 在hint中利用frozen_version(<major_version>)指定歷史版本。




設定輪轉合併順序

• 合併開始前,透過引數zone_merge_order設定合併順序;只對輪轉合併有效。

• 場景舉例
假設叢集中有三個zone,分別是z1,z2,z3,想設定輪轉合併的順序為"z1 -> z2 -> z3",步驟如下:

alter system set enable_manual_merge = false; -- 關閉手動合併
alter system set enable_merge_by_turn = true; -- 開啟輪轉合併
alter system set zone_merge_order = 'z1,z2,z3'; -- 設定合併順序

• 取消自定義的合併順序

alter system set zone_merge_order = ''; -- 取消自定義合併順序



合併注意事項

合併超時時間

• 由引數zone_merge_timeout定義超時閾值;預設值為'3h'(3個小時)。

• 如果某個ZONE的合併執行超過閾值,合併狀態被設定為TIMEOUT。

空間警告水位

• 由引數data_disk_usage_limit_percentage定義資料盤空間使用閾值,預設值90。

• 當資料盤空間使用量超過閾值後,合併任務列印ERROR警告日誌,合併任務失敗;需要儘快擴大資料盤物理空
間,並調大data_disk_usage_limit_percentage引數的值。

• 當資料盤空間使用量超過閾值後,禁止資料遷入。



檢視合併記錄和狀態:

__all_rootservice_event_history表,檢視合併記錄:
__all_zone表,	檢視當前合併狀態:




小結
◼ OB的LSMTree可以分為C0層(MemTable)、C1層(Minor SSTable)、C2層(Major SSTable)
◼ OB記憶體透過雙索引結構和資料壓縮,提高資料的查詢效能
◼ 合併和轉儲之前,都需要做一次凍結,然後根據引數設定決定凍結之後是轉儲還是合併
◼ 合併可以細分為全量合併、漸進合併、增量合併三種方式,同一個資料庫,這三種方式對資源的消耗程度遞減
◼ 為了最佳化轉儲越來越慢的問題,引入了“分層轉儲”機制,為了提高轉儲速度,加快記憶體釋放速度,被凍結的
MemTable 會直接flush 為Mini SSTable
◼ 輪轉合併可以輪流為每份副本單獨做合併,減少業務影響,但同時也存在合併時間變長、切主過程中影響長連線等
問題
◼ 合併和轉儲特點的比較,兩者互補共同組成了OB資料完整的落盤策略

  

相關文章