摘要:隨著大數(shù)據(jù)技術(shù)在高校的快速應(yīng)用,如何高效地在關(guān)系型數(shù)據(jù)庫與Hadoop之間進行數(shù)據(jù)傳輸成了必須解決的問題。文章針對這一需求,設(shè)計了一種基于Sqoop的數(shù)據(jù)自動傳輸方案。方案首先分析了Sqoop的基本原理和安裝方法,之后結(jié)合高校教務(wù)系統(tǒng),闡述了利用Sqoop實現(xiàn)數(shù)據(jù)導(dǎo)入、導(dǎo)出和增量同步的具體方法,并給出了完整的命令和Shell腳本程序。實際應(yīng)用表明,該方案能夠有效地實現(xiàn)數(shù)據(jù)自動傳輸,提升了數(shù)據(jù)處理效率。
關(guān)鍵詞:數(shù)據(jù)傳輸;Sqoop;Hadoop;關(guān)系數(shù)據(jù)庫;數(shù)據(jù)中心;大數(shù)據(jù);高校
中圖分類號:TP311.13 文獻標識碼:A
文章編號:1009-3044(2025)02-0060-04 開放科學(資源服務(wù)) 標識碼(OSID) :
0 引言
隨著高校信息化建設(shè)的不斷推進,各個業(yè)務(wù)系統(tǒng)產(chǎn)生了海量數(shù)據(jù)。為了更好地挖掘和利用這些數(shù)據(jù),高校紛紛構(gòu)建數(shù)據(jù)中心,將分散在各個業(yè)務(wù)系統(tǒng)的數(shù)據(jù)集中存儲和處理,以支持數(shù)據(jù)分析、決策支持等應(yīng)用。然而,傳統(tǒng)的關(guān)系型數(shù)據(jù)庫難以滿足海量數(shù)據(jù)的存儲和處理需求,因此需要將數(shù)據(jù)遷移到分布式計算平臺Hadoop中進行處理。處理后的結(jié)果數(shù)據(jù)還需要回傳到關(guān)系數(shù)據(jù)庫中,以便于進行數(shù)據(jù)可視化等后續(xù)處理。Sqoop就是一種能夠高效實現(xiàn)Hadoop與關(guān)系型數(shù)據(jù)庫之間數(shù)據(jù)傳輸?shù)拈_源工具[1]。
1 Sqoop 簡介
Sqoop是Hadoop生態(tài)圈中一個數(shù)據(jù)遷移組件,可實現(xiàn)數(shù)據(jù)的雙向傳輸。將數(shù)據(jù)從關(guān)系數(shù)據(jù)庫傳輸?shù)紿adoop 集群(HDFS、Hive 或HBase) 稱為Sqoop 導(dǎo)入;反之,數(shù)據(jù)從Hadoop 集群傳輸?shù)疥P(guān)系數(shù)據(jù)庫稱為Sqoop 導(dǎo)出。Sqoop 存在兩個系列版本Sqoop1 和Sqoop2,相較于Sqoop2,Sqoop1架構(gòu)更為簡單,部署和使用更加方便,因此本項目選擇Sqoop1作為數(shù)據(jù)傳輸工具。
Sqoop通過將數(shù)據(jù)傳輸任務(wù)轉(zhuǎn)換為MapReduce作業(yè)來實現(xiàn)數(shù)據(jù)的導(dǎo)入和導(dǎo)出。如圖1所示,Sqoop的工作流程如下[2]。
1) 接收命令:Sqoop接收用戶輸入的導(dǎo)入或?qū)С雒睢?/p>
2) 獲取元數(shù)據(jù)生成記錄容器類:Sqoop連接到關(guān)系型數(shù)據(jù)庫,獲取要傳輸?shù)谋淼脑獢?shù)據(jù)信息,包括Schema、表名、字段名、字段類型等,根據(jù)元數(shù)據(jù)生成一個記錄容器類。
3) 啟動MapReduce作業(yè):Sqoop根據(jù)傳輸要求,自動生成一個只有Map任務(wù)的MapReduce作業(yè),然后啟動作業(yè)開始數(shù)據(jù)傳輸,容器類向Map提供數(shù)據(jù)保存及轉(zhuǎn)換功能。
4) 數(shù)據(jù)傳輸:Sqoop可使用多個Map任務(wù)并行傳輸。在導(dǎo)入過程中,數(shù)據(jù)是從數(shù)據(jù)庫傳輸?shù)紿DFS;在導(dǎo)出過程中,數(shù)據(jù)是從HDFS傳輸?shù)綌?shù)據(jù)庫。
2 Sqoop 環(huán)境部署
在使用Sqoop之前,首先需要搭建其運行環(huán)境。假定Sqoop的安裝包及數(shù)據(jù)庫所需的JDBC連接包均已完成下載,下面是在Hadoop 2.x集群的數(shù)據(jù)節(jié)點上部署Sqoop(本例版本為1.4.7.bin__hadoop-2.6.0) 環(huán)境的具體步驟。
2.1 釋放Sqoop 軟件包
將/soft 目錄下的Sqoop 安裝包釋放到/apps 目錄下:
tar -xzvf /soft/sqoop-1.4.7. bin__hadoop-2.6.0. tar.gz -C /apps
將釋放后的目錄重命名,便于后續(xù)引用:
mv /apps/sqoop-1.4.7.bin__hadoop-2.6.0 /apps/sqoop
2.2 修改環(huán)境變量
修改用戶配置文件,如.bashrc,在文件末尾添加如下兩行文本:
export SQOOP_HOME=/apps/sqoop
export PATH=$SQOOP_HOME/bin:$PATH
使配置立即生效:
source ~/.bashrc
2.3 拷貝MySQL 的JDBC 包
將MySQL 的JDBC 連接包拷貝到Sqoop 的lib 目錄下:
cp/soft/mysql-connector-java-5.1.42-bin. jar /apps/sqoop/lib
如果是Oracle或其他數(shù)據(jù)庫,則需要拷貝它們所對應(yīng)的JDBC連接包。
2.4 配置Sqoop
在$SQOOP_HOME/conf/sqoop-env.sh文件末行添加如下內(nèi)容,作用是告訴Sqoop關(guān)于Hadoop、HBase、Hive等軟件的相關(guān)路徑:
export HADOOP_COMMON_HOME=/apps/hadoop
export HADOOP_MAPRED_HOME=/apps/hadoop
export HBASE_HOME=/apps/hbase
export HIVE_HOME=/apps/hive
#export ZOOCFGDIR=/apps/zookeeper
之后,通常使用命令sqoop version 和sqoop listdatabases進行安裝結(jié)果的驗證,如果正常執(zhí)行則表示成功安裝[3]。
3 Sqoop 導(dǎo)入導(dǎo)出命令及參數(shù)
導(dǎo)入命令格式:
sqoop import --參數(shù)1 值1 --參數(shù)2 值2 …… -- 參數(shù)n 值n
導(dǎo)出命令格式:
sqoop export --參數(shù)1 值1 --參數(shù)2 值2 …… -- 參數(shù)n 值n
命令可選參數(shù)很多,除了三個基本的數(shù)據(jù)庫連接參數(shù)——connect lt;jdbc-urigt;、username lt;usernamegt;和password lt;passwordgt;以外,其他常用參數(shù)如表1所示。
對HBase分布式數(shù)據(jù)庫的導(dǎo)入Sqoop也是提供支持的,HBase 相關(guān)的參數(shù)有column-family lt;列族gt;、hbase-row-key lt;行鍵gt;、hbase-table lt;Hbase 表gt;等[4],限于篇幅,本文將不再做HBase的相關(guān)介紹。
4 導(dǎo)入導(dǎo)出具體實現(xiàn)
4.1 數(shù)據(jù)導(dǎo)入
實際系統(tǒng)中會涉及多種業(yè)務(wù)系統(tǒng)數(shù)據(jù)源的導(dǎo)入,下面選擇幾種典型場景進行分析。
1) 將MySQL表導(dǎo)入HDFS中
$sqoop import \
--connect jdbc:mysql://dbsvr1:3306/jwdb?charac?terEnconding=UTF-8 \
--username root --password root \
--table student -m 3 \
--target-dir /jwxtdir/students \
--fields-terminated-by ','
命令及參數(shù)說明:
此命令實現(xiàn)將MySQL表導(dǎo)入HDFS的功能;
MySQL的主機為dbsvr1,端口是標準3306時可以不寫,數(shù)據(jù)源是jwdb數(shù)據(jù)庫,由于數(shù)據(jù)含有中文字符,需要使用選項“characterEnconding=UTF-8”;
數(shù)據(jù)庫用戶名是root,密碼root;
數(shù)據(jù)源是數(shù)據(jù)表student;
啟用3個map任務(wù)并行導(dǎo)入;
導(dǎo)入目標位置是HDFS 的/jwxtdir/students 目錄,需注意/jwxtdir/students路徑的最后一級目錄students,導(dǎo)入時會自動創(chuàng)建,導(dǎo)入前不能存在;
文件內(nèi)部用逗號分隔各數(shù)據(jù)項。
2) 將MySQL表導(dǎo)入Hive表中
$sqoop import \
--connect jdbc: mysql://dbsvr1/jwdb? characterEn?conding=UTF-8 \
--username root --password root \
--table student -m 3 \
--hive-import --hive-table studhive \
--fields-terminated-by ',' \
--hive-overwrite \
--delete-target-dir
命令及參數(shù)說明:
此命令實現(xiàn)將MySQL數(shù)據(jù)庫表向Hive表的數(shù)據(jù)導(dǎo)入功能[5];
啟用3個map并行任務(wù);
目標表studhive 是Hive 中提前創(chuàng)建好的,且與student表結(jié)構(gòu)一致的Hive表,未指定Hive數(shù)據(jù)庫默認使用default數(shù)據(jù)庫;
覆蓋Hive表中已經(jīng)存在的數(shù)據(jù);
如果存在目標目錄則先刪除。
向Hive導(dǎo)入過程中可能會出現(xiàn)一些報錯或異常,常見原因有缺少jar包、數(shù)據(jù)庫不存在、版本不兼容等,需要根據(jù)提示信息做相應(yīng)處理。
3) 增量導(dǎo)入
增量導(dǎo)入就是僅導(dǎo)入數(shù)據(jù)源中有變化的數(shù)據(jù)。通過記錄前次導(dǎo)入的狀態(tài),Sqoop可以檢測出哪些數(shù)據(jù)是新增或更新的,增量導(dǎo)入模式避免了重復(fù)導(dǎo)入全部數(shù)據(jù),提高了傳輸效率。
Sqoop提供了兩種增量導(dǎo)入模式:一是append模式,適用于源表中存在自增主鍵且主鍵值是遞增的情形;二是lastmodified模式,適用于源表包含有時間戳列的情形。增量導(dǎo)入命令中,通過check-column 和last-value 參數(shù)指定要檢查的列及上次已導(dǎo)入的最大值。
以下代碼段完成append模式的增量導(dǎo)入,它將導(dǎo)入sno值超過7 000的行。
$sqoop import \
--connect jdbc: mysql://dbsvr1/jwdb? characterEn?conding=UTF-8 \
--username root --password root \
--table student \
--target-dir /jwxtdir/students/incredata -m 2 \
--incremental append --check-column sno --last-value 7000
以下代碼段實現(xiàn)lastmodified模式的增量導(dǎo)入,它將抽取“2024-03-16 22:33:42”以后新產(chǎn)生的行進行導(dǎo)入。
$sqoop import \
--connect jdbc: mysql://dbsvr2/yktdb? characterEn?conding=UTF-8 \
--username root --password root \
--table cards \
--target-dir /yktdbdir/cards/incredata -m 2 \
--incremental lastmodified \
--check-column order_date --last-value '2024-03-16 22:33:42'
增量導(dǎo)入結(jié)束時,Sqoop輸出信息中會包含lastvalue值,用戶需要記錄此值以備下次使用。需要注意check-column不支持字符系列類型。
4) 導(dǎo)入整個數(shù)據(jù)庫
sqoop import-all-tables
--connect jdbc: mysql://dbsvr1/jwdb? characterEn?conding=UTF-8
4.2 數(shù)據(jù)導(dǎo)出
經(jīng)過處理后得到的結(jié)果數(shù)據(jù),可能在Hive表中,也可能在HDFS的文件中,無論哪種情況,都可使用sqoop命令導(dǎo)出。以下是從HDFS導(dǎo)出數(shù)據(jù)到MySQL 的命令格式。
$sqoop export \
--connect jdbc: mysql://dbsvr2/yktdb? characterEn?conding=UTF-8\
--username root \
--password root \
--table cardstotalb -m 1 \
--export-dir hdfs://master: 9000/results/part-m-00000 \
--input-fields-terminated-by ','
export-dir可以是具體文件也可以是目錄,示例中part-m-00000就是一個具體文件,文件內(nèi)數(shù)據(jù)項用逗號分隔,cardstotalb是擬接收數(shù)據(jù)的MySQL表,需提前創(chuàng)建好,并且二者結(jié)構(gòu)要一致。
Hive表的數(shù)據(jù)導(dǎo)出,可以按HDFS文件進行導(dǎo)出,命令基本相同,不再詳述。
4.3 自動增量導(dǎo)入
在實際應(yīng)用中,學校的多個業(yè)務(wù)系統(tǒng)如教務(wù)系統(tǒng)、圖書館系統(tǒng)、學生信息系統(tǒng)以及一卡通系統(tǒng)等,會持續(xù)不斷地生成新的數(shù)據(jù)。為了保持數(shù)據(jù)中心的數(shù)據(jù)實時性,需要定期將這些新增的數(shù)據(jù)同步到Hadoop 平臺,為此,編寫一個增量導(dǎo)入Shell腳本,并將其設(shè)置為定時執(zhí)行任務(wù),即可實現(xiàn)增量數(shù)據(jù)的自動導(dǎo)入。下面以表student的append模式導(dǎo)入為例說明具體實現(xiàn)方案。
第一步,編寫實現(xiàn)增量導(dǎo)入邏輯的Shell腳本文件import.sh。其關(guān)鍵點是記錄每次所導(dǎo)入數(shù)據(jù)的檢查列最大值,該最大值會在下次導(dǎo)入時作為last-value參數(shù)的值進行設(shè)定。本方案中是利用一個名為maxval?uefile的文件來專門保存這個最大值,保證導(dǎo)入數(shù)據(jù)不重復(fù)、不遺漏。首次執(zhí)行腳本之前,文件maxvalue?file的內(nèi)容須由用戶手動初始化,此后腳本程序會根據(jù)每次導(dǎo)入的數(shù)據(jù)情況自動對該文件予以更新。im?port.sh文件具體內(nèi)容如下。
#!/bin/bash
#===========1.參數(shù)準備
#設(shè)置數(shù)據(jù)庫連接信息(mysql主機、數(shù)據(jù)庫、表)
dbsvr=\"dbsvr1\"
dbsvr=\"dbsvr1\"
table=\"student\"
#設(shè)置數(shù)據(jù)庫登錄信息(用戶名、密碼)
username=\"root\"
password=\"root\"
#設(shè)置導(dǎo)入?yún)?shù)(HDFS目錄、檢查列)
dirname=\"/jwxtdir/students/inc`date +%F`\"
colname='sno'
#初始化最大值變量
maxvalue=0
#設(shè)置SQOOP_HOME環(huán)境變量
export SQOOP_HOME=/apps/sqoop
#===========2. 定義函數(shù)auto_import,實現(xiàn)增量導(dǎo)入
#導(dǎo)入期間的報告信息保存于baklog文件
auto_import () {
$SQOOP_HOME/bin/sqoop import --connect jdbc:mysql://$dbsvr: 3306/${dbname}? characterEnconding=UTF-8 --username ${username} --password ${pass?word} --table ${table} -m 2 --target-dir ${dirname} --incremental append --check-column ${colname} --last-value ${maxvalue} amp;gt; ~hadoop/baklog
}
#===========3.導(dǎo)入數(shù)據(jù)
#讀取maxvaluefile 文件內(nèi)容,為maxvalue 變量賦值
maxvalue=`cat ~hadoop/maxvaluefile`
#調(diào)用導(dǎo)入函數(shù),執(zhí)行導(dǎo)入操作
auto_import
#===========4.更新maxvaluefile文件
#從baklog文件提取下次導(dǎo)入需要的last-value,保存到 maxvaluefile文件
grep \"last-value\" ~hadoop/baklog|awk -F - '{print$4}'|awk '{print $2}' gt; ~hadoop/maxvaluefile
#===========腳本文件結(jié)束
第二步,設(shè)置定時任務(wù),實現(xiàn)腳本周期性執(zhí)行,這里使用Linux內(nèi)置的crontab工具來實現(xiàn),步驟如下。
1) 為腳本設(shè)置x執(zhí)行權(quán)限。
chmod +x /home/hadoop/import.sh
2) 確保自動調(diào)度服務(wù)cron處于啟動狀態(tài)
#查看cron服務(wù)狀態(tài)
sudo service cron status
#若未啟動,則啟動cron服務(wù)
sudo service cron start
3) Hadoop集群管理員(此處即hadoop用戶) 設(shè)置任務(wù)調(diào)度時程表
crontab -u hadoop -e
在打開頁面中添加一行文本,指出何時、執(zhí)行何任務(wù)。每一行文本包括6列,其中前5列對應(yīng)含義分別是分鐘、小時、月份中的第幾日、月份、一周中的第幾天(0-6) ,*代表任意,最后一列是要執(zhí)行的命令或程序。例如,下面一行文本設(shè)置后將會在每天的23點50分自動執(zhí)行腳本import.sh。
50 23 * * * /home/hadoop/import.sh
5 結(jié)束語
學校的教務(wù)、學生、一卡通、圖書館等系統(tǒng)涉及MySQL與Oracle兩種數(shù)據(jù)庫,利用Sqoop能較好實現(xiàn)與數(shù)據(jù)中心的數(shù)據(jù)傳輸。文中給出的只是實現(xiàn)的基本思路與核心代碼框架,并未詳盡闡述針對各種特殊或異常情況的判斷與處理機制。在實際應(yīng)用時,必須根據(jù)具體場景細化控制流程,融入對潛在問題的預(yù)判與應(yīng)對策略。
參考文獻:
[1] 徐亦卿.大數(shù)據(jù)技術(shù)發(fā)展認識基礎(chǔ)上的分支技術(shù)體系分析[J].電腦知識與技術(shù),2021,17(27):33-34.
[2] 于潔,馬維旻,吳俊.大數(shù)據(jù)離線分析系統(tǒng)安裝部署:Hadoop[M].北京:高等教育出版社,2022.
[3] 李霄揚,朱恒.基于HHS的離線數(shù)據(jù)分析平臺的設(shè)計與實現(xiàn)[J].電腦知識與技術(shù),2023,19(10):75-77.
[4] apache.Sqoop User Guide (v1.4.7)[EB/OL].[2024-12-20].https://sqoop.apache.org/docs/1.4.7.
[5] 周少珂,郭璇,張振平,等.大數(shù)據(jù)Hadoop集群下Sqoop數(shù)據(jù)傳輸技術(shù)研究[J].河南科技,2024(6):25-28.
【通聯(lián)編輯:王 力】