天天看點

hll 估值插件 在Greenplum中的使用 以及 分布式聚合函數優化思路

在大資料分析中,通常會有一些估值的需求,例如估計某個時間段有多少新增使用者,估計某個時間段有多少使用者。

常用的估值算法如hyperloglog,還有一些其他的估值算法。

可以參考

<a href="http://www.pipelinedb.com/">http://www.pipelinedb.com/</a>

我在幾年前寫過如何在postgresql中使用hll,請參考

<a href="https://github.com/aggregateknowledge/postgresql-hll">https://github.com/aggregateknowledge/postgresql-hll</a>

<a href="http://blog.163.com/digoal@126/blog/static/16387704020131264480325/">http://blog.163.com/digoal@126/blog/static/16387704020131264480325/</a>

<a href="http://blog.163.com/digoal@126/blog/static/1638770402013127917876/">http://blog.163.com/digoal@126/blog/static/1638770402013127917876/</a>

這裡要說的是在greenplum中的使用。

greenplum是個分布式資料庫系統,特别需要注意的是它的聚合用法與單節點不一樣。

我之前寫過基于postgresql的另一個分布式系統postgres-xc的聚合函數的原理和寫法,有興趣的同學可以參考如下

<a href="http://blog.163.com/digoal@126/blog/static/16387704020134222140958/">http://blog.163.com/digoal@126/blog/static/16387704020134222140958/</a>

其實greenplum的聚合函數用法和postgres-xc及其的相似。

文法如下

有兩種聚合運算模式可選

1. 如果隻配置了sfunc,則相關資料全部收集到master節點,在master節點對所有資料依條加上sfunc的結果(第一次可選為initcond)輸入給sfunc計算,直到所有資料都跑完sfunc,最後如果設定了finalfunc,則計算并得到最終結果。

2. 如果同時配置了sfunc和prefunc,則在segment節點并行完成sfunc,然後将segment節點執行的結果發給master,在master調用prefunc進行再次聚合,輸出結果,如果配置了finalfunc,則這個結果再給finalfunc執行并輸出最終結果。

過程如下 :

确認hll.so正确的安裝

因為postgres-hll是相容9.0以上的create extension模式的,是以得看看控制檔案

然後需要修改sql檔案

在需要使用hll的資料庫執行hll--2.10.0.sql

測試的資料類型包括int2, int4, int8, text, bytea.

分成20個組,一共100萬資料。

按分組聚合後,插入一張結果表

查詢每個分組的唯一值以及按階段的唯一值。

每組,每個次元有多少唯一值

所有資料範圍,每個次元有多少唯一值

指定資料範圍,每個次元又多少唯一值

結果略

調整目前會話精度

傳回為老的值

調整預設精度

需要重新編譯, 在hll.c中 :

我們前面講了gp的聚合分兩種使用,一種是全部收到master節點執行,另一種是兩階段聚合。

如果記錄數少,其實沒有必要使用兩階段聚合。

以hll_union_agg聚合為例

臨時結果儲存為stype: internal類型.

每次調用hll_union_trans函數,輸入一條hll值以及臨時結果internal,輸出internal。

最後調用hll_pack,将internal轉換為hll輸出

優化方法如下

在節點調用sfunc聚合,輸入參數為(input_type資料 , 臨時結果stype),輸出為stype

segment第一階段收集結果傳輸到master調用prefunc,輸入(stype , stype),得到的結果為stype

最後再将stype轉換為聚合的輸出類型即可(可選使用finalfunc)。

繼續閱讀