准備
本示例將實現從MySQL數據庫中將數據導入到HDFS中
參考文檔:
http://sqoop.apache.org/docs/1.99.7/user/Sqoop5MinutesDemo.html
http://blog.csdn.net/m_signals/article/details/53190965
http://blog.csdn.net/lazythinker/article/details/52064165
http://blog.sina.com.cn/s/blog_61d8d9640102whof.html
mysql數據庫信息:
test庫中user表中的記錄(共1條)
HDFS數據情況
創建了一個/root/test的空目錄
實現目標:
本示例需要實現將上方MySQL數據庫中的數據導入到HDFS中
開始
啟動Hadoop,啟動sqoop,命令行進入sqoop
1 # 設置交互的命令行打印更多信息,打印的異常信息更多 2 set option --name verbose --value true 3 # 連接sqoop,其中hadoop1是需要連接的sqoop的主機名 4 set server --host hadoop1 --port 12000--webapp sqoop 5 # 查看連接 6 show version --all
創建link
如果需要使用sqoop進行導入導出操作,需要先創建連接。
使用show conncetor命令可以查看sqoop支持的連接器。
而sqoop中默認提供了如下幾種連接。
創建mysql-link
本例實現mysql-->hdfs的數據導入操作,所以需要創建一個mysql的link和hdfs的link。
注意:在創建mysql-link的時候需要將mysql的jar包放入到$SQOOP2_HOME/server/lib/extra-lib目錄中
首先創建mysql-link,過程如下
1 sqoop:000> create link -connector generic-jdbc-connector 2 Creating link for connector with name generic-jdbc-connector 3 Please fill following values to create new link object 4 Name: mysql-link 5 Database connection 6 Driverclass: com.mysql.jdbc.Driver 7 ConnectionString: jdbc:mysql://10.25.40.37/test 8 Username: root 9 Password:********* 10 FetchSize: 11 ConnectionProperties: 12 There are currently 0 values in the map: 13 entry# protocol=tcp 14 There are currently 1 values in the map: 15 protocol = tcp 16 entry# 17 SQL Dialect 18 Identifier enclose: 19 New link was successfully created with validation status OK and name mysql-link 20 sqoop:000>
以上輸入項說明,下圖中紅色的表示需要輸入的內容。
注意Identifier enclose項需要輸入一個空格,然后回車
創建hdfs-link
創建HDFS的link的配置就比較簡單,配置HDFS訪問地址和hadoop配置文件目錄路徑即可
1 sqoop:000> create link -connector hdfs-connector 2 Creating link for connector with name hdfs-connector 3 Please fill following values to create new link object 4 Name: hdfs-link 5 HDFS cluster 6 URI: hdfs://hadoop1:9000 7 Conf directory:/usr/local/hadoop/hadoop-2.7.4/etc/hadoop 8 Additional configs:: 9 There are currently 0 values in the map: 10 entry# 11 New link was successfully created with validation status OK and name hdfs-link 12 sqoop:000>
創建job
創建job時,配置項較多。
命令:
1 # create job -f formLinkName -t toLinkName 2 create job -f mysql-link -t hdfs-link
注意下面紅色部分
sqoop:000> create job -f mysql-link -t hdfs-link
Creating job for links with from name mysql-link and to name hdfs-link
Please fill following values to create new job object
Name: test1(job名稱)
Database source
Schema name: test(數據庫的schema名稱)
Table name: user(數據庫表名)
SQL statement:
Column names:
There are currently 0 values in the list:
element#
Partition column:
Partition column nullable:
Boundary query:
Incremental read
Check column:
Last value:
Target configuration
Override null value:
Null value:
File format:
0 : TEXT_FILE
1 : SEQUENCE_FILE
2 : PARQUET_FILE
Choose: 0(選擇文本文件)
Compression codec:
0 : NONE
1 : DEFAULT
2 : DEFLATE
3 : GZIP
4 : BZIP2
5 : LZO
6 : LZ4
7 : SNAPPY
8 : CUSTOM
Choose: 0(選擇NONE)
Custom codec:
Output directory: /root/test(這里輸入HDFS文件的目錄,需要是空目錄)
Append mode:
Throttling resources
Extractors: 2(這里是參考官網填的2)
Loaders: 2(這里是參考官網填的2)
Classpath configuration
Extra mapper jars:
There are currently 0 values in the list:
element#
New job was successfully created with validation status OK and name test1
sqoop:000>
啟動job
命令
1 # start job -name jobName 2 start job -name test1
期間遇到的問題及解決方案
以下問題均是創建完link和job后,開始啟動job時報的錯。
Host '10.25.40.37' is not allowed to connect to this MySQL server
錯誤原因:
這問題表示主機10.25.40.37沒有授權外部訪問其MySQL
解決方案:
將連接的MySQL主機中的授權信息改了
- 直接改mysql庫中user表root的那條記錄,將其值改為%(表示任何主機都可訪問)
- 使用授權命令,授權指定的主機可訪問該數據庫(推薦:更安全)
1 mysql> GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION; 2 mysql> FLUSH PRIVILEGES;
詳細操作步驟可自行百度。
User: root is not allowed to impersonate root
錯誤原因:
該錯誤是因為在安裝sqoop時,在hadoop的core-site.xml配置文件中配置的用戶權限錯誤
在之前的sqoop安裝文章里,按照官網的配置如下。其中hadoop.proxyuser.sqoop2.hosts中的sqoop2是用戶的意思,同理hadoop.proxyuser.sqoop2.groups中的sqoop2是用戶組的意思。
1 <property> 2 <name>hadoop.proxyuser.sqoop2.hosts</name> 3 <value>*</value> 4 </property> 5 <property> 6 <name>hadoop.proxyuser.sqoop2.groups</name> 7 <value>*</value> 8 </property>
解決方案:
將sqoop2改為root即可,改完后如下:(PS:這里的解決方案感覺還是有問題不完美,沒有深入了解)
1 <property> 2 <name>hadoop.proxyuser.root.hosts</name> 3 <value>*</value> 4 </property> 5 <property> 6 <name>hadoop.proxyuser.root.groups</name> 7 <value>*</value> 8 </property>
GENERIC_HDFS_CONNECTOR_0007:Invalid input/output directory - Unexpected exception
輸入輸出目錄有問題,檢查HDFS中是否存在相應目錄即可
There are 0 datanode(s) running and no node(s) are excluded in this operation
錯誤原因:
啟動job的時候報的錯,這應該是datanode節點數據的問題
解決方案:
- 配置dfs.datanode.data.dir和core-site.xml里面的hadoop.tmp.dir一致
hdfs-site.xml里面的
dfs.datanode.data.dir
/tmp/hdfs_tmp
與core-site.xml里面的
hadoop.tmp.dir
/tmp/hdfs_tmp
兩個配置應該是指向同一個目錄地址,而且必須是一個已經存在的linux目錄(不存在目錄的話,在啟動hadoop時,必須手動創建,否則put文件到hdfs系統時就會報錯),今天報這個錯就是因為兩個配置沒有指向同一個目錄地址,且兩個地址還不存在對應的目錄
參考至:
http://blog.sina.com.cn/s/blog_61d8d9640102whof.html
- 刪除dfs.namenode.data.dir中的current文件夾中的內容,格式化namenode,重新啟動hadoop
參考至:
http://blog.csdn.net/qiruiduni/article/details/50280943
最后我使用了1解決方案后問題解決了,但是不知道以后會不會有其他問題。
Call From hadoop1/192.168.56.110 to 0.0.0.0:10020 failed on connection exception
問題原因:
報錯信息提示,在訪問端口 100020的時候出錯,這表示DataNode 需要訪問 MapReduce JobHistory Server,而默認值是: 0.0.0.0:10020 。
解決方案:
找到{HADOOP_HOME}/etc/hadoop/mapred-site.xml配置文件 ,增加如下配置:
1 <property> 2 <name>mapreduce.jobhistory.address</name> 3 <!-- 配置實際的主機名和端口--> 4 <value>{namenode}:10020</value> 5 </property>
這里我的主機名是hadoop1,所以配置的值是hadoop1:10020
然后啟動JobHistory服務即可:
命令:mr-jobhistory-daemon.sh start historyserver
{hadoop_home}/sbin/mr-jobhistory-daemon.sh start historyserver
參考至:
http://blog.csdn.net/lazythinker/article/details/52064165
GENERIC_HDFS_CONNECTOR_0007:Invalid input/output directory - Output directory is not empty
錯誤原因:
輸入或者輸出目錄不是空目錄,本示例的錯誤原因是之前啟動job后,在HDFS里已經導入過一些數據進去。沒刪除,所以報這個錯。
解決方案:
刪除該目錄下的內容即可
清空上方創建job時指定的output目錄(/root/test)中內容即可。
驗證是否導入成功
查看HDFS中的/root/test/目錄中的數據,共出現了2個文件
查看文件內容
可以看到2ea38d69-e9e4-4364-adfc-67d88f5c8153.txt文件中已經存在了導入的數據,而8962bce1-08e7-4ebc-939e-4839d05eb145.txt是個空文件。