天天看點

opengauss 《Industrial-Strength OLTP Using Main Memory and Many Cores》ABSTRACT1. INTRODUCTION2. ADJUSTING THE ENGINE3. INTEGRATION WITH GAUSSDB4. EXPERIMENTAL RESULTS5. RELATED WORK6. CONCLUSION

該論文詳細介紹了opengauss記憶體庫的工程實作,原理請參考《Speedy Transactions in Multicore In-Memory Databases》 https://ata.alibaba-inc.com/articles/216581

ABSTRACT

GaussDB和開源版本的openGauss是TP型資料庫,本文展示了其面向main memory和多核的優化,在TaiShan伺服器上TPCC有2.5倍的提升。

1. INTRODUCTION

2012年研發OLAP,2015年釋出,FusionInsight MPPDB,GaussDB200

2017年研發下一代OLTP,為了滿足來自高端使用者的5個需求:

  1. 基于share-nothing架構的scale-out能力;
  2. 多核的scale-up能力;
  3. 大記憶體;
  4. SQL相容;
  5. 高可用;

政策是基于GaussDB研發一款記憶體資料庫,可以服用GaussDB的SQL相容和HA能力。

基于PostgreSQL9.2,繼承了MPPDB的線程模型。

本文要讨論GaussDB的記憶體資料庫:Memory-Optimized Tables,下文簡稱為mot。

1.1 System Architecture

GaussDB的整體架構如下圖所示,典型的sharenothing系統:單機DB+2PC和全局事務管理。mot做為單機的存儲引擎,是以可以完整複用已有的SQL,執行器,分布式事務,HA等。

mot的記憶體管理:感覺NUMA的内管管理,2MB chunk

opengauss 《Industrial-Strength OLTP Using Main Memory and Many Cores》ABSTRACT1. INTRODUCTION2. ADJUSTING THE ENGINE3. INTEGRATION WITH GAUSSDB4. EXPERIMENTAL RESULTS5. RELATED WORK6. CONCLUSION

1.2 Internal Architecture

mot底層使用無鎖的masstree,并發控制協定使用Silo,并對進行了工程上的增強。Silo的論文參考《Speedy Transactions in Multicore In-Memory Databases》

mot在使用masstree時key的長度從29位元組增加到了45位元組。

mot并發控制協定的選擇考慮如下因素:

  1. OCC:Silo和TicToc分3個階段。并發事務無需等待,僅僅在validation階段做檢測,适當的abort;
  2. Encounter time locking (ETL):樂觀讀,寫者上鎖。是以,并發的寫者能互相感覺并做abort。ETC和相比OCC:一方面能提前檢測沖突,減少無用功;另一方面能加速Read-after-writes;
  3. Pessimistic concurrency control (2PL):

結論:OCC更加适合多核(參考《Staring into the abyss: An evaluation of concurrency control with one thousand cores》)。mot選擇了Silo的算法,相比于TicToc,Silo算法比較簡潔而且大部分負載情況下性能表現差不多。

mot表大小受限于内容大小,當然可以進一步優化來提升表大小,比如:anti-caching和tiering。

2. ADJUSTING THE ENGINE

2.1 Indexing and Storage

引入類似HOT機制,在更新一個行時不用每次都更新索引樹,而是跟新這一行的sentinels(類似BTree索引中的IndexTuple)。

opengauss 《Industrial-Strength OLTP Using Main Memory and Many Cores》ABSTRACT1. INTRODUCTION2. ADJUSTING THE ENGINE3. INTEGRATION WITH GAUSSDB4. EXPERIMENTAL RESULTS5. RELATED WORK6. CONCLUSION

2.1.1 Optimistic inserts優化

在Silo基礎上,mot完善了基于OCC的insert優化。

2.1.1.1 Motivation.

OCC的3個階段中,insert先在本地操作僅僅在commit時檢測沖突。是以需要優化:

  1. 并發事務insert相同的key,如何保證唯一性;
  2. insert的事務最終abort;
  3. 同一個事務插入相同的key;
  4. 如何insert多個索引樹;

2.1.1.2 Implementation Details.

Silo處理插入key為K流程:

  1. 如果K已經對應一個已送出record,本事務abort;
  2. 否則,生成record為R,狀态為ABSENT,索引樹中插入K->R;
  3. 如果發現已存在ABSENT的record,則直接複用(先成功插入者為準);

mot對Silo插入流程的改進:

  1. DoubleRow:同一行插入到在不同索引樹上,導緻部分索引樹沖突;
  2. Self Inserted:事務需要識别索引樹上哪些ABSENT狀态的record是自己插入的;
opengauss 《Industrial-Strength OLTP Using Main Memory and Many Cores》ABSTRACT1. INTRODUCTION2. ADJUSTING THE ENGINE3. INTEGRATION WITH GAUSSDB4. EXPERIMENTAL RESULTS5. RELATED WORK6. CONCLUSION

2.1.2 Non-unique indexes

在key之後增加字尾:8個位元組的row指針。

2.2 Concurrency Control

read after write hazard:occ實作的事務中,如何讀取本事務剛剛寫入的資料。

mot的優化:實作了一個access-set結構,記錄本事務read,update,insert,deleted集合。

維護每個key的狀态的狀态轉換。送出時從access-set上提取出write-set和insert-set。

和Silo不同的是,mot支援了RC隔離級别:不對read-set做校驗。

read-set:如果高于RC級别,對read-set做沖突檢測;

write-set:對row上鎖;

insert-set:對sentinel上鎖;

opengauss 《Industrial-Strength OLTP Using Main Memory and Many Cores》ABSTRACT1. INTRODUCTION2. ADJUSTING THE ENGINE3. INTEGRATION WITH GAUSSDB4. EXPERIMENTAL RESULTS5. RELATED WORK6. CONCLUSION

3. INTEGRATION WITH GAUSSDB

由于GaussDB是基于早起PostgreSQL做的開發,并沒有storage engine的概念,是以mot是通過FDW機制來實作。同時,也需要對原有FDW做相應的擴充,比如:在create table/index時在本地觸發對mot的DDL操作。

opengauss 《Industrial-Strength OLTP Using Main Memory and Many Cores》ABSTRACT1. INTRODUCTION2. ADJUSTING THE ENGINE3. INTEGRATION WITH GAUSSDB4. EXPERIMENTAL RESULTS5. RELATED WORK6. CONCLUSION

3.1 Tables and Indexes Created and Used

建立FDW函數:ValidateTableDef

fdwroutine->AddForeignUpdateTargets = MOTAddForeignUpdateTargets;
    fdwroutine->GetForeignRelSize = MOTGetForeignRelSize;
    fdwroutine->GetForeignPaths = MOTGetForeignPaths;
    fdwroutine->GetForeignPlan = MOTGetForeignPlan;
    fdwroutine->PlanForeignModify = MOTPlanForeignModify;
    fdwroutine->ExplainForeignScan = MOTExplainForeignScan;
    fdwroutine->BeginForeignScan = MOTBeginForeignScan;
    fdwroutine->IterateForeignScan = MOTIterateForeignScan;
    fdwroutine->ReScanForeignScan = MOTReScanForeignScan;
    fdwroutine->EndForeignScan = MOTEndForeignScan;
    fdwroutine->AnalyzeForeignTable = MOTAnalyzeForeignTable;
    fdwroutine->AcquireSampleRows = MOTAcquireSampleRowsFunc;
    fdwroutine->ValidateTableDef = MOTValidateTableDef;
    fdwroutine->PartitionTblProcess = NULL;
    fdwroutine->BuildRuntimePredicate = NULL;
    fdwroutine->BeginForeignModify = MOTBeginForeignModify;
    fdwroutine->ExecForeignInsert = MOTExecForeignInsert;
    fdwroutine->ExecForeignUpdate = MOTExecForeignUpdate;
    fdwroutine->ExecForeignDelete = MOTExecForeignDelete;
    fdwroutine->EndForeignModify = MOTEndForeignModify;
    fdwroutine->IsForeignRelUpdatable = MOTIsForeignRelationUpdatable;
    fdwroutine->GetFdwType = MOTGetFdwType;
    fdwroutine->TruncateForeignTable = MOTTruncateForeignTable;
    fdwroutine->VacuumForeignTable = MOTVacuumForeignTable;
    fdwroutine->GetForeignRelationMemSize = MOTGetForeignRelationMemSize;
    fdwroutine->GetForeignMemSize = MOTGetForeignMemSize;
    fdwroutine->GetForeignSessionMemSize = MOTGetForeignSessionMemSize;
    fdwroutine->NotifyForeignConfigChange = MOTNotifyForeignConfigChange;      

3.1.1 Index Usage for Planning and Execution

優化器中新增GetForeignPaths。

3.2 Integrating MOT with HA

  1. Logging:複用GaussDB的XLOG來記錄WAL日志,GaussDB并行寫日志,多個并發backend程序插入WAL slot,在commit時接管WAL并flush;
  2. Checkpointing:提供checkpoint的callback函數;
  3. Recovery:提供recover的callback函數,并行recover,每個線程負責一個datasegment;

3.3 VACUUM and DROP

3.3.1 Deleting Pools

基于epoch的gc,新配置設定記憶體區域,将live的資料拷貝到新記憶體區域,老的記憶體區域直接回收掉。

3.3.2 GC and Pools Deletion

3.4 JIT for Query Acceleration

GaussDB已經支援了JIT:

  1. 表達式,比如WHERE子句;
  2. Inline函數;

上述兩種JIT優化是通用的,但近支援了SQL的部分JIT優化,對加速CPU-bound查詢效果顯著,比如OLAP。

而mot選擇對特定OLTP查詢場景進行優化,一旦進入這種場景就是全JIT優化,面向OLTP常用負載:點查、簡單的範圍查詢。

GaussDB的JIT仍然是火山模型的pull-model,mot對特性查詢的sql進行了全JIT支援,是以一旦命中就不需要使用火山模型。

mot并不支援複雜agg函數,比如:groupby,count distinct

4. EXPERIMENTAL RESULTS

4.1 Hardware

環境1:

Huawei ARM64:
TaiShan
Kunpeng920-4826和6426
1TB記憶體
4TB NVMe 3.5GB/s
– 2-sockets of 48 cores, adding to 96 cores. 
– 2-sockets of 64 cores, adding to 128 cores. 
– 4-sockets of 64 cores, adding to 256 cores.      

環境2:

Intel x86:
2socket,每個socket上18實體核,2個超線程,總共72核      

4.2 Benchmark and Configuration

client端和server之間10Gb網絡

所有的測試中,原GaussDB的存儲引擎的資料全部能在記憶體中buffer住,是以測試結果可以忽略IO的影響。

4.3 Results

使用TPCC測試性能和正确性。

opengauss 《Industrial-Strength OLTP Using Main Memory and Many Cores》ABSTRACT1. INTRODUCTION2. ADJUSTING THE ENGINE3. INTEGRATION WITH GAUSSDB4. EXPERIMENTAL RESULTS5. RELATED WORK6. CONCLUSION

結論:ARM單核性能是x86的0.75倍,和主頻成比例,96個ARM核和72個x86核性能相當。

opengauss 《Industrial-Strength OLTP Using Main Memory and Many Cores》ABSTRACT1. INTRODUCTION2. ADJUSTING THE ENGINE3. INTEGRATION WITH GAUSSDB4. EXPERIMENTAL RESULTS5. RELATED WORK6. CONCLUSION

上圖測試擴充性,結論:

  1. mot随着并發增加吞吐增加,大概250并發達到峰值;
  2. 而GaussDB原存儲在并發100時達到峰值;

單條query的加速比

建構表且僅有2個整數,其中一個整數做為primary key。

opengauss 《Industrial-Strength OLTP Using Main Memory and Many Cores》ABSTRACT1. INTRODUCTION2. ADJUSTING THE ENGINE3. INTEGRATION WITH GAUSSDB4. EXPERIMENTAL RESULTS5. RELATED WORK6. CONCLUSION

結論:

  1. insert提升2倍多:原Disk-based的插入需要在page内定位行指針,插入B-Tree也需要定位node,而mot使用masstree;
  2. lookup提升2倍多:原因同上;
  3. delete提升1.5到2倍:mot執行了實體删除,而原Disk-based僅僅是标記,後續vacuum負擔會更大;
  4. update提升3.5倍多:masstree查找更快。
  5. 所有測試中ARM平台提升比x86更加明顯:ARM的relaxed memory對原Disk-based的2PL并發控制不優化,而MOT OCC在這種優化更明顯;

JIT加速

opengauss 《Industrial-Strength OLTP Using Main Memory and Many Cores》ABSTRACT1. INTRODUCTION2. ADJUSTING THE ENGINE3. INTEGRATION WITH GAUSSDB4. EXPERIMENTAL RESULTS5. RELATED WORK6. CONCLUSION
  1. stocklevel無提升:包含mot不支援的複雜agg,同時sql中包含pipeline breaker需要物化;
  2. 其他場景均提升30%;
  3. 在并發300個連接配接時提升更高,OCC允許reader在本地并發執行,減少cache miss;

存在abort時

opengauss 《Industrial-Strength OLTP Using Main Memory and Many Cores》ABSTRACT1. INTRODUCTION2. ADJUSTING THE ENGINE3. INTEGRATION WITH GAUSSDB4. EXPERIMENTAL RESULTS5. RELATED WORK6. CONCLUSION

OCC中事務執行期間不會被阻塞,但是當有競争時需要abort。

上圖中,12個warehouse,120個并發來模拟高比例的競争場景。

  1. 随着并發增加,abort比例上升;
  2. mot整體性能仍然有2倍提升;

Replication對性能的影響

opengauss 《Industrial-Strength OLTP Using Main Memory and Many Cores》ABSTRACT1. INTRODUCTION2. ADJUSTING THE ENGINE3. INTEGRATION WITH GAUSSDB4. EXPERIMENTAL RESULTS5. RELATED WORK6. CONCLUSION

開啟replication時,結論:

  1. mot有7%損耗;
  2. Disk-based有20%損耗;

5. RELATED WORK

  1. Prototypes and Frameworks: DBX提供了對各種并發控制協定算法進行比較的架構:2PL,OCC,Silo。經過測試在華為的機器上Silo性能表現最好;
  2. Microsoft’s Hekaton: SQL的Hekaton是記憶體引擎,也是在commit是進行alidation,類似Silo。不同點是它使用Bw-tree作為索引,read-lock會阻塞寫,雖然能減少abort,但是也降低了并發度,因為需要原子的對共享記憶體區域進行++來實作原子鎖,雖然都是樂觀,Silo更加樂觀;
  3. PostgreSQL Storage Engine:也是用FDW來實作記憶體引擎,功能不完善,缺少二級索引,DDL等;
  4. Mot:相容SQL,工業級記憶體引擎;

6. CONCLUSION

MOT是為衆核和大記憶體設計的記憶體引擎,記憶體管理,并發控制協定,GC都進行了工程上的優化,通過FDW嵌入到GaussDB中,無縫相容SQL引擎,友善使用者使用。