一、通過Presto insert到其他數據源的性能
1、壓測結果
(K是一千,M是一百萬)
源庫 |
源表 |
行數 |
worker數 |
tpch -> hive |
tpch -> es6 |
tpch -> mysql |
|||
耗時(分:秒) |
速率(rows/s) |
耗時(分:秒) |
速率(rows/s) |
耗時(分:秒) |
速率(rows/s) |
||||
tiny |
lineitem |
60K |
4 |
1:57 |
513 |
||||
orders |
15K |
4 |
2:51 |
87 |
|||||
part |
2K |
4 |
2:34 |
12 |
|||||
supplier |
0.1K |
4 |
0:03 |
38 |
|||||
customer |
1.5K |
4 |
3:46 |
6 |
|||||
partsupp |
8K |
4 |
5:29 |
24 |
|||||
sf100 |
lineitem |
600M |
1 |
53:57 |
185K |
||||
4 |
13:28 |
743K |
871:13 |
11.5K |
400:10 |
25K |
|||
orders |
150M |
4 |
2:55 |
855K |
335:50 |
7.44K |
96:20 |
26K |
|
part |
20M |
4 |
0:41 |
485K |
52:12 |
6.38K |
11:18 |
29.5K |
|
supplier |
1M |
4 |
0:05 |
1050K |
0:27 |
36.8K |
0:38 |
26.3K |
|
customer |
15M |
1 |
3:21 |
74.4K |
|||||
4 |
0:25 |
610K |
25:27 |
9.82K |
9:49 |
25.5K |
|||
partsupp |
80M |
4 |
1:17 |
1050K |
211:57 |
6.29K |
43:36 |
30.6K |
|
sf300 |
lineitem |
1800M |
4 |
40:11 |
747K |
||||
orders |
450M |
4 |
8:03 |
932K |
|||||
part |
60M |
4 |
1:56 |
519K |
|||||
supplier |
3M |
4 |
0:06 |
483K |
|||||
customer |
45M |
4 |
1:11 |
634K |
|||||
partsupp |
240M |
4 |
3:28 |
1150K |
轉換成圖表如下所示(縱軸單位1000行/秒,橫軸單位1百萬行):
相同數據量不同數據源的insert速率
2、解讀
隨着worker數的增加,性能線性增長;
隨着數據量的增加,耗時線性增長;
tpch -> hive 速度還是非常快的
tpch -> es6 慢很多,默認配置,未進行參數優化,查了下資料也無可優化寫入的參數,由於速度非常慢,不建議大數據量插入。
tpch -> mysql 也不快,而且在insert時先將數據插入臨時表,然后再從臨時表導入到目標表,這樣會消耗兩倍的磁盤空間和時間,可使用create table as提高性能
3、建議
不建議使用Presto大批量insert數據到ElasticSearch或MySQL,在需要插數據到MySQL時要使用create table as
二、TPCH OLAP性能
1、TPCH介紹
TPC(事務處理性能委員會),由數十家會員公司創建的非盈利組織,功能是制定商務應用基准程序(Benchmark)的標准規范、性能和價格度量,並管理測試結果的發布,其發布的TPCH標准的主要目的是評價特定查詢的決策支持能力,強調數據庫在數據挖掘、分析處理方面的能力,包含22段復雜sql,詳情可見https://yq.aliyun.com/articles/149715?t=t1
由於數據量的大小對查詢速度有直接的影響,TPC- H 標准對數據庫系統中的數據量有嚴格、明確的規定。用SF 描述數據量,1SF 對應1 GB 單位,SF 由低到高依次是1、10、30、100、300、1 000、3 000、10 000。需要強調,SF 規定的數據量只是8個基本表的數據量,不包括索引和臨時表。
2、Hive和TPCH
(1)壓測結果
無預熱,以運行2次的平均時間作為最終運行時間,worker數4,每worker 100G內存
join_distribution_type為PARTITIONED,join_reordering_strategy為ELIMINATE_CROSS_JOINS
查詢語句 |
sf100(基准的10000倍) |
sf300(基准的30000倍) |
sf1000(基准的100000倍) |
||||
HIVE on Presto |
Hive on MR |
TPCH on Presto |
HIVE on Presto |
Hive on MR |
TPCH on Presto |
TPCH on Presto |
|
q01 |
8.599 s ± 470.226 ms |
6.5 m |
8.779 s ± 337.290 ms |
14.363 s ± 173.241 ms |
12.5 m |
26.196 s ± 807.516 ms |
1.422 m ± 3.524 s |
q02 |
10.659 s ± 2.570 s |
>60 m 還未執行完 |
14.194 s ± 661.145 ms |
25.267 s ± 2.235 s |
>60 m 還未執行完 |
39.602 s ± 434.164 ms |
2.112 m ± 3.742 s |
q03 |
10.490 s ± 1.621 s |
8 m |
27.493 s ± 148.492 ms |
28.781 s ± 2.642 s |
11 m |
1.411 m ± 1.800 s |
4.813 m ± 2.956 s |
q04 |
4.152 s ± 57.276 ms |
6.5 m |
29.934 s ± 1.659 s |
10.121 s ± 827.315 ms |
6 m |
1.413 m ± 1.551 s |
4.997 m ± 5.850 s |
q05 |
19.645 s ± 2.247 s |
13 m |
32.882 s ± 510.531 ms |
59.886 s ± 4.129 s |
17.5 m |
1.591 m ± 1.481 s |
5.508 m ± 4.229 s |
q06 |
3.552 s ± 563.564 ms |
2 m |
4.158 s ± 1.613 s |
4.705 s ± 53.033 ms |
1.5 m |
13.544 s ± 1.587 s |
40.434 s ± 193.747 ms |
q07 |
30.973 s ± 1.561 s |
22 m |
47.387 s ± 921.360 ms |
1.545 m ± 1.936 s |
30 m |
2.227 m ± 4.816 s |
7.741 m ± 29.050 s |
q08 |
21.706 s ± 929.845 ms |
>90 m 還未執行完 |
38.677 s ± 147.785 ms |
1.125 m ± 826.608 ms |
>90 m 還未執行完 |
1.993 m ± 1.324 s |
4 worker,超過400G內存限制,資源不足 |
q09 |
30.347 s ± 1.276 s |
>60 m 還未執行完 |
59.550 s ± 996.313 ms |
1.599 m ± 5.453 s |
>60 m 還未執行完 |
2.998 m ± 3.964 s |
4 worker,超過400G內存限制,資源不足 |
q10 |
9.092 s ± 2.391 s |
13 m |
30.500 s ± 357.089 ms |
26.605 s ± 8.540 s |
12 m |
1.486 m ± 404.465 ms |
4.862 m ± 328.805 ms |
q11 |
7.166 s ± 322.441 ms |
7 m |
7.797 s ± 212.132 ms |
21.236 s ± 3.460 s |
10 m |
19.765 s ± 1.293 s |
58.372 s ± 8.522 s |
q12 |
4.087 s ± 171.827 ms |
7 m |
27.380 s ± 189.505 ms |
16.256 s ± 2.787 s |
9 m |
1.407 m ± 845.700 ms |
4.522 m ± 512.652 ms |
q13 |
9.660 s ± 622.961 ms |
5 m |
27.948 s ± 342.240 ms |
22.866 s ± 1.432 s |
10 m |
1.414 m ± 161.220 ms |
4.759 m ± 680.237 ms |
q14 |
4.084 s ± 324.562 ms |
4 m |
30.155 s ± 226.274 ms |
9.168 s ± 263.044 ms |
10 m |
1.514 m ± 303.349 ms |
5.025 m ± 439.113 ms |
q15 |
4.145 s ± 102.530 ms |
6 m |
7.805 s ± 398.101 ms |
10.273 s ± 128.693 ms |
21 m |
19.677 s ± 9.899 ms |
1.084 m ± 1.469 s |
q16 |
4.024 s ± 1.172 s |
8.5 m |
28.806 s ± 488.611 ms |
7.348 s ± 2.382 s |
24.5 m |
1.382 m ± 825.194 ms |
4.616 m ± 557.200 ms |
q17 |
25.625 s ± 1.013 s |
9 m |
36.223 s ± 511.238 ms |
1.252 m ± 613.062 ms |
33 m |
1.898 m ± 450.427 ms |
6.265 m ± 127.279 ms |
q18 |
24.291 s ± 917.825 ms |
20.5 m |
42.352 s ± 132.229 ms |
1.375 m ± 5.720 s |
50 m |
2.239 m ± 1.923 s |
7.535 m ± 2.703 s |
q19 |
4.456 s ± 737.512 ms |
13 m |
32.079 s ± 828.022 ms |
13.788 s ± 1.279 s |
80 m |
1.588 m ± 485.782 ms |
5.250 m ± 1.347 s |
q20 |
7.854 s ± 2.233 s |
4.5 m |
33.239 s ± 598.212 ms |
21.219 s ± 3.412 s |
34.5 m |
1.657 m ± 183.141 ms |
5.460 m ± 1.004 s |
q21 |
58.191 s ± 5.942 s |
18.5 m |
1.072 m ± 1.531 s |
2.648 m ± 2.150 s |
83 m |
3.305 m ± 7.362 s |
4 worker,超過400G內存限制,資源不足 |
q22 |
3.363 s ± 1.896 s |
1.5 m |
25.634 s ± 730.441 ms |
6.997 s ± 1.295 s |
2 m |
1.245 m ± 3.536 ms |
4.184 m ± 801.859 ms |
轉換成圖表后如下所示(縱軸單位是秒):
同一數據量下的比較
不同數據量TPCH on Presto的表現:
(2)解讀
隨着worker數的增加,性能線性增長;
隨着數據量的增加,耗時低於線性增長,對於批量處理的優化還是比較高的;
當Hive由MR引擎更換到Presto引擎后,性能提升是顯著的,可以將原來小時級的任務加速到秒級;
由於插入數據是比較耗時的,所以又測了TPCH數據源的性能,這個數據源支持最高達300萬倍基准數據的龐大數據量測試,通過比較發現,
HIVE on Presto比同數據量的TPCH on Presto執行要快,可能是因為Hive數據存的是分布式文件系統Hdfs,且文件格式是列式存儲ORC,讀取效率高
因此可通過TPCH on Presto大致估算HIVE on Presto執行所需的最大時長,發現4節點400G的Presto是完全可以支撐3萬倍基准數據的OLAP查詢的,可以支撐大部分的10萬倍基准數據的復雜查詢,有3個10萬倍基准數據的復雜查詢由於內存資源不足無法支撐
(3)建議
在內存資源足夠的情況下,建議使用Presto作為Hive的執行引擎
3、ElasticSearch
(1)壓測結果
由於ES on Presto並不完全支持sql語法,如對一個字符串類型的列進行過濾時,使用Presto where過濾只能得到空值,需要用Presto ES connector的push-down特性才可以得到正確結果,而TPCH的sql非常復雜,且實際使用ES的場景中很少需要用到這么復雜的查詢,因此只針對少量常用語法進行比較
索引數據量 |
操作 |
ES on Presto |
ES on DSL |
||
tiny_customer |
數據量 |
select count(1) from es6.default.tinyconsumer; |
1s |
GET /tiny_customer/_search |
1s |
使用_dsl強下推 |
1s |
||||
簡單過濾字段 |
注意對於文本數據,必須使用push-down特性,不然查不到數據 |
1s |
GET /tiny_customer/_search |
2s |
|
select count(1) from customer where _mktsegment=match_phrase('HOUSEHOLD'); |
1s |
||||
去重數據量 |
select count(distinct nationkey) from tiny_customer; |
1s |
GET /tiny_customer/_search |
1s |
|
customer |
數據量 |
select count(1) from es6.default.consumer; |
610s |
GET /customer/_search |
1s |
使用_dsl強下推 |
600s |
||||
簡單過濾字段 |
注意對於文本數據,必須使用push-down特性,不然查不到數據 |
2s |
GET /customer/_search |
2s |
|
select count(1) from customer where _mktsegment=match_phrase('HOUSEHOLD'); |
140s |
||||
去重數據量 |
select count(distinct nationkey) from customer; |
630s |
GET /customer/_search |
1s |
(2)解讀
若查的數據量不大,Presto性能還是可以的,且更方便易用,但對於大數據量,發現只是查數據子集時兩者性能差別不大,但遇到需要查數據量等掃描全索引的情況,這個時候ES on Presto就遠不如ES on ES快,因為ES本身有豐富的統計信息,且對查詢做了很多優化,而Presto需要把所有數據查出來再進行統計,即使使用_dsl強下推也無法顯著提高性能,看來Presto並未針對ES特性做足夠的優化
(3)建議
索引數據量不大的場景,或對性能不敏感且對易用性敏感的場景,可以使用Presto查ES中的數據。但在查詢時注意不能完全套用普通sql語法,要對語法做充分測試
三、性能優化
1、數據源優化
Presto使用的是MPP架構,使用純內存計算,計算的效率是很高的,但在計算前要先把數據從數據源中讀出來,這個階段的性能就非常取決於數據源。
當在Presto上對數據庫跨庫查詢,例如Mysql數據庫。這個時候Presto的做法是從MySQL數據庫端拉取最基本的數據,然后再去做進一步的處理,例如統計等聚合操作。
舉個栗子:
SELECT count(id) FROM table_1 WHERE condition=1;
上面的SQL語句會分為3個步驟進行:
- Presto發起到Mysql數據庫進行查詢
SELECT id FROM table_1 WHERE condition=1;
- 對結果進行count計算
- 返回結果
所以說,對於Presto來說,其跨庫查詢的瓶頸是在數據拉取這個步驟。當一個查詢中有多個數據源時,瓶頸取決於最慢的數據源的讀取效率,當查詢性能無法滿足要求時,可考慮使用Presto sql把Mysql中相關的數據表定期轉移到HDFS中,並轉存為高效的列式存儲格式ORC,且在歸檔的時候我們要選擇一個歸檔字段,如果是按日歸檔,我們可以用日期作為這個字段的值,采用yyyy-MM-dd的形式,例如2019-01-23。
2、集群優化
(1)加節點數比加內存性能提升更明顯,因為加節點不光會加內存,還會加cpu,提高處理能力
(2)當內存不足,經常發生GC會極大降低性能甚至導致查詢失敗
(3)單個節點的內存設置不可過小
因為有的聚合運算的reduce步驟只能放在同一台機器執行,這個時候若內存數過小,會發生大量GC降低性能,甚至OOM無法執行。這是tpch q08,一個8表的join、group by操作,在一個130G的集群上執行,每個節點24G內存,但經過短時間的100多G內存的占用后持續了較長時間的24G內存占用,就是這個原因。一共需要執行12分鍾,只有3分鍾是占用了100多G內存
四、業界壓測參考
以上內容只做了關於Presto的縱向性能測試,業界有做了關於市面上流行的開源引擎的比較,有興趣的可以看看
開源OLAP引擎測評報告(SparkSql、Presto、Impala、HAWQ、ClickHouse、GreenPlum)