作者/楊彬,遼寧行政學院
Sqoop數(shù)據(jù)收集與入庫系統(tǒng)的應用
作者/楊彬,遼寧行政學院
大多數(shù)情況下單位或組織有價值的數(shù)據(jù)都要存儲在關(guān)系型數(shù)據(jù)庫系統(tǒng)中,隨著時間的累計,數(shù)據(jù)量已非常龐大,為了進一步進行處理,有些數(shù)據(jù)需要抽取出來,利用大數(shù)技術(shù)進行處理再次加工。為了能夠和Hadoop HDFS系統(tǒng)之外的數(shù)據(jù)庫系統(tǒng)機型交互,Sqoop孕育而生。Sqoop 是一款開源的工具,是Apache頂級項目,通過JDBC和關(guān)系數(shù)據(jù)庫進行交互,用戶可將數(shù)據(jù)從關(guān)系型數(shù)據(jù)庫抽取到Hadoop HDFS中;也可以把hadoop MapReduce處理完的數(shù)據(jù)導回到關(guān)系數(shù)據(jù)庫中。
數(shù)據(jù)導入;數(shù)據(jù)導出;JDBC;關(guān)系數(shù)據(jù)庫
1. Sqoop架構(gòu)
Sqoop架構(gòu)非常簡單,整合了Hive、Hbase和Oozie,通過hadoop 的MapReduce任務來傳輸數(shù)據(jù)并提供并發(fā)和容錯功能。Sqoop接收到客戶端的shell命令或者Java api命令后,通過Sqoop中的任務翻譯器把命令轉(zhuǎn)換為對應的MapReduce任務,將關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)和Hadoop HDFS中的數(shù)據(jù)進行相互轉(zhuǎn)移,進而完成數(shù)據(jù)導入和數(shù)據(jù)導入導出。Sqoop架構(gòu)如圖1所示。

圖1 Sqoop架構(gòu)
2. Sqoop數(shù)據(jù)庫導入與使用
■2.1 Sqoop數(shù)據(jù)庫導入
Sqoop是通過一個MapReduce作業(yè)從關(guān)系數(shù)據(jù)庫中導入一個表,抽取一行行記錄,然后寫入到HDFS。首先Sqoop使用JDBC來檢查將要導入的表并檢索出表中所有的列及其對應的SQL數(shù)據(jù)類型。這些SQL類型被映射到Java數(shù)據(jù)類型中,這些對應的java類型在MapReduce應用中將被作為字段值被保存,這些信息被Sqoop的代碼生成器使用來創(chuàng)建對應表的類,用于保存從表中抽取的記錄。在導入中,關(guān)鍵的是DBWritable接口的序列化方法,Widget類和JDBC進行交互使用這些方法。
JDBC的ResultSet接口提供用戶從檢查結(jié)果中檢索記錄的游標,readFields()方法將用ResultSet中一行數(shù)據(jù)的列來填充Example對象的字段。其格式如下:
Public void readFields(resultSet _dbResults)throws SQLException;
InputFormat()方法通過JDBC從一個數(shù)據(jù)庫表中讀取部分內(nèi)容,它通過 Sqoop啟動MapReduce作業(yè)來完成。
DataDriverDBInputFormat()方法能夠完成多個Map任務對查詢結(jié)果的劃分,為了提高導入性能,查詢根據(jù)表的主鍵我的做為“劃分列”來進行劃分的。在配置InputFormat之后,Sqoop將作業(yè)發(fā)送到MapReduce集群。Map任務將執(zhí)行查詢并將ResultSet中的數(shù)據(jù)反序列化到生成類的實例,這些數(shù)據(jù)保存在SequenceFile文件中也可以被分割為多個文本文件。導入指令為:Sqoop import –connect jdbc:mysql://hostname:port/database –username root –password 123456 –tablename –m n。
其構(gòu)成含義如下:
(1)––co n n e c t j d b c:m y s q l://hostname:port/database指定mysql數(shù)據(jù)庫主機名和端口號和數(shù)據(jù)庫名;
(2)––username root 指定數(shù)據(jù)庫用戶名;
(3)––password 123456 指定數(shù)據(jù)庫密碼;
(4)––tablename 導出的表名;
(5)–m n 啟動一個map進程數(shù),如果表很大,可以啟動多個map進程。
默認情況下,Sqoop會將導入的數(shù)據(jù)保存為逗號分隔的文本文件。
Sqoop從關(guān)系數(shù)據(jù)庫中導入到HDFS的過程,如圖2所示。
具體操作實例如下:關(guān)系數(shù)據(jù)庫(10.8.218.89)表為base,執(zhí)行Sqoop命令將數(shù)據(jù)從mysql導入到hive中,具體命令為:
Sqoop import ––connect jdbc:mysql://10.8.218.89:3208/dbvideo ––table base ––user root––password 123456 –m 1 ––hive–import ––hive–database dbvideo ––hive–table base ––hive–overwrite ––fields–ter–minated–by “ ”––lines–terminated–by “
”––as–textf i le
通過help指令查看sqoop導入幫助: Sqoop help import。

圖2 Sqoop從數(shù)據(jù)庫中導入到HDFS的過程
■2.2 Sqoop導入數(shù)據(jù)的使用
數(shù)據(jù)被導入HDFS,以文本格式數(shù)據(jù)可以供Hadoop Streaming中的腳本使用,也可以為TextInputFormat為默認格式運行的MapReduce作業(yè)使用。同時Sqoop和Hive可共同構(gòu)成一個強大的服務用于分析任務,在進行導入時,Sqoop可以生成hive表,將數(shù)據(jù)導入hive表,其命令如下:
Sqoop import –connect jdbc:mysql://localhost/ha–doopguide –table widgets –m 1 –hive–import
3. Sqoop數(shù)據(jù)庫導出
■3.1 Sqoop數(shù)據(jù)庫導出
Sqoop導出功能其導入功能非常相似,在執(zhí)行導出操作之前,Sqoop一般使用jdbc連接數(shù)據(jù)庫并選擇一個導出方法,Sqoop會根據(jù)目標表的定義生成一個java類,通過這個生成類從文本文件中解析記錄,接著會啟動一個MapReduce作業(yè),從HDFS中讀取源數(shù)據(jù)文件,使用生成的類解析記錄,執(zhí)行選定的導出方法。jdbc的導出方法會產(chǎn)生一批insert語句,每條語句都會向目標表中插入多條記錄。
Sqoop還可以將存儲在SequenceFile中的記錄導出到輸出表。Sqoop從SequenceFile中讀取對象,發(fā)送到OutputCollector,由它將這些對象傳遞給數(shù)據(jù)庫導出OutputFormat(),由OutputFormat()完成輸出到表的過程。Sqoop從HDFS導出到關(guān)系數(shù)據(jù)庫的過程,如圖3所示

圖3 Sqoop從HDFS導出到關(guān)系數(shù)據(jù)庫的過程
■3.2 Sqoop導出數(shù)據(jù)的執(zhí)行
在Sqoop中,導出的數(shù)據(jù)源是HDFS,關(guān)系數(shù)據(jù)庫作為目標。在將一張表從HDFS導出到關(guān)系數(shù)據(jù)庫時,須在關(guān)系數(shù)據(jù)庫中創(chuàng)建一張用于接收數(shù)據(jù)的目標表。執(zhí)行過程如下:
①先在mysql中創(chuàng)建一個具有相同序列順序的sql目標表
Create table sales(volume decimal(10,2),zip inte ger);
②接著運行導出命令:
Sqoop export –connect jdbc:mysql://localhost/ha doopguide –m 1 –table sales –export–dir /user/hive/zip_prof i ts –input–f i elds–terminated–by “