orc存儲
1. 概述
cstore_fdw實現了 PostgreSQL 資料庫的列式存儲。列存儲非常適合用於數據分析的場景,數據分析的場景下數據是批量載入的。
這個擴展使用了Optimized Row Columnar (ORC)數據存儲格式,ORC改進了Facebook的RCFile格式,帶來如下好處:
壓縮:將內存和磁碟中數據大小削減到2到4倍。可以擴展以支持不同壓縮演算法。
列投影:只提取和查詢相關的列數據。提升IO敏感查詢的性能。
跳過索引:為行組存儲最大最小統計值,並利用它們跳過無關的行。
2. 使用
cstore_fdw的安裝和使用都非常簡單,可以參考官方資料。
thub.com/citusdata/cstore_fdw
注)注意cstore_fdw只支持PostgreSQL9.3和9.4 。
下面做幾個簡單的性能對比,看看cstore_fdw究竟能帶來多大的性能提升。
2.1 數據載入
2.1.1 普通表
CREATE TABLE tb1
(
id int,
c1 TEXT,
c2 TEXT,
c3 TEXT,
c4 TEXT,
c5 TEXT,
c6 TEXT,
c7 TEXT,
c8 TEXT,
c9 TEXT,
c10 TEXT
);
注:要和普通表的全表掃描作對比,所以不建主鍵和索引。
[postgres@node2 chenhj]$ time psql -p 40382 -At -F, -c "select id,id::text,id::text,id::text,id::text,id::text,id::text,id::text,id::text,id::text,id::text from generate_series(1,10000000) id"|time psql -p 40382 -c " tb1 from STDIN with CSV"
COPY 10000000
1.56user 1.00system 6:42.39elapsed 0%CPU (0avgtext+0avgdata 7632maxresident)k
776inputs+0outputs (17major+918minor)pagefaults 0swaps
real 6m42.402s
user 0m15.174s
sys 0m14.904s
postgres=# select pg_total_relation_size('tb1'::regclass);
pg_total_relation_size
------------------------
1161093120
(1 row)
postgres=# \timing
Timing is on.
postgres=# analyze tb1;
ANALYZE
Time: 11985.070 ms
插入1千萬條記錄,數據佔用存儲大小1.16G,插入耗時6分42秒,分析耗時12秒。
2.1.2 cstore表
$ mkdir -p /home/chenhj/data94/cstore
CREATE EXTENSION cstore_fdw;
CREATE SERVER cstore_server FOREIGN DATA WRAPPER cstore_fdw;
CREATE FOREIGN TABLE cstb1
(
id int,
c1 TEXT,
c2 TEXT,
c3 TEXT,
c4 TEXT,
c5 TEXT,
c6 TEXT,
c7 TEXT,
c8 TEXT,
c9 TEXT,
c10 TEXT
)
SERVER cstore_server
OPTIONS(filename '/home/chenhj/data94/cstore/cstb1.cstore',
compression 'pglz');
[postgres@node2 chenhj]$ time psql -p 40382 -At -F, -c "select id,id::text,id::text,id::text,id::text, www.hnne.com id::text,id::text,id::text,id::text,id::text,id::text from generate_series(1,10000000) id"|time psql -p 40382 -c " cstb1 from STDIN with CSV"
COPY 10000000
1.53user 0.78system 7:35.15elapsed 0%CPU (0avgtext+0avgdata 7632maxresident)k
968inputs+0outputs (20major+920minor)pagefaults 0swaps
real 7m35.520s
user 0m14.809s
sys 0m14.170s
[postgres@node2 chenhj]$ ls -l /home/chenhj/data94/cstore/cstb1.cstore
-rw------- 1 postgres postgres 389583021 Jun 23 17:32 /home/chenhj/data94/cstore/cstb1.cstore
postgres=# \timing
Timing is on.
postgres=# analyze cstb1;
ANALYZE
Time: 5946.476 ms
插入1千萬條記錄,數據佔用存儲大小390M,插入耗時7分35秒,分析耗時6秒。
使用cstore列存儲後,數據佔用存儲大小降到普通表的3分之1。需要說明的是,由於所有TEXT列填充了隨機數據,壓縮率不算高,某些實際的應用場景下壓縮效果會比這更好。
2.2 Text列的like查詢性能對比
2.2.1 普通表
清除文件系統緩存,並重啟PostgreSQL
[postgres@node2 chenhj]$ pg_ctl -D /home/chenhj/data94 -l logfile94 restart
[root@node2 ~]# free
total used free shared buffers cached
Mem: 2055508 771356 1284152 0 9900 452256
-/+ buffers/cache: 309200 1746308
Swap: 4128760 387624 3741136
[root@node2 ~]# echo 1 > /proc/sys/vm/drop_caches
[root@node2 ~]# free
total used free shared buffers cached
Mem: 2055508 326788 1728720 0 228 17636
-/+ buffers/cache: 308924 1746584
Swap: 4128760 381912 3746848
對Text列執行like查詢
[postgres@node2 chenhj]$ iostat -k dm-2
Linux 2.6.32-71.el6.x86_64 (node2) 06/23/14 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.80 0.00 0.38 3.42 0.00 95.40
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
dm-2 58.55 330.68 212.08 7351441 4714848
[postgres@node2 chenhj]$ time psql -p 40382 -c "select count(*) from tb1 where c1 like '%66'"
count
--------
100000
(1 row)
real 0m7.051s
user 0m0.001s
sys 0m0.004s
[postgres@node2 chenhj]$ iostat -k dm-2
Linux 2.6.32-71.el6.x86_64 (node2) 06/23/14 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.80 0.00 0.38 3.43 0.00 95.39
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
dm-2 58.90 381.53 211.90 8489597 4714956
耗時7.1秒,產生IO讀1.14G,IO寫108K。
不清文件系統緩存,不重啟PostgreSQL,再執行一次。消耗時間降到1.6秒,幾乎不產生IO。
[postgres@node2 chenhj]$ iostat -k dm-2
Linux 2.6.32-71.el6.x86_64 (node2) 06/23/14 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.80 0.00 0.38 3.43 0.00 95.39
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
dm-2 58.81 332.20 213.06 7350301 4714364
[postgres@node2 chenhj]$ time psql -p 40382 -c "select count(*) from tb1 where c1 like '%66'"
count
--------
100000
(1 row)
real 0m1.601s
user 0m0.002s
sys 0m0.001s
[postgres@node2 chenhj]$ iostat -k dm-2
Linux 2.6.32-71.el6.x86_64 (node2) 06/23/14 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.80 0.00 0.38 3.43 0.00 95.38
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
dm-2 58.80 332.12 213.01 7350337 4714364
2.2.2 cstore表
清除文件系統緩存,並重啟PostgreSQL
[postgres@node2 chenhj]$ pg_ctl -D /home/chenhj/data94 -l logfile94 restart
[root@node2 ~]# echo 1 > /proc/sys/vm/drop_caches
對Text列執行like查詢
[postgres@node2 chenhj]$ iostat -k dm-2
Linux 2.6.32-71.el6.x86_64 (node2) 06/23/14 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.80 0.00 0.38 3.38 0.00 95.45
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
dm-2 58.12 376.42 209.04 8492017 4716048
[postgres@node2 chenhj]$ time psql -p 40382 -c "select count(*) from cstb1 where c1 like '%66'"
count
--------
100000
(1 row)
real 0m2.786s
user 0m0.002s
sys 0m0.003s
[postgres@node2 chenhj]$ iostat -k dm-2
Linux 2.6.32-71.el6.x86_64 (node2) 06/23/14 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.80 0.00 0.38 3.38 0.00 95.44
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
dm-2 58.12 378.75 208.89 8550761 4716048
耗時2.8秒,產生IO讀59M,IO寫0K。執行時間優化的雖然不是太多,但IO大大減少,可見列投影起到了作用。
不清文件系統緩存,不重啟PostgreSQL,再執行一次。消耗時間降到1.4秒,幾乎不產生IO。
[postgres@node2 chenhj]$ iostat -k dm-2
Linux 2.6.32-71.el6.x86_64 (node2) 06/23/14 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.80 0.00 0.38 3.36 0.00 95.47
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
dm-2 57.75 376.33 207.58 8550809 4716524
[postgres@node2 chenhj]$ time psql -p 40382 -c "select count(*) from cstb1 where c1 like '%66'"
count
--------
100000
(1 row)
real 0m1.424s
user 0m0.002s
sys 0m0.001s
[postgres@node2 chenhj]$ iostat -k dm-2
Linux 2.6.32-71.el6.x86_64 (node2) 06/23/14 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.80 0.00 0.38 3.36 0.00 95.47
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
dm-2 57.70 375.96 207.38 8550809 4716588
2.3 對Int列執行=查詢
2.3.1 普通表
清除文件系統緩存,並重啟PostgreSQL後
[postgres@node2 chenhj]$ pg_ctl -D /home/chenhj/data94 -l logfile94 restart
[root@node2 ~]# echo 1 > /proc/sys/vm/drop_caches
對Int列執行=查詢
[postgres@node2 chenhj]$ iostat -k dm-2
Linux 2.6.32-71.el6.x86_64 (node2) 06/23/14 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.79 0.00 0.37 3.33 0.00 95.50
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
dm-2 57.25 373.21 205.67 8560897 4717624
[postgres@node2 chenhj]$ time psql -p 40382 -c "select count(*) from tb1 where id =666666"
count
-------
1
(1 row)
real 0m6.844s
user 0m0.002s
sys 0m0.006s
[postgres@node2 chenhj]$ iostat -k dm-2
Linux 2.6.32-71.el6.x86_64 (node2) 06/23/14 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.79 0.00 0.37 3.34 0.00 95.49
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
dm-2 57.60 422.57 205.54 9699161 4717708
耗時6.8秒,產生IO讀1.14G,IO寫84K
不清緩存,再執行一次。消耗時間降到1.1秒,幾乎不產生IO。
[postgres@node2 chenhj]$ iostat -k dm-2
Linux 2.6.32-71.el6.x86_64 (node2) 06/23/14 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.79 0.00 0.37 3.33 0.00 95.50
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
dm-2 57.44 421.37 204.97 9699177 4718032
[postgres@node2 chenhj]$ time psql -p 40382 -c "select count(*) from tb1 where id =666666"
count
-------
2. 大數據常用文件格式介紹
圖片看不見的話可以看我CSDN上的文章:
https://blog.csdn.net/u013332124/article/details/86423952
最近在做hdfs小文件合並的項目,涉及了一些文件格式的讀寫,比如avro、orc、parquet等。期間閱讀了一些資料,因此打算寫篇文章做個記錄。
這篇文章不會介紹如何對這些格式的文件進行讀寫,只會介紹一下它們各自的特點以及底層存儲的編碼格式 。
[圖片上傳失敗...(image-a5104a-1547368703623)]
使用sequencefile還可以將多個小文件合並到一個大文件中,通過key-value的形式組織起來,此時該sequencefile可以看做是一個小文件容器。
[圖片上傳失敗...(image-4d03a2-1547368703623)]
Parquet是一個基於列式存儲的文件格式,它將數據按列劃分進行存儲。Parquet官網上的文件格式介紹圖:
[圖片上傳失敗...(image-92770e-1547368703623)]
我們可以看出,parquet由幾個部分構成:
[圖片上傳失敗...(image-391e57-1547368703623)]
Orc也是一個列式存儲格式,產生自Apache Hive,用於降低Hadoop數據存儲空間和加速Hive查詢速度。
[圖片上傳失敗...(image-ba6160-1547368703623)]
目前列式存儲是大數據領域基本的優化項,無論是存儲還是查詢,列式存儲能做的優化都很多,看完上面對orc和parquet的文件結構介紹後,我們列式存儲的優化點做一個總結:
在壓縮方面 :
在查詢方面 :
就網上找到的一些數據來看,Orc的壓縮比會比Parquet的高一些,至於查詢性能,兩個應該不會差距太大。本人之前做過一個測試,在多數場景,hive on mr下,orc的查詢性能會更好一些。換成hive on spark後,parquet的性能更好一些
本文介紹的4種大數據存儲格式,2個是行式存儲,2個是列式存儲,但我們可以看到一個共同點:它們都是支持分割的。這是大數據文件結構體系中一個非常重要的特點, 因為可分割使一個文件可以被多個節點並發處理,提高數據的處理速度 。
另外,當前大數據的主要趨勢應該是使用列式存儲,目前我們公司已經逐步推進列式存儲的使用,本人也在hive上做過一些測試,在多個查詢場景下,無論是orc還是parquet的查詢速度都完爆text格式的, 差不多有4-8倍的性能提升 。另外,orc和parquet的壓縮比都能達到10比1的程度。因此,無論從節約資源和查詢性能考慮,在大多數情況下,選擇orc或者parquet作為文件存儲格式是更好的選擇。另外,spark sql的默認讀寫格式也是parquet。
當然,並不是說列式存儲已經一統天下了,大多時候我們還是要根據自己的使用場景來決定使用哪種存儲格式。
Sequencefile
https://blog.csdn.net/en_joker/article/details/79648861
https://stackoverflow.com/questions/11778681/advantages-of-sequence-file-over-hdfs-textfile
Avro和Sequencefile區別
https://stackoverflow.com/questions/24236803/difference-between-avrodata-file-and-sequence-file-with-respect-to-apache-sqoop
parquet
https://www.cnblogs.com/ITtangtang/p/7681019.html
Orc
https://www.cnblogs.com/ITtangtang/p/7677912.html
https://www.cnblogs.com/cxzdy/p/5910760.html
Orc和parquet的一些對比
https://blog.csdn.net/colorant/article/details/53699822
https://blog.csdn.net/yu616568/article/details/51188479