天天看點

kudu介紹kudu介紹問題描述總結

kudu介紹

Kudu是運作在hadoop平台上的列式存儲系統,擁有Hadoop生态系統應用的常見技術特性,運作在一般的商用硬體上,支援水準擴充,高可用。

kudu的優勢

1)一個table由多個tablet組成,對分區檢視、擴容和資料高可用支援非常好

2)支援update和upsert操作。

3)與presto內建或spark內建後(dataframe)可通過标準的sql操作,使用起來很友善

4)可與spark系統內建

kudu的劣勢

1)隻有主鍵可以設定range分區,且隻能由一個主鍵,也就是一個表隻能有一個字段range分區,且該字段必須是主鍵。

2)如果是pyspark連接配接kudu,則不能對kudu進行額外的操作;而scala的spark可以調用kudu本身的庫,支援kudu的各種文法。

3)kudu的shell用戶端不提供表schema檢視。如果你不通過imapla連接配接kudu,且想要檢視表的中繼資料資訊,需要用spark加載資料為dataframe,通過檢視dataframe的schema檢視表的中繼資料資訊。

3)kudu的shell用戶端不提供表内容檢視。如果你想要表的據資訊,要麼自己寫腳本,要麼通過spark、imapla檢視。

4)如果使用range 分區需要手動添加分區。假設id為分區字段,需要手動設定第一個分區為1-30.第二個分區為30-60等等

問題描述

在項目中有個功能是外導使用者群,每次導入重複的記錄數,總是顯示重複記錄數為0。因為我們是将導入的檔案内容先存儲在group_input表中,表結構如下

CREATE TABLE group_input (

l_date varchar commen ‘日期’,

file_id varchar ‘導入檔案id’,

id_type varchar ‘id類型’,

id_str varchar ‘id值’,

super_id varchar ‘唯一id’

)

WITH (

column_design = ‘{“l_date”:{“key”:true,“nullable”:false,“encoding”:“AUTO_ENCODING”,“compression”:“DEFAULT_COMPRESSION”},“file_id”:{“key”:true,“nullable”:false,“encoding”:“AUTO_ENCODING”,“compression”:“DEFAULT_COMPRESSION”},“id_type”:{“key”:true,“nullable”:false,“encoding”:“AUTO_ENCODING”,“compression”:“DEFAULT_COMPRESSION”},“id_str”:{“key”:true,“nullable”:false,“encoding”:“AUTO_ENCODING”,“compression”:“DEFAULT_COMPRESSION”},“super_id”:{“key”:false,“nullable”:true,“encoding”:“AUTO_ENCODING”,“compression”:“DEFAULT_COMPRESSION”}}’,

partition_design = ‘{“hash”:[{“columns”:[“file_id”,“id_type”,“id_str”],“buckets”:3}],“range”:null}’

);

我們設計是以l_date,id_str,id_type,file_id作為聯合主鍵,現在使用java API操作kudu,往表裡面添加10條重複資料。

public static void main(String[] args) throws KuduException {
    String kuduAddress = "nffapp01:7051,nffapp02:7051,nffdata02:7051";
    KuduClient kuduClient = new KuduClient.KuduClientBuilder(kuduAddress).build();
    //建立表
    //建立kudu表字段
    LinkedList<ColumnSchema> columnSchemas = new LinkedList<>();
    columnSchemas.add(KuduUtil.newColumn("l_date", Type.STRING,true));
    columnSchemas.add(KuduUtil.newColumn("file_id",Type.INT32,true));
    columnSchemas.add(KuduUtil.newColumn("id_type",Type.STRING,true));
    columnSchemas.add(KuduUtil.newColumn("id_str",Type.STRING,true));
    columnSchemas.add(KuduUtil.newColumn("super_id",Type.STRING,false));
    //建立schema
    Schema schema = new Schema(columnSchemas);
    //建立表提供的所有選項
    CreateTableOptions createTableOptions = new CreateTableOptions();
    //設定副本數
    createTableOptions.setNumReplicas(1);
    //設定範圍分區的規則
    LinkedList<String> list = new LinkedList<String>();
    list.add("l_date");
    //設定hash分區
    createTableOptions.addHashPartitions(list,5);
    kuduClient.createTable("group_input",schema,createTableOptions);
    //向表内插入新資料
    KuduTable table = kuduClient.openTable("group_input");
    KuduSession session = kuduClient.newSession();
    session.setTimeoutMillis(60000);
    for (int i = 0; i < 10; i++) {
        logger.info("----------------insert  "+i+"---------------");
        Insert insert = table.newInsert();
        PartialRow row = insert.getRow();
        row.addString(0, "2019-08-01");
        row.addInt(1,20);
        row.addString(2, "20"+i);
        row.addString(3, "18664301061");
        row.addString(4, "super_id:9980767");
        session.apply(insert);
    }
    kuduClient.close();
}
           

}

獲得的結果,根據id_type可以看出插入了第一條記錄後其他記錄都未插入。

kudu介紹kudu介紹問題描述總結

當修改id_type和file_id值的時候,則資料可以全部插入,結果如圖

kudu介紹kudu介紹問題描述總結

總結

産品在設計之時沒有考慮到kudu表主鍵的唯一性。當同一個檔案中包含相同的記錄時,隻能導入一條記錄。為了滿足項目需要,隻能修改統計規則,總記錄條數=導入成功數+導入失敗數+重複數,這樣的話就重複數=成功重複數+失敗重複數