


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