sqoop導入數據到Base並同步hive與impala

 

基礎環境

sqoop:sqoop-1.4.5+cdh5.3.6+78,hive:hive-0.13.1+cdh5.3.6+397,hbase:hbase-0.98.6+cdh5.3.6+115node

Sqool和Hive、HBase簡介

Sqoop

Sqoop是一個用來將Hadoop和關係型數據庫中的數據相互轉移的開源工具,能夠將一個關係型數據庫(例如 : MySQL ,Oracle ,Postgres等)中的數據導進到Hadoop的HDFS中,也能夠將HDFS的數據導進到關係型數據庫中。mysql

Hive

不想用程序語言開發MapReduce的朋友好比DB們,熟悉SQL的朋友可使用Hive開離線的進行數據處理與分析工做。 
Hive是基於Hadoop的一個數據倉庫工具,能夠將結構化的數據文件映射爲一張數據庫表,並提供簡單的sql查詢功能,能夠將sql語句轉換爲MapReduce任務進行運行。 
注意Hive如今適合在離線下進行數據的操做,就是說不適合在掛在真實的生產環境中進行實時的在線查詢或操做,由於一個字「慢」。 
Hive起源於FaceBook,在Hadoop中扮演數據倉庫的角色。創建在Hadoop集羣的最頂層,對存儲在Hadoop羣上的數據提供類SQL的接口進行操做。你能夠用 HiveQL進行select、join,等等操做。 
若是你有數據倉庫的需求而且你擅長寫SQL而且不想寫MapReduce jobs就能夠用Hive代替。git

Hive的內置數據類型能夠分爲兩大類:(1)、基礎數據類型;(2)、複雜數據類型。其中,基礎數據類型包括:TINYINT、SMALLINT、INT、BIGINT、BOOLEAN、FLOAT、DOUBLE、STRING、BINARY、TIMESTAMP、DECIMAL、CHAR、VARCHAR、DATE。 
下面的表格列出這些基礎類型所佔的字節以及從什麼版本開始支持這些類型。sql

數據類型 所佔字節 開始支持版本
TINYINT 1byte: -128 ~ 127  
SMALLINT 2byte:-32,768 ~ 32,767  
INT 4byte:-2,147,483,648 ~ 2,147,483,647  
BIGINT 8byte:-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807  
BOOLEAN    
FLOAT 4byte單精度  
DOUBLE 8byte雙精度  
STRING    
BINARY   從Hive0.8.0開始支持
TIMESTAMP   從Hive0.8.0開始支持
DECIMAL   從Hive0.11.0開始支持
CHAR   從Hive0.13.0開始支持
VARCHAR   從Hive0.12.0開始支持
DATE   從Hive0.12.0開始支持

複雜類型包括ARRAY、MAP、STRUCT、UNION,這些複雜類型是由基礎類型組成的。數據庫

HBase

HBase做爲面向列的數據庫運行在HDFS之上,HDFS缺少隨即讀寫操做,HBase正是爲此而出現。HBase以Google BigTable爲藍本,以鍵值對的形式存儲。項目的目標就是快速在主機內數十億行數據中定位所需的數據並訪問它。 
HBase是一個數據庫,一個NoSql的數據庫,像其餘數據庫同樣提供隨即讀寫功能,Hadoop不能知足實時須要,HBase正能夠知足。若是你須要實時訪問一些數據,就把它存入HBase。apache

你能夠用Hive做爲靜態數據倉庫,HBase做爲數據存儲,放那些進行一些會改變的數據。在Hive中,普通表是存儲在HDFS中,而你能夠經過建立EXTERNAL TABLE外表來指定數據存儲位置,能夠是系統目錄,也能夠是ElasticSearch,還能夠是HBase。 
在使用Sqoop從Mysql導出數據入Hadoop時,就須要考慮是直接入Hive(此時是普通表),仍是導入數據到HBase,Sqoop同時支持導入這兩種導入。安全

測試Sqoop

 
  1. #測試MySQL鏈接
  2. [hdfs@node196 bin]$ sqoop list-databases --connect jdbc:mysql://192.168.180.11/angel --username anqi –P
  3.  
  4. #檢驗SQL語句
  5. [hdfs@node196 bin]$ sqoop eval --connect jdbc:mysql://192.168.180.11/angel --username anqi --password anqi_mima \
  6. --query "SELECT xi.*, jing.name,wang.latitude,wang.longitude \
  7. FROM xi ,jing, wang \
  8. WHERE xi.id=jing.foreignId AND wang.id=xi.id AND xi.date>='2015-09-01' AND xi.date<='2015-10-01'"

以上Sqoop語句執行事後,能夠確認Sqoop運行正常,Sqoop鏈接MySQL正常。架構

使用Sqoop從MySQL導入數據到Hive

使用複雜SQL

 
  1. #從MySQL導入數據到Hive
  2. [hdfs@node196 bin]$ sqoop eval --connect jdbc:mysql://192.168.180.11/angel --username anqi --password anqi_mima \
  3. --query "SELECT xi.*, jing.name,wang.latitude,wang.longitude \
  4. FROM xi ,jing, wang \
  5. WHERE xi.id=jing.foreignId AND wang.id=xi.id AND xi.date>='2015-09-01' AND xi.date<='2015-10-01' \
  6. AND \$CONDITIONS" \
  7. --split-by date --hive-import -m 5 \
  8. --target-dir /user/hive/warehouse/anqi_wang \
  9. --hive-table anqi_wang

注意: 
因爲使用Sqoop從MySQL導入數據到Hive須要指定target-dir,所以導入的是普通表而不能爲外部表。app

如下簡要列舉了Sqoop的執行過程:工具

 
  1. BoundingValsQuery: SELECT MIN(date), MAX(date) FROM (SELECT xi.*, jing.name,wang.latitude,wang.longitude FROM xi ,jing, wang WHERE xi.id=jing.foreignId AND wang.id=xi.id AND xi.date>='2015-09-01' AND xi.date<='2015-10-01' AND (1 = 1) ) AS t1
  2.  
  3. 15/10/13 13:11:47 INFO mapreduce.JobSubmitter: number of splits:5
  4.  
  5. 15/10/12 13:40:28 INFO mapreduce.Job: map 0% reduce 0%
  6. 15/10/12 13:40:39 INFO mapreduce.Job: map 20% reduce 0%
  7. 15/10/12 13:40:40 INFO mapreduce.Job: map 40% reduce 0%
  8. 15/10/12 13:40:47 INFO mapreduce.Job: map 60% reduce 0%
  9. 15/10/12 13:40:48 INFO mapreduce.Job: map 80% reduce 0%
  10. 15/10/12 13:40:52 INFO mapreduce.Job: map 100% reduce 0%

能夠看出,--split-by設置後,job按設置值切分,切分個數爲-m設置值(-m 5 不設置的話默認job切分數是4)。經檢驗,此種較複雜的SQL語句,Sqoop支持得很好。

調整Hive數據類型

上面任務執行成功後,通過檢測,發現Hive表結構中的數據類型與MySQL對應列有以下關係:

 
  1. MySQL(bigint) --> Hive(bigint)
  2. MySQL(tinyint) --> Hive(tinyint)
  3. MySQL(int) --> Hive(int)
  4. MySQL(double) --> Hive(double)
  5. MySQL(bit) --> Hive(boolean)
  6. MySQL(varchar) --> Hive(string)
  7. MySQL(decimal) --> Hive(double)
  8. MySQL(date/timestamp) --> Hive(string)

能夠看出MySQL的decimal類型變成了Hive中的double類型。此時須要在導入時經過--map-column-hive 做出映射關係指定,以下所示:

 
  1. [hdfs@node196 bin]$ sqoop import \
  2. --connect jdbc:mysql://192.168.184.12/angel --username anqi --password anqi_mima \
  3. --query "SELECT * FROM xi WHERE date>='2015-09-16' AND date<='2015-10-01' \
  4. AND \$CONDITIONS" \
  5. --split-by date --hive-import -m 5 \
  6. --map-column-hive cost="DECIMAL",date="DATE" \
  7. --target-dir /user/hive/warehouse/xi \
  8. --hive-table xi

以上命令能夠執行成功,然而Hive列類型設置爲DECIMAL時,從Mysql[decimal(12,2)]-->Hive[decimal]會致使導入後小數丟失。

注意: 
對於cost="DECIMAL(10,2)"這樣指定精確度的映射語句的執行,在Sqoop1.4.5中執行失敗。這是Sqoop1.4.5的一個BUG,詳情見:https://issues.apache.org/jira/browse/SQOOP-2103,它在1.4.7版本中修復。

不斷更新

將上面Sqoop語句執行兩次,在執行第二次時會出現錯誤:

 
  1. ERROR tool.ImportTool: Encountered IOException running import job: org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory hdfs://node190:8020/user/hive/warehouse/anqi_wang already exists

這表示HDFS中已經存在相應存儲,此時須要執行Sqoop-Hive的增量導入語句。

注意: 
因爲Hive沒有rowkey,其hdfs存儲決定了Sqoop-Hive只能添加,update更新導入沒法進行。

使用Sqoop從MySQL導入數據到HBase

使用複雜SQL

 
  1. #從MySQL導入數據到HBase
  2. [hdfs@node196 bin]$ sqoop import \
  3. --connect jdbc:mysql://192.168.184.12/angel --username anqi --password anqi_mima \
  4. --query "SELECT * FROM xi WHERE 1=1 \
  5. AND \$CONDITIONS" \
  6. --hbase-table hxi --hbase-create-table \
  7. --hbase-row-key id --split-by date -m 7 \
  8. --column-family aitanjupt

上面SQL語句較簡單。經檢驗,更復雜的SQL語句,Sqoop支持得很好,導入正常。

不斷更新

以上指定了HBase的Rowkey後,再次執行從MySQL導入數據到HBase的Sqoop語句,基於相同的Rowkey值,HBase內相應的行會進行更新替換。

Hive使用HBase數據

 
  1. CREATE EXTERNAL TABLE default.angel(
  2. id BIGINT,
  3. username STRING,
  4. password STRING)
  5. ROW FORMAT SERDE 'org.apache.hadoop.hive.hbase.HBaseSerDe'
  6. STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
  7. WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key, angel:username, angel:password")
  8. TBLPROPERTIES("hbase.table.name" = "hxi");

關於Hive使用存儲在HBase中的數據,更多詳細信息能夠查看《使用Hive或Impala執行SQL語句,對存儲在HBase中的數據操做》一文。

關於Sqoop2

架構上,Sqoop1使用MapOnly做業進行Hadoop(HDFS/HBase/Hive)同關係數據庫進行數據的導入導出,用戶使用命令行方式與之交互,數據傳輸和數據格式緊密耦合;易用性欠佳,Connector數據格式支持有限,安全性很差,對Connector的限制過死。Sqoop2則創建了集中化的服務,負責管理完整的MapReduce做業,提供多種用戶交互方式(CLI/WebUI/RESTAPI),具備權限管理機制,具備規範化的Connector,使得它更加易用,更加安全,更加專一。

綜上所述

使用Sqoop從MySQL導入數據到HBase要比導入到Hive方便,使用Hive對HBase數據操做時,也無decimal精度相關BUG,而且能夠很好的支持更新。所以建議使用Sqoop從MySQL導入數據到HBase,而非直接Hive。

通過測試,使用Sqoop從MySQL導入數據到HBase,100萬條需花費7~12分鐘。impala對於hbase的查詢效率也沒有對hdfs效率高。

本文會不按期更新,如有不對之處請前往原文出處:http://www.cnblogs.com/wgp13x/ 進行指正。

同步hive與impala

1.只要建立hive表時,與hbase中的表作了映射,表名和字段名能夠不一致,以後不管在hbase中新增刪除數據仍是在hive中,都會自動同步。

若是在hive裏面是建立的外部表須要在hbase中先建立,內部表則會在hbase中自動建立指定的表名。

由於hive不支持刪除等操做,而hbase裏面比較方便,因此咱們能夠採用這種方式

2.若是在hive裏面作了新增、刪除數據庫、表或者數據等更新操做,須要執行在impala裏面執行INVALIDATEMETADATA;命令才能將hive的數據同步impala;

若是直接在impala裏面新增、刪除數據庫、表或者數據,會自動同步到hive,無需執行任何命令。

同步整合參考:

https://www.jb51.net/article/124693.htm

https://blog.csdn.net/a2011480169/article/details/51588253

相關文章
相關標籤/搜索