如何快速地把HDFS中的數據導入ClickHouse

如何快速地把HDFS中的數據導入ClickHouse

3739fb5b1bad134c6fc2ebccb502178d.jpeg

ClickHouse是面向OLAP的分佈式列式DBMS。我們部門目前已經把所有數據分析相關的日誌數據存儲至ClickHouse這個優秀的數據倉庫之中,當前日數據量達到了300億。

之前介紹的有關數據處理入庫的經驗都是基於實時數據流,數據存儲在Kafka中,我們使用Java或者Golang將數據從Kafka中讀取、解析、清洗之後寫入ClickHouse中,這樣可以實現數據的快速接入。然而在很多同學的使用場景中,數據都不是實時的,可能需要將HDFS或者是Hive中的數據導入ClickHouse。有的同學通過編寫Spark程序來實現數據的導入,那麼是否有更簡單、高效的方法呢。

目前開源社區上有一款工具Waterdrop,項目地址https://github.com/InterestingLab/waterdrop,可以快速地將HDFS中的數據導入ClickHouse。

HDFS to ClickHouse

假設我們的日誌存儲在HDFS中,我們需要將日誌進行解析並篩選出我們關心的字段,將對應的字段寫入ClickHouse的表中。

Log Sample

我們在HDFS中存儲的日誌格式如下, 是很常見的Nginx日誌

10.41.1.28 github.com 114.250.140.241 0.001s "127.0.0.1:80" [26/Oct/2018:03:09:32 +0800] "GET /InterestingLab/waterdrop HTTP/1.1" 200 0 "-" - "Dalvik/2.1.0 (Linux; U; Android 7.1.1; OPPO R11 Build/NMF26X)" "196" "-" "mainpage" "443" "-" "172.16.181.129"

ClickHouse Schema

我們的ClickHouse建表語句如下,我們的表按日進行分區

CREATE TABLE cms.cms_msg
(
    date Date, 
    datetime DateTime, 
    url String, 
    request_time Float32, 
    status String, 
    hostname String, 
    domain String, 
    remote_addr String, 
    data_size Int32, 
    pool String
) ENGINE = MergeTree PARTITION BY date ORDER BY date SETTINGS index_granularity = 16384

Waterdrop with ClickHouse

接下來會給大家詳細介紹,我們如何通過Waterdrop滿足上述需求,將HDFS中的數據寫入ClickHouse中。

Waterdrop

Waterdrop是一個非常易用,高性能,能夠應對海量數據的實時數據處理產品,它構建在Spark之上。Waterdrop擁有着非常豐富的插件,支持從Kafka、HDFS、Kudu中讀取數據,進行各種各樣的數據處理,並將結果寫入ClickHouse、Elasticsearch或者Kafka中。

Prerequisites

首先我們需要安裝Waterdrop,安裝十分簡單,無需配置系統環境變量

  1. 準備Spark環境
  2. 安裝Waterdrop
  3. 配置Waterdrop

以下是簡易步驟,具體安裝可以參照Quick Start

cd /usr/local
wget https://archive.apache.org/dist/spark/spark-2.2.0/spark-2.2.0-bin-hadoop2.7.tgz
tar -xvf https://archive.apache.org/dist/spark/spark-2.2.0/spark-2.2.0-bin-hadoop2.7.tgz
wget https://github.com/InterestingLab/waterdrop/releases/download/v1.1.1/waterdrop-1.1.1.zip
unzip waterdrop-1.1.1.zip
cd waterdrop-1.1.1

vim config/waterdrop-env.sh
# 指定Spark安裝路徑
SPARK_HOME=${SPARK_HOME:-/usr/local/spark-2.2.0-bin-hadoop2.7}

Waterdrop Pipeline

我們僅需要編寫一個Waterdrop Pipeline的配置文件即可完成數據的導入。

配置文件包括四個部分,分別是Spark、Input、filter和Output。

Spark

這一部分是Spark的相關配置,主要配置Spark執行時所需的資源大小。

spark {
  spark.app.name = "Waterdrop"
  spark.executor.instances = 2
  spark.executor.cores = 1
  spark.executor.memory = "1g"
}

Input

這一部分定義數據源,如下是從HDFS文件中讀取text格式數據的配置案例。

input {
    hdfs {
        path = "hdfs://nomanode:8020/rowlog/accesslog"
        table_name = "access_log"
        format = "text"
    }
}

Filter

在Filter部分,這裏我們配置一系列的轉化,包括正則解析將日誌進行拆分、時間轉換將HTTPDATE轉化爲ClickHouse支持的日期格式、對Number類型的字段進行類型轉換以及通過SQL進行字段篩減等

filter {
    # 使用正則解析原始日誌
    grok {
        source_field = "raw_message"
        pattern = '%{IP:ha_ip}\\s%{NOTSPACE:domain}\\s%{IP:remote_addr}\\s%{NUMBER:request_time}s\\s\"%{DATA:upstream_ip}\"\\s\\[%{HTTPDATE:timestamp}\\]\\s\"%{NOTSPACE:method}\\s%{DATA:url}\\s%{NOTSPACE:http_ver}\"\\s%{NUMBER:status}\\s%{NUMBER:body_bytes_send}\\s%{DATA:referer}\\s%{NOTSPACE:cookie_info}\\s\"%{DATA:user_agent}\"\\s%{DATA:uid}\\s%{DATA:session_id}\\s\"%{DATA:pool}\"\\s\"%{DATA:tag2}\"\\s%{DATA:tag3}\\s%{DATA:tag4}'
    }
    # 將"dd/MMM/yyyy:HH:mm:ss Z"格式的數據轉換爲
    # "yyyy/MM/dd HH:mm:ss"格式的數據
    date {
        source_field = "timestamp"
        target_field = "datetime"
        source_time_format = "dd/MMM/yyyy:HH:mm:ss Z"
        target_time_format = "yyyy/MM/dd HH:mm:ss"
    }
    # 使用SQL篩選關注的字段,並對字段進行處理
    # 甚至可以通過過濾條件過濾掉不關心的數據
    sql {
        table_name = "access"
        sql = "select substring(date, 1, 10) as date, datetime, hostname, url, http_code, float(request_time), int(data_size), domain from access"
    }
}

Output

最後我們將處理好的結構化數據寫入ClickHouse

output {
    clickhouse {
        host = "your.clickhouse.host:8123"
        database = "waterdrop"
        table = "access_log"
        fields = ["date", "datetime", "hostname", "uri", "http_code", "request_time", "data_size", "domain"]
        username = "username"
        password = "password"
    }
}

Running Waterdrop

我們將上述四部分配置組合成爲我們的配置文件config/batch.conf

vim config/batch.conf
spark {
  spark.app.name = "Waterdrop"
  spark.executor.instances = 2
  spark.executor.cores = 1
  spark.executor.memory = "1g"
}
input {
    hdfs {
        path = "hdfs://nomanode:8020/rowlog/accesslog"
        table_name = "access_log"
        format = "text"
    }
}
filter {
    # 使用正則解析原始日誌
    grok {
        source_field = "raw_message"
        pattern = '%{IP:ha_ip}\\s%{NOTSPACE:domain}\\s%{IP:remote_addr}\\s%{NUMBER:request_time}s\\s\"%{DATA:upstream_ip}\"\\s\\[%{HTTPDATE:timestamp}\\]\\s\"%{NOTSPACE:method}\\s%{DATA:url}\\s%{NOTSPACE:http_ver}\"\\s%{NUMBER:status}\\s%{NUMBER:body_bytes_send}\\s%{DATA:referer}\\s%{NOTSPACE:cookie_info}\\s\"%{DATA:user_agent}\"\\s%{DATA:uid}\\s%{DATA:session_id}\\s\"%{DATA:pool}\"\\s\"%{DATA:tag2}\"\\s%{DATA:tag3}\\s%{DATA:tag4}'
    }
    # 將"dd/MMM/yyyy:HH:mm:ss Z"格式的數據轉換爲
    # "yyyy/MM/dd HH:mm:ss"格式的數據
    date {
        source_field = "timestamp"
        target_field = "datetime"
        source_time_format = "dd/MMM/yyyy:HH:mm:ss Z"
        target_time_format = "yyyy/MM/dd HH:mm:ss"
    }
    # 使用SQL篩選關注的字段,並對字段進行處理
    # 甚至可以通過過濾條件過濾掉不關心的數據
    sql {
        table_name = "access"
        sql = "select substring(date, 1, 10) as date, datetime, hostname, url, http_code, float(request_time), int(data_size), domain from access"
    }
}
output {
    clickhouse {
        host = "your.clickhouse.host:8123"
        database = "waterdrop"
        table = "access_log"
        fields = ["date", "datetime", "hostname", "uri", "http_code", "request_time", "data_size", "domain"]
        username = "username"
        password = "password"
    }
}

執行命令,指定配置文件,運行Waterdrop,即可將數據寫入ClickHouse。這裏我們以本地模式爲例。

./bin/start-waterdrop.sh --config config/batch.conf -e client -m 'local[2]'

Conclusion

在這篇文章中,我們介紹瞭如何使用Waterdrop將HDFS中的Nginx日誌文件導入ClickHouse中。僅通過一個配置文件便可快速完成數據的導入,無需編寫任何代碼。除了支持HDFS數據源之外,Waterdrop同樣支持將數據從Kafka中實時讀取處理寫入ClickHouse中。我們的下一篇文章將會介紹,如何將Hive中的數據快速導入ClickHouse中。

當然,Waterdrop不僅僅是ClickHouse數據寫入的工具,在Elasticsearch以及Kafka等數據源的寫入上同樣可以扮演相當重要的角色。

希望瞭解Waterdrop和ClickHouse、Elasticsearch、Kafka結合使用的更多功能和案例,可以直接進入項目主頁https://github.com/InterestingLab/waterdrop

– Power by InterestingLab

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章