Oracle關于記憶體列存有2篇文章,本文是第一篇。
Abstract
Oracle IMC是第一個商用的dual-format資料庫。行存适用于點查點寫的OLTP,而列存适用于對部分列的OLAP分析。沒有任何一種存儲格式能同時适用于所有的查詢場景。
IMC是純記憶體的列存,支援僅對需要分析的某個表的某個列進行加載。記憶體列存可以應用一些列的AP技術:壓縮,向量化,記憶體索引。基于極快的記憶體掃描速度還可以進行Vector Group By等優化。
OLTP的DML操作需要對相關索引進行更新,使用者為了加速OLAP的查詢而建了大量的索引。而通過Oracle IMC可以去掉這部分索引,不僅能加速OLAP也提升了OLTP的DML性能。
由于Oracle IMC是在scan層,是以Oracle上層的大量文法/函數,高可用等特性都100%相容。
IMC能夠與RAC和Exadata有機結合,使得IMC能夠ScaleOut。
1. INTRODUCTION
随着記憶體越來越大可以預見基于記憶體的Database也會成逐漸為主流,Oracle IMC有如下特性:
Dual format
列存:對少數列,大範圍行操作,适用于OLAP,如:MonetDB,C-Store;
行存:對全部列,小範圍行操作,适用于OLTP,包括記憶體事務型資料庫,如:TimesTen,H-store;
Oracle IMC支援同時行存和列存:
- 資料的DML以行存的方式進行,確定OLTP的負載;
- 在記憶體中實時的轉成列存,用于OLAP的分析負載;
記憶體列存并不要求記憶體翻倍:
- Oracle的Buffer Cache的高命中率,并不需要配置太多Buffer Cache;
- 另外,IMC能替代大部分索引的角色,Buffer Cache的需求量進一步減少;
- 建議80%的記憶體用于IMC;
Unlimited Capacity
并不需要把整個DB中的所有表都加載到記憶體中,隻需要對熱點的表或者分區加載到記憶體。其他表可使用類似Exadata的分層存儲:高容量磁盤,高IO吞吐的PCI Flash ache,低延遲的DRAM。
Complete Transparency
IMC是在access層,對上層執行器層和優化器完全相容,唯一需要考慮的是多了一個scan方法和代價上的不同。
2. NEW IN-MEMORY COLUMNAR FORMAT
Oracle 12.1.0.2釋出的IMC,IMC所占用的記憶體是在SGA中配置設定,和Buffer Cache類似。
Populating the In-Memory Column Store
populate:從持久化存儲的行存加載到記憶體中的列存IMC。
新增關鍵字INMEMORY,可以作用于4類對象:
- Tablespace
- Table
- Partition of a Table
- Sub-Partition within a Partition
populate過程是通過一組程序來并發的完成,程序數目可以配置:inmemory_max_populate_servers
不像其他記憶體資料庫,IMC在加載的時候仍然能夠通過buffercache來提供服務。
對于重要的對象可以優先加載,是以給不同的對象允許賦予不同的加載優先級
In-Memory Compression
前面提到過在SGA中給IMC配置設定一片記憶體:
IMCU:一批行資料(100w);
CU:IMCU中的每個列的記憶體區域,使用使用者指定的壓縮算法進行壓縮;
3種主要的壓縮算法使用不同的場景:
- FOR DML:最低級别的壓縮,适用于有頻繁DML的場景;
- FOR QUERY:大量高頻次的查詢,2到10倍壓縮比,該壓縮無需解壓縮,無需額外記憶體;
- FOR CAPACITY:對容量敏感的應用,5到30倍壓縮比,Oracle自研了OZIP壓縮算法能結合自家硬體協處理器進行解壓縮;
3. QUERY PROCESSING
In-Memory Scans
針對對IMC如下優化技術:
- 向量化:SIMD,提高CPU指令密度;
- bit-packey:列的bit位圖更加緊湊,cache line能裝更多的内容;
- IM索引(範圍):每個CU都有min/max等統計;
- 字典索引,每個IMCU統計每列的distinct;
In-Memory Joins
掃小表,建立緊湊的bloom;
掃大表時減少資料量
In-Memory Aggregations and Groupings
Select Stores.id, Products.id, sum(Sales.revenue)
From Sales, Stores, Products
Where Sales.store_id = Stores.id
And Sales.product_id = Products.id
And Stores.type = “Outlet”
And Products.type = “Footwear”
Group by Stores.id, Products.id;
- 掃描STORES和PRODUCTS;
- KeyVector:每個列在記憶體構造Key Vector,把GroupBy中的key映射到連續的id;
- In-Memory Accumulator:記憶體中構造NxM的矩陣;
- 掃描SALES表,每行如果能在KyeVector中比對上,則把相應的Sales.revenue加到矩陣中;
- 最終矩陣就是Agg的結果;
4. TRANSACTIONAL CONSISTENCY
Oracle預設的隔離級别是Consistent Read,每個事務都有一個單調遞增的時間戳,也就是SCN。
IMC通過SCN支援Consistent Read的隔離級别:
- 在IMCU建立時對應一個SCN(populate時拿一個read SCN);
- 每個IMCU中有一塊SMU:Snapshot Metadata Unit用來跟蹤在read SCN之後對IMCU的更改;
- SMU transaction journal:每個事務如果涉及到IMCU,則變更會也要記錄到SMU中的transaction journal中;
- 掃描IMCU時,除了要掃描IMCU全量資料,也要掃描SMU transaction journal,讀取小于read SCN事務的更改,進行merge;
- 當變更超過了門檻值,則觸發repopulate;
5. IN-MEMORY COLUMN STORE SCALE-OUT
通過CacheFusion協定Oracle支援RAC架構可以擴充多個計算節點,每個計算節點可以存儲部分IMC資料,整體上IMC的容量可以線性擴充。再通過Oracle的Parallel Execution來分布式并行查詢。
Distributionand ParallelExecution
使用者可以通過DISTRIBUTE子句來指定表在不同節點上的分布方式
- DISTRIBUTE BY PARTITION:對于分區表,可以按照子分區來分布,可以支援in-memory partition-wise join;
- DISTRIBUTE BY SUBPARTITION:一級分區可能存在skew問題,此時可以使用二級分區;
- DISTRIBUTE BY ROWID RANGE:按照ROWID RANGE來分布;
- DISTRIBUTE AUTO:根據統計資料自動選擇上述3種;
In-Memory Fault Tolerance
對于Exadata,可以通過DUPLICATE子句指定IMCU的副本,做到IMC的高可用
- 節點間infiniband高速網絡,對于SMU的更新可以直接RDMA;
- 強同步,每個副本都時刻可服務,獨立維護和Populate;
- 小表可以指定ALL;
6. CONCLUSIONS AND FUTURE WORK
Oracle IMC在data access層實作了基于記憶體的dual-format引擎,是以:
- 相容Oracle豐富的功能;
- 極緻的OLAP性能;
- 支援Consistent Read隔離級别;
未來的一個方向是IMC和Automatic Data Optimization的結合,自動做分層管理;另外,大量資料結構原來是基于磁盤來設計的,現在搬到了記憶體中,可以進行深入的調優。
IMC涉及到大量的資料庫子系統,本文僅涉及其中非常小的部分:Data,Space,Transaction,Optimizer,Parallel Execution,RAC,OLAP,Virtual OS,SPARC。