在大資料分析中,通常會有一些估值的需求,例如估計某個時間段有多少新增使用者,估計某個時間段有多少使用者。
常用的估值算法如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)。