cstore_fdw的安裝使用以及源碼分析


一、cstore_fdw的簡介

  https://github.com/citusdata/cstore_fdw,此外部表擴展是由citusdata公司開發,使用RC_file格式對數據進行列式存儲。

  

  優點1:因為有壓縮,所以在disk上的存儲大大減少,壓縮比能達到2-4倍

  優點2:數據內部分塊存儲,對於塊數據進行了max以及min值的記錄,在查詢時能夠進行跳塊查詢

  優點3:在進行查詢時,並不是將所有的磁盤數據都load到內存,而是選擇列根據記錄的skiplist中的offset來load所需要的數據,減少IO

二、安裝使用

  安裝之前需要安裝protobuf & protobuf-c

  [root@centos01 ~]# git clone https://github.com/citusdata/cstore_fdw.git

  下載好后修改Makefile文件中的pgconfig指定到安裝目錄下 例如:/usr/local/postgres/bin/pgconfig

  [root@centos01 ~]# make && make install

  配置postgres.conf文件末尾添加:

  shared_preload_libraries = 'cstore_fdw'

  啟動數據庫:

  [postgres@centos01 ~]$ pg_ctl -D db1 -l logfile start -m fast

  [postgres@centos01 ~]$ psql

  

postgres=# create extension cstore_fdw;
CREATE EXTENSION
postgres=# create server cstore_server foreign data wrapper cstore_fdw ;
CREATE SERVER
postgres=# CREATE FOREIGN TABLE customer_reviews
postgres-# (
postgres(#     customer_id TEXT,
postgres(#     review_date DATE,
postgres(#     review_rating INTEGER,
postgres(#     review_votes INTEGER,
postgres(#     review_helpful_votes INTEGER,
postgres(#     product_id CHAR(10),
postgres(#     product_title TEXT,
postgres(#     product_sales_rank BIGINT,
postgres(#     product_group TEXT,
postgres(#     product_category TEXT,
postgres(#     product_subcategory TEXT
postgres(# )
postgres-# SERVER cstore_server
postgres-# OPTIONS(compression 'pglz');

  PG原生表占用磁盤大小:

postgres=# insert into customer_reviews select * from customer;
INSERT 0 176774
postgres=# select pg_relation_size('customer');
 pg_relation_size 
------------------
        145489920
(1 row)

  經過cstore_fdw外部擴展壓縮后占用的磁盤大小:

[postgres@centos01 13056]$ ll /home/postgres/db1/cstore_fdw/13056

-rw------- 1 postgres postgres 6236569 Dec 5 10:07 278237
-rw------- 1 postgres postgres 56 Dec 5 10:07 278237.footer

  對比后磁盤使用減少了很多!!

三、源碼分析

postgres中外部表的實現相當於一個引擎,通過掛接C語言的函數指針實現

Datum
cstore_fdw_handler(PG_FUNCTION_ARGS)
{
	FdwRoutine *fdwRoutine = makeNode(FdwRoutine);

	fdwRoutine->GetForeignRelSize = CStoreGetForeignRelSize;
	fdwRoutine->GetForeignPaths = CStoreGetForeignPaths;
	fdwRoutine->GetForeignPlan = CStoreGetForeignPlan;
	fdwRoutine->ExplainForeignScan = CStoreExplainForeignScan;
	fdwRoutine->BeginForeignScan = CStoreBeginForeignScan;//1
	fdwRoutine->IterateForeignScan = CStoreIterateForeignScan;//2
	fdwRoutine->ReScanForeignScan = CStoreReScanForeignScan;//3
	fdwRoutine->EndForeignScan = CStoreEndForeignScan;//4
	fdwRoutine->AnalyzeForeignTable = CStoreAnalyzeForeignTable;
	fdwRoutine->PlanForeignModify = CStorePlanForeignModify;//5
	fdwRoutine->BeginForeignModify = CStoreBeginForeignModify;//6
	fdwRoutine->ExecForeignInsert = CStoreExecForeignInsert;//7
	fdwRoutine->EndForeignModify = CStoreEndForeignModify;//8

	PG_RETURN_POINTER(fdwRoutine);
}

  1、2、3、4構成了查詢操作 例如: select * from customer_reviews;

  5、6、7、8構成了插入操作 例如:insert into customer_reviews select * from customer;

  特別注意的是在插入的時候,由於CStorePlanForeignModify這個函數中判斷了tableEntry->rtekind == RTE_SUBQUERY,

  因此 insert into xx values xxx 這種插入是不支持的。

  從源碼中觀察到在CStoreEndForeignModify中會進行flushstripe操作,就是不管插入一條數據還是批量插入數據,都會進行flushstripe操作

  如果插入一條數據,則此條數據占用了一個條帶的磁盤空間

  如果是批量插入,則按照默認的條帶大小,塊大小來進行分割,滿足stripe了就刷磁盤,接着剩余不滿足stripe的作為另外一個條帶,如果按照一條數據一個條帶的話,查詢load數據就會相當緩慢。

  最后得出結論:對於總是進行單條插入或者交易型數據庫,這種壓縮效率就不是很明顯了,如果對於批量插入的話,壓縮比例還是很可觀的,而且查詢也會較快。

  RCFile格式對比orc格式:

  還有就是對於RCfile這種格式,字符串類型的壓縮並沒有很明顯的處理,不像orc格式,orc帶有字典壓縮處理,而RCFile並沒有

  https://github.com/gokhankici/orc_fdw

  這個外部表擴展僅僅對orc格式的文件進行讀操作,並沒有寫操作,寫文件的操作是使用java語言開發的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM