自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Impala是如何提升3~90倍查詢效率的?

云計(jì)算
我們?cè)诖a生成的投資已經(jīng)獲得回報(bào),同時(shí)也期望通過持續(xù)的升級(jí)查詢引擎獲得更好的新能提升。對(duì)于列式數(shù)據(jù)格式,將有更高效的編碼,以及更大的(內(nèi)存)緩存,我們期待I/O性能戲劇性的提升,這導(dǎo)致CPU的性能越來越重要。

Cloudera Impala是基于Hadoop的實(shí)時(shí)檢索引擎開源項(xiàng)目,其效率較Hive提升3~90倍,詳見Cloudera的 blog。

為什么是代碼生成?

這一切的基礎(chǔ)是最優(yōu)的查詢引擎一定是原生的應(yīng)用,因?yàn)樗鼈冡槍?duì)你的數(shù)據(jù)格式而開發(fā),而且僅僅支持你的查詢。舉個(gè)例子,這是一個(gè)理想的代碼:

1
2
3
select count(*)
from tbl
where col like %XYZ%

這與 grep -c "XYZ" tbl 的效率一樣高。

另一個(gè)例子,select sum(col) from tbl。如果表格只有一個(gè)int64的列,使用little endian編碼,這可以通過專用的應(yīng)用來運(yùn)行:

1
2
3
4
5
int64_t sum = 0;
int64_t* values = (int64_t*)buffer;
for (int i = 0; i < num_rows; ++i) {
  sum += values[i];
  }

這兩個(gè)查詢都是十分合理的(因?yàn)榈诙未a用于列式的數(shù)據(jù)),不過在運(yùn)行已有的查詢引擎時(shí)會(huì)變得緩慢。(這是假設(shè)強(qiáng)制執(zhí)行的情況;一個(gè)數(shù)據(jù)庫(kù)當(dāng)然可以使用索引或者預(yù)先計(jì)算的值來運(yùn)行,其效率要高過簡(jiǎn)單的應(yīng)用。當(dāng)然,這里的技術(shù)同樣應(yīng)該使用非強(qiáng)制執(zhí)行策略來實(shí)現(xiàn)。)這是因?yàn)槿缃竦膽?yīng)用程序大多數(shù)都遵循了添加多種執(zhí)行開銷這一解釋方法。 #p# 

增加的運(yùn)行成本來自:

調(diào)用虛函數(shù)。沒有編譯就解釋執(zhí)行表達(dá)式(例如col1 + col2 < col3),致使在每個(gè)表達(dá)式上產(chǎn)生虛函數(shù)調(diào)用。(這當(dāng)然依賴于安裝啟用,但是我們,也可能包括大多數(shù)其它人采用一種類似“Eval”函數(shù),每一個(gè)操作符都會(huì)生效。)在這種情況下,表達(dá)式自身占用資源很少,但虛函數(shù)調(diào)用的資源占用是很多的。

各種類型的大的代碼分支判斷,操作符,以及沒有被查詢引用的函數(shù)。分支預(yù)測(cè)器可以緩和這類問題,但同時(shí)分支指令會(huì)阻止流水線的效率以及指令集的并行性。

不能傳送所有的常量。Impala能計(jì)算一個(gè)固定寬度的元組格式(列3字節(jié)偏移值為16)。好處是這些常量不用重復(fù)寫入代碼,而不用在內(nèi)存中去查找。

生成代碼的目標(biāo)就是讓每個(gè)查詢都使用同樣數(shù)量的指令,就像定制代碼一樣,因?yàn)椴樵儓?zhí)行支持廣泛的功能, 工具可以精確的匹配查詢,而并不需要額外的資源。

Impala的IR(Intermediate Representation)使用

在SQL語(yǔ)義分析階段后,我們?yōu)椴樵兊牟僮鞣瑟?dú)立的“內(nèi)核”代碼:這意味著代碼內(nèi)部循環(huán)花費(fèi)了大部分CPU周期。在代碼生成的時(shí)候,我們知道所有類型,包括元組的布局、SQL操作以及表達(dá)式都將用于這個(gè)查詢。其結(jié)果是非常緊密的內(nèi)循環(huán)并與所有函數(shù)調(diào)用內(nèi)聯(lián),并且沒有外來的指令。

我們首先需要得到IR函數(shù)對(duì)象的代碼路徑。LLVM提供兩種機(jī)制生成IR。第一種是使用LLVM的IrBuilder (C++) API,通過它編程生成IR, 逐條按指令產(chǎn)生。第二種方式是是用Clang的編譯器將C++源碼轉(zhuǎn)換成IR。Impala同時(shí)使用這兩種方式。

簡(jiǎn)單的說,關(guān)于執(zhí)行代碼生成,我們:

通過IRBuilder生成IR,可以獲得更高效率的代碼以及附加的運(yùn)行時(shí)間信息。

我們需要為函數(shù)讀取預(yù)編譯的IR,但不會(huì)從運(yùn)行時(shí)間信息中獲取價(jià)值。

通過同時(shí)使用以上的1和2方法來置換調(diào)用的函數(shù)。這讓我們可以把本應(yīng)該用虛函數(shù)實(shí)現(xiàn)的地方改用內(nèi)聯(lián)來實(shí)現(xiàn)。

LLVM優(yōu)化隨同一些我們定制的優(yōu)化一同進(jìn)行。這與將你的代碼進(jìn)行優(yōu)化編譯很相似,要考慮很多事情。除了可以有更少的代碼,這一步還可以幫助去掉子表達(dá)式、常量傳播、更多函數(shù)插入、指令重排序、無用代碼去除以及其它編譯優(yōu)化技術(shù)。

運(yùn)行時(shí)進(jìn)行編譯執(zhí)行優(yōu)化將IR轉(zhuǎn)換到機(jī)器編碼。LLVM返回一個(gè)函數(shù)指針,用于替代請(qǐng)求引擎的解釋函數(shù)。 #p# 

實(shí)例和結(jié)果

關(guān)于代碼生成話題,我們討論最多的問題是究竟可以提升多少速度?性能有多大變化?

這是一個(gè)運(yùn)行 TPCH-Q1查詢的測(cè)試,該集群擁有10個(gè)數(shù)據(jù)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)有10塊硬盤、48GB內(nèi)存以及8核CPU(16個(gè)超線程)。查詢代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
select
  l_returnflag,
  l_linestatus,
sum(l_quantity),
  sum(l_extendedprice),
  sum(l_extendedprice * (1 - l_discount)),
  sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)),
  avg(l_quantity),
  avg(l_extendedprice),
  avg(l_discount),
  count(1)
from
tpch.lineitem
where
   l_shipdate<='1998-09-02'
group by
   l_returnflag,
   l_linestatus

Impala以操作樹的形式來批處理數(shù)據(jù)元組,在這個(gè)例子里,有兩個(gè)操作符:一個(gè)是掃描并讀取磁盤上的數(shù)據(jù),另一個(gè)是哈希聚合,其中包括了求和和求平均值。

我們將關(guān)注點(diǎn)放到聚合這步。對(duì)于哈希聚合,我們一批一批的對(duì)元組進(jìn)行迭代,評(píng)估并哈希分組列(l_returnflags and l_linestatus),檢查哈希表,然后評(píng)估聚合表達(dá)式(求和、平均值以及select的元素個(gè)數(shù))。對(duì)于聚合的操作符,代碼生成階段編譯所有的行組進(jìn)入一個(gè)獨(dú)立的完整內(nèi)聯(lián)循環(huán)的評(píng)估邏輯。

我們將在兩個(gè)不同大小的數(shù)據(jù)集上運(yùn)行這個(gè)查詢,首先將在1TB的數(shù)據(jù)集上運(yùn)行,接下來在100GB的數(shù)據(jù)集上運(yùn)行。文件順序用 Snappy塊壓縮。對(duì)于100GB的數(shù)據(jù)集,它足夠小以適應(yīng)集群的操作系統(tǒng)緩存。這可以防止可能出現(xiàn)的磁盤性能瓶頸。

 

 

對(duì)于這兩個(gè)數(shù)據(jù)集,代碼生成可以減少2/3的查詢時(shí)間。所有的生成代碼的時(shí)間大約150ms。(生成代碼可以通過設(shè)置查詢時(shí)的參數(shù)打開或關(guān)閉,所以你可以做同樣的測(cè)試。你可以通過在Impala的shell中輸入‘set’來查看查詢選項(xiàng)。) 為了更長(zhǎng)遠(yuǎn)的生成代碼所帶來的好處,我們可以對(duì)比更詳細(xì)的數(shù)值。在這里例子中,查詢運(yùn)行在一臺(tái)服務(wù)器上,它的數(shù)據(jù)集小得多(只有700MB)。使用 perf stat工具,它通過概括精簡(jiǎn)的方式提供被調(diào)試程序運(yùn)行的整體情況和匯總數(shù)據(jù)。結(jié)果來自5次查詢后的匯總。

 

 

你能發(fā)現(xiàn),沒有代碼生成的情況下,我們的指令運(yùn)行了兩次,分支錯(cuò)誤多過了兩倍。

結(jié)論

我們?cè)诖a生成的投資已經(jīng)獲得回報(bào),同時(shí)也期望通過持續(xù)的升級(jí)查詢引擎獲得更好的新能提升。對(duì)于列式數(shù)據(jù)格式,將有更高效的編碼,以及更大的(內(nèi)存)緩存,我們期待I/O性能戲劇性的提升,這導(dǎo)致CPU的性能越來越重要。

代碼生成對(duì)執(zhí)行簡(jiǎn)單表達(dá)式的查詢性能非常有幫助。例如,一個(gè)使用常用表達(dá)式的查詢對(duì)每一行的性能提升不會(huì)很明顯,因?yàn)榻忉尦杀疽儆谡齽t表達(dá)式的運(yùn)行時(shí)間。

目前的Impala 0.5版里仍然還有部分執(zhí)行路徑?jīng)]有被轉(zhuǎn)化為本地代碼,我們還沒有時(shí)間來完成。大部分的代碼補(bǔ)丁將會(huì)集成在即將推出的GA發(fā)行版中。我們有很多方法,讓GA發(fā)行版的代碼生成發(fā)揮最大的優(yōu)勢(shì)。

責(zé)任編輯:王程程 來源: Cloudera
相關(guān)推薦

2012-10-29 09:55:52

HadoopImpalaDremel

2025-02-26 00:15:30

2022-12-13 08:45:01

3F傾聽模型

2017-05-10 16:09:12

MySQL數(shù)據(jù)庫(kù)查詢

2017-05-11 11:30:43

MySQL查詢速度

2015-10-14 13:04:37

阿里云云棲大會(huì)

2024-07-10 09:07:09

2015-10-15 11:06:59

2023-03-09 07:51:23

性能提升數(shù)據(jù)庫(kù)

2024-08-19 00:40:00

SQL數(shù)據(jù)庫(kù)

2018-01-19 09:00:37

2023-06-27 13:49:00

GPU通信RLHF

2025-02-24 08:24:39

2024-03-18 10:19:15

AI藥物研發(fā)

2015-07-28 10:42:34

DevOpsIT效率

2023-12-01 15:54:44

2014-04-01 09:52:46

MySQL

2024-06-27 11:22:34

2024-10-29 08:21:05

2012-11-21 17:35:21

Oracle技術(shù)嘉年華
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)