1. 程式人生 > >sqoop簡單操作-從mysql匯入匯出資料

sqoop簡單操作-從mysql匯入匯出資料

轉:http://blog.csdn.net/chaiyiping/article/details/40295881

安裝和配置:

tar -zxvf sqoop-1.4.6.bin__hadoop-2.0.4-alpha.tar.gz
	
	vi /etc/profile
	#sqoop environment
	export SQOOP_HOME=/home/hadoop/cloud/sqoop-1.4.6.bin__hadoop-2.0.4-alpha
	export PATH=$PATH:$SQOOP_HOME/bin
	儲存退出
	source /etc/profile


一,將本地資料放入hive表中

1,本地資料

本地檔案data1.txt中有兩列資料,如下:

1 aaa  
2 bbb  
3 ccc  
4 ddd  
5 eee  
... 

2,在hive中建立表

hive> create table table1                                    
    > (id int,name string)  
    > ROW FORMAT DELIMITED  
    > FIELDS TERMINATED BY ' '  
    > STORED AS TEXTFILE;  
OK  
Time taken: 0.082 seconds

列與data1.txt中的資料對應,並給出資料分割的字元,在data1.txt中是空格符“ ” 所以FIELDS TERMINATED BY ' '

3,上傳檔案中的資料到表table1中

load data local inpath '/home/hadoop/data1.txt' into table  default.table1

注意:hive本身是不儲存資料的,簡單一點來說可以把它看做是mapreduce的一個包裝,讓使用者可以通過簡單的方式呼叫mapreduce來訪問hdfs中的資料。事實上它的資料本身還是放在hdfs上的。還記得之前在配置的時候設定了hive在hdfs中的warehouse嗎?那就是hive放資料的地方。那就看一下table1的資料位置吧:
hive> dfs -ls /user/hive/warehouse/table1  
    > ;  
Found 1 items  
-rw-r--r--   1 hadoop supergroup        131 2014-10-20 09:06 /user/hive/warehouse/table1/data1.txt

可以看到實際上它只是把data1.txt放到了自己對應的hdfs的目錄下,table1的資料本事還是儲存在data1.txt這個文字檔案中的。

查詢一下table1中的資料:

hive> select * from table1;  
OK  
1   aaa  
2   bbb  
3   ccc  
4   ddd  
5   eee  
...  
Time taken: 0.093 seconds, Fetched: 20 row(s) 

二,通過sqoop把hive中的表匯出到mysql資料庫

1,在mysql中建立表用來儲存匯入資料

mysql> use hive  
Reading table information for completion of table and column names  
You can turn off this feature to get a quicker startup with -A  
  
Database changed

選擇資料庫hive
mysql> create table import1 (id int,name varchar(10));  
Query OK, 0 rows affected (0.07 sec)

建立表import1用來儲存資料

2,利用sqoop將hive中的表匯出到mysql的表中

sqoop export -connect jdbc:mysql://hadoop06:3306/hive -username root -password 123456 -table import1 -export-dir /user/hive/warehouse/table1 -input-fields-terminated-by ' ';

實際上還是從hdfs中匯出檔案到mysql,所以還是要給出input-fields-terminated-by ' '

再檢視MySQL中的表import中的資料:

mysql> select * from import1  
    -> ;  
+------+------+  
| id   | name |  
+------+------+  
|   17 | qqq  |  
|   18 | rrr  |  
|   19 | sss  |  
|   20 | ttt  |  
...  
|   14 | nnn  |  
|   15 | ooo  |  
|   16 | ppp  |  
+------+------+  
20 rows in set (0.00 sec) 
可以看到亂序了,這是因為mapreduce的原因...

三,通過sqoop將mysql中的表匯入到hive

sqoop import --connect jdbc:mysql://hadoop06:3306/hive --username root --password 123456 --table import1 --hive-import --split-by 'id'
     這裡也要給出split-by引數,sqoop通過這裡的引數值來分配mapreduce任務。sqoop會將切分的不同區域的任務分配給不同的map中。每個map再從資料庫中一行一行的獲取值然後寫入到hdfs中。split-by根據不同的引數有不同的切分方法,例如int型,它會選取最大的值和最小的值根據傳入的-m引數(預設為1)來確定劃分幾個區域。預設的split-by引數是要匯入的表的主鍵,如果沒有給出引數又沒有主鍵,匯入操作就會失敗報錯
1.執行匯入的操作命令:在Sqoop的安裝目錄下輸入命令 sqoop import --connect jdbc:mysql://資料庫主機ip:3306/資料庫名 --username root --password 123456 --table tablename --hive-import -m 1;


 2.對命令及出現的問題說明:


(1)執行匯入時,實際上在內部執行了三個步驟:


        第一步將資料匯入hdfs,
        第二步建立hive表名相同的表,
        第三步將hdfs上資料傳入hive表中


(2)最開始執行匯入後,可在Hadoop下使用fs命令在HDFS中看見匯入的資料,在Hive中使用“show tables;”沒法看見對應的表,原因是之前執行匯入的命令中,沒有加入 “--hive-import”引數;


(3)報異常:hive.HiveImport: Exception in thread "main" java.lang.NoSuchMethodError:  org.apache.thrift.EncodingUtils.setBit(BIZ)B。


     解決辦法:這是因為在同路徑下安裝了hive和hbase,而hbase和hive的lib目錄下的thrift版本不同。hbase下的為libthrift-0.8.0.jar,hive下的為libthrift-0.9.0.jar。將Hbase下的0.8.0版的刪除,換為0.9.0的即可。ps:不知為什麼Sqoop向Hive中匯入資料還有Hbase的事;
 
報異常:ERROR tool.ImportTool: Encountered IOException running import job: org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory hdfs://ns1/user/hadoop/import1 already exists
 
解決辦法:出現這個問題,啥也不用說,先把HDFS中的輸出目錄幹掉 hadoop dfs -rmr /user/hadoop/import1;


匯入完成之後檢視Hive中的資料:
hive> select * from import1;  
OK  
1   aaa  
2   bbb  
3   ccc  
...  
19  sss  
20  ttt  
16  ppp  
Time taken: 0.293 seconds, Fetched: 20 row(s) 

更詳細操作

http://lib.csdn.net/article/hive/45629

http://lib.csdn.net/article/hive/45638