1. 概述
本手冊主要介紹了,一個將傳統數據接入到Hadoop集羣的數據接入方案和實施方法。供數據接入和集羣運維人員參考。
1.1. 整體方案
Flume作爲日誌收集工具,監控一個文件目錄或者一個文件,當有新數據加入時,收集新數據發送給Kafka。Kafka用來做數據緩存和消息訂閱。Kafka裏面的消息可以定時落地到HDFS上,也可以用Spark Streaming來做實時處理,然後將處理後的數據落地到HDFS上。
1.2. 數據接入流程
本數據接入方案,分爲以下幾個步驟:
l 安裝部署Flume:在每個數據採集節點上安裝數據採集工具Flume。詳見“2、安裝部署Flume”。
l 數據預處理:生成特定格式的數據,供Flume採集。詳見“3、數據預處理”。
l Flume採集數據到Kafka: Flume採集數據併發送到Kafka消息隊列。詳見“4、Flume採集數據到Kafka”。
l Kafka數據落地:將Kafka數據落地到HDFS。詳見“5、Kafka數據落地”。
2. 安裝部署Flume
若要採集數據節點的本地數據,每個節點都需要安裝一個Flume工具,用來做數據採集。
2.2.1下載並安裝
到官網去下載最新版本的Flume
下載地址爲:http://flume.apache.org/,目前最新版本爲1.6.0,需要1.7及以上版本的JDK。
1、解壓
tar -xzvf apache-flume-1.6.0-bin.tar.gz -C /usr/local/
2、安裝JDK1.7
如果節點上JDK版本低於1.7,需要安裝1.7或以上版本的JDK
JDK 1.7 下載地址:
http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html
在Flume目錄下創建一個java目錄,存放JDK
cd /usr/local/apache-flume-1.6.0-bin
mkdir java
cd java
tar -xzvf jdk-7u79-linux-x64.tar.gz
2.2.2配置Flume系統參數
修改 flume-env.sh 配置文件,主要是JAVA_HOME變量設置
cd /usr/local/apache-flume-1.6.0-bin/conf
cp flume-env.sh.template flume-env.sh
在flume-env.sh裏面設置FLUME_CLASSPATH變量和JAVA_HOME變量,
示例:
export JAVA_HOME=/usr/local/apache-flume-1.6.0-bin/java/jdk1.7.0_79
FLUME_CLASSPATH="/usr/local/apache-flume-1.6.0-bin/"
變量具體內容根據實際修改
2.2.3添加Flume第三方依賴
添加第三方依賴包flume-plugins-1.0-SNAPSHOT.jar,此包實現了一個Flume攔截器,將Flume採集到的數據進行序列化、結構化等預處理,最後每條數據生成一條Event數據返回。
cd /usr/local/apache-flume-1.6.0-bin
mkdirplugins.d --創建依賴目錄,目錄名必須爲plugins.d
cdplugins.d
mkdirflume-plugins --項目目錄,目錄名隨意
cdflume-plugins
mkdirlib --jar包目錄,目錄名必須爲lib
將第三方jar包flume-plugins-1.0-SNAPSHOT.jar放在lib目錄下
2.2.4添加Hive配置文件
將hive-site.xml文件拷貝到/usr/local/apache-flume-1.6.0-bin/conf目錄下,並修改hive元數據地址與真實地址對應。如下所示:
<property>
<name>hive.metastore.uris</name>
<value>thrift://m103:9083,thrift://m105:9083</value>
</property>
2.2.5創建Flume agent配置文件
創建flume啓動配置文件,指定source,channel,sink 3個組件內容。每個組件都有好幾種配置選項,具體配置請查看Flume官網。創建配置文件flume.conf,示例如下:
vim flume.conf
a1.sources = x1
a1.sinks = y1
a1.channels = z1
# Describe/configure thesource
a1.sources.x1.type =exec
a1.sources.x1.channels =z1
a1.sources.x1.command =tail -F /home/xdf/exec.txt
# Describe the sink
a1.sinks.y1.type =logger
# Use a channel whichbuffers events in memory
a1.channels.z1.type =memory
a1.channels.z1.capacity= 1000
a1.channels.z1.transactionCapacity= 100
# Bind the source andsink to the channel
a1.sources.x1.channels =z1
a1.sinks.y1.channel = z1
2.2.6啓動Flume Agent
進入Flume安裝目錄,開啓agent。
cd /usr/local/apache-flume-1.6.0-bin
./bin/flume-ng agent--conf conf --conf-file flume.conf --name a3 -Dflume.root.logger=INFO,console
注意:-Dflume.root.logger=INFO,console僅爲 debug 使用,請勿生產環境生搬硬套,否則大量的日誌會返回到終端。-c/--conf 後跟配置目錄,-f/--conf-file 後跟具體的配置文件,-n/--name 指定agent的名稱。
2.2.7 測試
上面配置的example.conf文件,實現的功能是監控文件/home/xdf/exec.txt,如果有新數據寫入時,Flume就會採集到新數據並打印在控制檯上。
測試用例:向/home/xdf/exec.txt文件中寫入內容“hello flume”。
echo 'hello flume'>> /home/xdf/exec.txt
Flume 終端窗口此時會打印出如下信息,就表示成功了:
2015-06-3016:01:52,910 (SinkRunner-PollingRunner-DefaultSinkProcessor) [INFO -org.apache.flume.sink.LoggerSink.process(LoggerSink.java:94)] Event: {headers:{} body: 68 65 6C 6C 6F 20 66 6C 75 6D 65 hello flume }
至此,Flume安裝部署完畢。
3. 數據預處理
1、Flume採集數據都是按行分割的,一行代表一條記錄。如果原始數據不符合要求,需要對數據進行預處理。示例如下:
原始數據格式爲:
out: === START OFINFORMATION SECTION ===
out: Vendor: TOSHIBA
out: Product: MBF2300RC
out: Revision: 0109
out: User Capacity: 300,000,000,000 bytes [300 GB]
out: Logical blocksize: 512 bytes
經過預處理,我們將數據變爲一條5個字段的記錄:
TOSHIBA;MBF2300RC;0109;300;512
2、如果要將上面數據接入到hive中,我們還需要下面幾個處理:
a. 創建一張hive表
createtable test(Vendor string,Product string,Revision string,User_Capacitystring,block string);
b. 在Kafka節點上創建一個topic,名字與上面hive表名對應,格式爲“hive-數據庫名-表名”。示例如下:
bin/kafka-topics --create --zookeeper localhost:2181/kafka --topic hive-xdf-test --partitions 1 --replication-factor 1
c. 將第一步得到的記錄數據與topic整合成一條記錄,用“@@”分割。示例如下:
hive-xdf-test @@TOSHIBA;MBF2300RC;0109;300;512
d. Flume採集整合後的一條數據,通過topic獲取hive表的元數據,根據元數據對記錄數據進行結構化、序列化處理,然後經過Kafka存入到hive表中。具體操作參考下面具體步驟所示。
4. Flume採集數據到Kafka
Flume如果要將採集到的數據發送到Kafka,需要指定配置文件(如下:flume_test.conf)的sink類型爲KafkaSink,並且指定Kafka 的broker list。配置文件示例如下,紅色標註的爲KafkaSink配置項:
vimflume_test.conf
a3.channels= c3
a3.sources= r3
a3.sinks= k3
a3.sources.r3.type= exec
a3.sources.r3.channels= c3
a3.sources.r3.command= tail -F /home/xdf/exec.txt
a3.sources.r3.fileHeader= false
a3.sources.r3.basenameHeader= false
a3.sources.r3.interceptors= i3
a3.sources.r3.interceptors.i3.type=iie.flume.interceptor.CSVInterceptor$Builder
a3.sources.r3.interceptors.i3.separator= ;
a3.sources.r3.decodeErrorPolicy=IGNORE
a3.channels.c3.type= memory
a3.channels.c3.capacity= 10000
a3.channels.c3.transactionCapacity= 1000
a3.sinks.k3.channel= c3
#a3.sinks.k3.type = logger
#a3.sinks.k3.batchSize= 10
a3.sinks.k3.type = org.apache.flume.sink.kafka.KafkaSink
a3.sinks.k3.brokerList = localhost:9092
注意:此處有一個攔截器插件的定義,它就是用來做結構化、序列化數據預處理的。此插件由上面配置的Flume第三方jar包中獲得。
a3.sources.r3.interceptors.i3.type=iie.flume.interceptor.CSVInterceptor$Builder
5. Kafka數據落地
我們提供了一個Camus工具,來定時將Kafka中的數據落地到hive表中。
Camus工具包含以下三個文件:
文件 |
說明 |
camus-example-0.1.0-cdh-SNAPSHOT-shaded.jar |
程序運行jar包 |
camus.properties |
配置文件 |
camusrun.sh |
運行腳本 |
配置文件需要根據實際情況,修改以下兩個參數
kafka.whitelist.topics=hive-xdf-test ----數據對應的topic
kafka.brokers=m105:9092,m103:9092 ----kafka broker lists
需要指定多個topic時,用逗號間隔,示例:
Kafka.whitelist.topics=topic1,topic2,topic3
修改完配置文件後,定時運行camusrun.sh腳本,就會將新生成的數據接入到topic所對應的hive表中了。
6. 具體案例
6.1 Smart數據接入
6.1.2 創建hive表
最終我們要將smart數據接入到hive表中,所以我們首先要創建一個滿足smart數據結構的hive表。
createtable smart_data(serial_number String ,update_time string,smart_health_statusstring ,current_drive_temperature int,drive_trip_temperatureint,elements_in_grown_defect_list int,manufactured_time string ,cycle_countint ,start_stop_cycles int ,load_unload_count int ,load_unload_cycles int ,blocks_sent_to_initiator bigint,blocks_received_from_initiator bigint ,blocks_read_from_cache bigint,num_commands_size_not_larger_than_segment_size bigint,num_commands_size_larger_than_segment_size bigint ,num_hours_powered_upstring ,num_minutes_next_testint ,read_corrected_ecc_fast bigint,read_corrected_ecc_delayed bigint ,read_corrected_re bigint,read_total_errors_corrected bigint ,read_correction_algo_invocations bigint,read_gigabytes_processed bigint ,read_total_uncorrected_errors string,write_corrected_ecc_fast bigint ,write_corrected_ecc_delayed bigint,write_corrected_re bigint ,write_total_errors_corrected bigint,write_correction_algo_invocations bigint ,write_gigabytes_processed bigint,write_total_uncorrected_errors string ,verify_corrected_ecc_fast bigint,verify_corrected_ecc_delayed bigint ,verify_corrected_re bigint,verify_total_errors_corrected bigint ,verify_correction_algo_invocationsbigint ,verify_gigabytes_processed bigint ,verify_total_uncorrected_errorsbigint ,non_medium_error_count bigint);
6.1.2 創建topic
Flume採集到的數據要生成一條條的event數據傳給kafka消息系統保存,kafka需要事先創建一個topic來生產和消費指定數據。爲系統正常運行,我們統一定義topic的名字結構爲“hive-數據庫名-表名”。需要在kafka集羣節點上創建topic,示例如下:
bin/kafka-topics --create --zookeeper localhost:2181/kafka --topic hive-xdf-smart_data --partitions 1
--replication-factor 1
注意:此處的數據庫名、表名,必須爲上一步創建的hive表,因爲Flume會通過此topic名來獲取hive表的元數據信息,從而生成對應event數據。
6.1.2 配置Flume agent啓動參數
生成參數文件smart_test.conf如下:
vimsmart_test.conf
a3.channels= c3
a3.sources= r3
a3.sinks= k3
a3.sources.r3.type= exec
a3.sources.r3.channels= c3
a3.sources.r3.command= tail -F /home/xdf/exec.txt
a3.sources.r3.fileHeader= false
a3.sources.r3.basenameHeader= false
a3.sources.r3.interceptors= i3
a3.sources.r3.interceptors.i3.type =iie.flume.interceptor.CSVInterceptor$Builder
a3.sources.r3.interceptors.i3.separator= ;
a3.sources.r3.decodeErrorPolicy=IGNORE
a3.channels.c3.type= memory
a3.channels.c3.capacity= 10000
a3.channels.c3.transactionCapacity= 1000
a3.sinks.k3.channel= c3
#a3.sinks.k3.type = logger
#a3.sinks.k3.batchSize= 10
a3.sinks.k3.type= org.apache.flume.sink.kafka.KafkaSink
a3.sinks.k3.brokerList= localhost:9092
注意:
1、此處數據源sources的類型爲exec。具體命令爲:
a3.sources.r3.command= tail -F /home/xdf/exec.txt
我們定時在每個節點運行一個腳本生成一條smart數據,將數據寫入/home/xdf/exec.txt文件。
flume用上面那個命令一直監控文件/home/xdf/exec.txt,如有新數據寫入,則採集傳輸到kafka裏。
2、指定了一個自定義的第三方插件,Flume過濾器CSVInterceptor,將CSV格式的數據轉化成結構化,序列化的Event格式。
3、Sink爲KafkaSink,數據會寫到kafka裏面,特別注意:這裏需要指定對應的brokerList,示例如下:
a3.sinks.k3.brokerList = m103:9092,m105:9092
6.1.3 開啓Flume Agent
執行命令:
cd /usr/local/apache-flume-1.6.0-bin
./bin/flume-ng agent--conf conf --conf-file smart_test.conf --name a3 -Dflume.root.logger=INFO
6.1.4 生成Smart數據
在每個數據節點上運行createEvent.py腳本,生成一條結構化好的smart數據。
腳本有兩個參數smart_data.log,hive-xdf-smart_data,前者爲smart命令輸出的原始信息文件,後者是topic名字,即上一步生成的topic名。
python createEvent.pysmart_data.log hive-xdf-smart_data >
/home/xdf/exec.txt
此腳本會解析smart原始信息,生成一條帶topic字段的結構化smart數據寫入到/home/xdf/exec.txt文件中,數據格式如下:
hive-xdf-smart_data@@EB00PC208HFC;2015-06-2318:56:09;OK;28;65;0;week 08 of year2012;50000;21;200000;69;-1;-1;-1;-1;-1;-1;-1;0;0;0;0;0;0;300744.962;0;0;0;0;0;0;10841.446;0;-1;-1;-1;-1;-1;-1;-1
用符號“@@”將topic跟smart數據分開,smart數據每列間用逗號隔開。
6.1.5 測試時查看Kafka數據
查看數據是否成功生成到kafka中,可在kafka節點上,通過下面命令查看:
kafka-console-consumer--zookeeper localhost:2181/kafka --topic hive-xdf-smart_data --from-beginning
結果展示:
6.1.6 Kafka數據落地到hive表中
打開camus.properties配置文件,修改以下兩個參數
kafka.whitelist.topics=hive-xdf-smart_data ----smart數據對應topic
kafka.brokers=m105:9092,m103:9092 ----kafka broker lists
修改完配置文件後,定時運行camusrun.sh腳本,就會將新生成的smart數據接入到topic所對應的hive表中了。
camusrun.sh腳本內容入下:
#!/bin/bash
hadoop jarcamus-example-0.1.0-cdh-SNAPSHOT-shaded.jarcom.linkedin.camus.etl.kafka.CamusJob -P camus.properties
至此,數據接入流程完畢。