1. 程式人生 > 其它 >Kudu系列: Kudu主鍵選擇策略

Kudu系列: Kudu主鍵選擇策略

每個Kudu 表必須設定Pimary Key(unique), 另外Kudu表不能設定secondary index, 經過實際效能測試, 本文給出了選擇Kudu主鍵的幾個策略, 測試結果糾正了我之前的習慣認知.

簡單介紹測試場景: 表中有一個unqiue欄位Id, 另外還有一個日期維度欄位histdate, 有三種設定kudu PK的方法, 分別是:
表設計方案1 (histdate, id)作為聯合主鍵, 日期欄位放在前.
表設計方案2 (id,histdate)作為聯合主鍵, 日期欄位放在後.
表設計方案3 (id)作為單欄位主鍵.

先給出測試資料:

結論:
1. 選擇性強的欄位(比如 id 欄位) 應該放在PK清單最前面, 這個規則對查詢效能影響最大.
2. PK清單中只加必要的欄位, 越少越好.
3. 如果查詢針對PK中所有欄位都加了條件, 其效能是最優的. 但只要有一個PK欄位未加上條件, 就完全用不上PK索引,效能就很差.
4. where條件中各個欄位條件的先後順序並不關鍵.
5. Kudu表使用Java API Insert的速度還是很好的, 單執行緒達到了1萬筆/秒多.Kudu Update 效率也很高, 實測對一個窄表做全欄位update, 其速度達到了Insert速度的88%, 而vertica的update效率比insert差很多.

在測試之前的誤區:
誤區1. (histdate,id)組合PK應該是最優的, 因為在數倉中經常按照日期做查詢, 把日期放在PK清單最前面, 應該有助於提升查詢效能, 結果發現無論是日期+id組合查詢,還是id單獨查詢, 該方案效能都最差, 甚至不如完全不在PK清單中的 duplicated_id 的定位查詢.
誤區2. 即使給部分PK欄位加上過濾條件, 查詢也會利用上PK index, 結果證明是完全利用不上index.

具體表結構:

-- 下面三個表的 id 取值為: java.util.UUID.randomUUID().toString(), duplicated_id和id取值相同. 

CREATE TABLE kudu_testdb.perf_test_t1
( 
histdate    timestamp ENCODING BIT_SHUFFLE COMPRESSION LZ4,
id    string ENCODING PLAIN_ENCODING COMPRESSION SNAPPY,
value 
int, duplicated_id string ENCODING PLAIN_ENCODING COMPRESSION SNAPPY, PRIMARY KEY (histdate,id) ) PARTITION BY HASH (histdate,id) PARTITIONS 2 STORED AS KUDU TBLPROPERTIES ( 'kudu.table_name' = 'testdb.perf_test_t1', 'kudu.master_addresses' = '10.205.6.1:7051,10.205.6.2:7051,10.205.7.3:7051' ); CREATE TABLE kudu_testdb.perf_test_t2 ( histdate timestamp ENCODING BIT_SHUFFLE COMPRESSION LZ4, id string ENCODING PLAIN_ENCODING COMPRESSION SNAPPY, value
int, duplicated_id string ENCODING PLAIN_ENCODING COMPRESSION SNAPPY, PRIMARY KEY (id,histdate) ) PARTITION BY HASH (id,histdate) PARTITIONS 2 STORED AS KUDU TBLPROPERTIES ( 'kudu.table_name' = 'testdb.perf_test_t2', 'kudu.master_addresses' = '10.205.6.1:7051,10.205.6.2:7051,10.205.7.3:7051' ); CREATE TABLE kudu_testdb.perf_test_t3 ( id string ENCODING PLAIN_ENCODING COMPRESSION SNAPPY, histdate timestamp ENCODING BIT_SHUFFLE COMPRESSION LZ4, value int, duplicated_id string ENCODING PLAIN_ENCODING COMPRESSION SNAPPY, PRIMARY KEY (id) ) PARTITION BY HASH (id) PARTITIONS 2 STORED AS KUDU TBLPROPERTIES ( 'kudu.table_name' = 'testdb.perf_test_t3', 'kudu.master_addresses' = '10.205.6.1:7051,10.205.6.2:7051,10.205.7.3:7051' );