Andy這篇論文的題目很騷,好像他之前列的題目是最好的關於。。。的論文,被評委斃了,反正意思就是特別自信,特別牛逼。
執行器優化,是AP引擎的核心問題,對當然后續AP和TP的邊界會越來越模糊,總之需要大量計算的引擎,執行器就會成為瓶頸
尤其是當前硬件的進化,導致原先成為系統瓶頸的IO已經慢慢不再是瓶頸,那么執行和CPU的瓶頸一定是后續主要待解決的問題
所有數據庫的執行,都是基於執行樹,
傳統的方式都是自頂而下,Volcano模式,從頂往下依次調研next,tuple-at-a-time,這種方式對CPU不太友好,但是傳統數據庫的瓶頸在IO
自然,你也可以自底向上,data-centric模式,簡單理解,就是batch processing模式,Spark處理數據的方式就是典型的例子,每個算子都一次性把所有數據處理完,把中間結果傳給上層的算子
傳統的方式為什么不用data-centric?
直覺的想想,這個方法沒法直接用,尤其是對tp場景,我只需要查一條數據,但是你底層需要把所有的數據都處理一遍,並且要存儲大量的中間結果,明顯是無法接受的
但對於AP場景,因為AP場景往往需要掃描基本全量數據,所以這個時候你用Volcano就很低效了,所以明顯data-centric更適合於分析場景
並且做些優化,那么data-centric模式就會產生比較好的效果,
codegen就是這樣主要的優化方式,
傳統的數據執行器,都是interpreter,解釋執行,一個一個operator去執行;解釋執行的問題是,大量虛函數調用,這個是非確定性尋址,對CPU非常不友好,因為CPU Pipline無法預判
codegen主要的優化就是把多個operator合並編譯成一個可執行機器code,比如論文里面經常看到的詞fuse,看着比較唬人,知道spark里面有stage的概念,一個意思,就是這些operator可以pipeline執行,不需要cache中間結果。這樣就可以大大優化執行效率。
JIT,just-in-time,這是codegen的一種方式,就是在運行時編譯,你說為啥一定要運行時編譯,我提前編譯好不行,當然可以,但某些情況下,比如用戶提交的一個查詢,一個udf,這個只有在運行時才知道,所以需要JIT編譯,所以JIT只是codegen的一種形式,不等同於codegen
LLVM,Low Level Virtual Machine,可以理解成一套可定制的編譯器框架,提供,IR,中間表示語言,理解成介於高級語言和機器語言中間的語言
為啥需要LLVM,直接用java或c++的編譯器不行,可以但是一般通用編譯器對於執行優化做的不行,所以你如果用通用編譯器生成的機器碼,效率不高
LLVM的中間表示,編程語言無關的,你在任何編程框架中,都可以調用sdk編寫,並最終編譯成優化過的機器碼
那再回到volcano模型,到底什么是Vectorized,
其實說簡單也簡單,就是本來是next一個tuple,但現在next一組tuple
所以核心ideal就是amortization,每調用一次函數,處理的數據更多了,並且如果每次只處理一列數據,那么對於cpu cache更友好,所以Vectorize往往針對列存,但注意不是不能用於行存,只是列存天然適合向量化執行,向量化本身只是指bath執行
所以文中,對於Vectorize兩個約束,
給出的例子是,
向量化,常常提到SIMD,Single Instruction Multiple Data,這個是CPU指令的擴展,如果用上SIMD,那么向量化執行的效率會更高,但SIMD本身不代表向量化的全部
文中后續,實現了兩種原型,Tectorwise和Typer,分別進行一系列測試,比較到底哪一種模式更好,結論是差不多
這個領域還不成熟,所以名詞特別多,容易繞暈,這篇主要就是把概念澄清一下
各種技術間組合也不是固定的,data-centric是否可以用向量化,volcano是否可以codegen,是否有一個系統可以把所有方法集成在一起?拭目以待