天天看點

Greenplum 跨庫資料JOIN需求 - dblink的使用和弊端以及解決方案

postgresql , greenplum , dblink

greenplum在許多企業中被用于資料倉庫,一個企業中通常會有統一的使用者管理系統,賬務系統;還有許多業務線。

資料被分成兩類,一類是業務相關的,一類是全公司統一的資料。

如果使用者将兩個部分資料分别存入不同的資料庫(單個執行個體可以建立多個資料庫),并且公共資料需要與業務資料join時,你可能會想到dblink這個功能,通過dblink管理其他資料庫然後和本地資料進行join。

Greenplum 跨庫資料JOIN需求 - dblink的使用和弊端以及解決方案
Greenplum 跨庫資料JOIN需求 - dblink的使用和弊端以及解決方案

如果你對執行個體和資料庫的概念不太了解,可以參考一下這篇文檔。

<a href="https://github.com/digoal/blog/blob/master/201605/20160510_01.md">《postgresql 邏輯結構 和 權限體系 介紹》</a>

那麼到底dblink是否适合這個場景呢?

greenplum預設并沒有打包dblink,是以需要部署一下。

例如現在greenplum base postgresql是8.3的版本。

将dblink.so拷貝到所有節點的gp軟體目錄

需要使用dblink的資料庫,執行dblink.sql

建立2張測試表,注意他們的分布鍵,用于觀察。

分别插入100萬測試資料

redistribute motion 3:3,表示從3個節點重分布到3個節點,說明原始資料來自3個節點。

gather motion 3:1,表示從3個節點彙聚到1個節點,

從dblink結果的重分布資訊(1:3),可以分析出這樣的結論

1. 可以肯定的是,dblink并沒有在每個資料節點執行,但是在哪個資料節點執行的,從計劃上看不出來。

2. 由于dblink沒有在所有節點執行,意味着,如果dblink傳回的結果集很大的話,這個執行節點的壓力會較大。

從重分布執行計劃結果看,自定義函數也隻在某個節點被調用。

某些情況會報錯,例如: 當函數中有通路到資料庫表,并且需要與其他表進行join時。

從執行計劃可以看出,沒有gather motion節點,說明dblink函數和自定義函數就是在master節點執行的。

如果在資料節點執行,應該有gather motion節點,例如

分布式資料庫兩階段聚合的原理請參考

<a href="https://github.com/digoal/blog/blob/master/201305/20130502_01.md">《postgres-xc customized aggregate introduction》</a>

<a href="https://github.com/digoal/blog/blob/master/201608/20160825_02.md">《greenplum 最佳實踐 - 估值插件hll的使用(以及hll分式聚合函數優化)》</a>

目前dblink與普通的使用者自定義函數類似,并沒有和greenplum的mpp架構進行适配,它們會在master節點被調用,如果dblink傳回的結果集較大,master很容易成為瓶頸。

如果需要使用dblink與其他表進行join,流程是這樣的。

1. 首先會在master調用dblink,

2. dblink執行的結果集會收到master節點

3. master節點将結果集重分布到資料節點,

4. 然後再與其他表進行join。(好在join并不會在master節點執行。)

當然,我們不排除gpdb社群未來會改造dblink,來适配mpp的架構。但是至少目前還存在以上弊端,(除非dblink傳回的結果集很小,否則請謹慎使用)。

1. 建議資料放到一個資料庫中,使用不同的schema來區分不同的業務資料或公共資料。這樣的話在同一個資料庫中就可以任意的join了,對master無傷害。

2. 如果不同業務一定要使用多個資料庫,那麼建議使用外部表作為公共表,這樣做也不會傷害master,并且每個節點都可以并行的通路外部表的資料。

例如gpfdist外部表,阿裡雲hybriddb的oss外部表等。

外部表一旦寫入,就不可修改,如果公共資料經常變化,或者定期需要更新,(例如某些賬務系統,每天或定期會将使用者資訊更新到greenplum中)那麼建議使用一個字段來标示最新資料,同時低頻率的增量合并外部表。

例如

2.1. 隻寫 tbl_foreign_table_news(id int, xxx, xxx 最後更新時間)。

2.2. 低頻率的truncate tbl_foreign_table_origin,然後将tbl_foreign_table_news合并到 tbl_foreign_table_origin。

2.3. 使用者查詢tbl_foreign_table_origin即為公共資料。

3. 如果dblink擷取的結果集較小,那麼使用dblink作為臨時的方案,來實作執行個體内跨庫資料join是沒有太大問題的。

Greenplum 跨庫資料JOIN需求 - dblink的使用和弊端以及解決方案