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
Sqoop是一个用来将Hadoop和关系型数据库中的数据相互转移的开源工具,能够将一个关系型数据库(例如 : MySQL ,Oracle ,Postgres等)中的数据导进到Hadoop的HDFS中,也能够将HDFS的数据导进到关系型数据库中。mysql
不想用程序语言开发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做为面向列的数据库运行在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同时支持导入这两种导入。安全
#测试MySQL链接
[hdfs@node196 bin]$ sqoop list-databases --connect jdbc:mysql://192.168.180.11/angel --username anqi –P
#检验SQL语句
[hdfs@node196 bin]$ sqoop eval --connect jdbc:mysql://192.168.180.11/angel --username anqi --password anqi_mima \
--query "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'"
以上Sqoop语句执行事后,能够确认Sqoop运行正常,Sqoop链接MySQL正常。架构
#从MySQL导入数据到Hive
[hdfs@node196 bin]$ sqoop eval --connect jdbc:mysql://192.168.180.11/angel --username anqi --password anqi_mima \
--query "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 \$CONDITIONS" \
--split-by date --hive-import -m 5 \
--target-dir /user/hive/warehouse/anqi_wang \
--hive-table anqi_wang
注意:
因为使用Sqoop从MySQL导入数据到Hive须要指定target-dir,所以导入的是普通表而不能为外部表。app
如下简要列举了Sqoop的执行过程:工具
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
15/10/13 13:11:47 INFO mapreduce.JobSubmitter: number of splits:5
15/10/12 13:40:28 INFO mapreduce.Job: map 0% reduce 0%
15/10/12 13:40:39 INFO mapreduce.Job: map 20% reduce 0%
15/10/12 13:40:40 INFO mapreduce.Job: map 40% reduce 0%
15/10/12 13:40:47 INFO mapreduce.Job: map 60% reduce 0%
15/10/12 13:40:48 INFO mapreduce.Job: map 80% reduce 0%
15/10/12 13:40:52 INFO mapreduce.Job: map 100% reduce 0%
能够看出,--split-by设置后,job按设置值切分,切分个数为-m设置值(-m 5 不设置的话默认job切分数是4)。经检验,此种较复杂的SQL语句,Sqoop支持得很好。
上面任务执行成功后,通过检测,发现Hive表结构中的数据类型与MySQL对应列有以下关系:
MySQL(bigint) --> Hive(bigint)
MySQL(tinyint) --> Hive(tinyint)
MySQL(int) --> Hive(int)
MySQL(double) --> Hive(double)
MySQL(bit) --> Hive(boolean)
MySQL(varchar) --> Hive(string)
MySQL(decimal) --> Hive(double)
MySQL(date/timestamp) --> Hive(string)
能够看出MySQL的decimal类型变成了Hive中的double类型。此时须要在导入时经过--map-column-hive 做出映射关系指定,以下所示:
[hdfs@node196 bin]$ sqoop import \
--connect jdbc:mysql://192.168.184.12/angel --username anqi --password anqi_mima \
--query "SELECT * FROM xi WHERE date>='2015-09-16' AND date<='2015-10-01' \
AND \$CONDITIONS" \
--split-by date --hive-import -m 5 \
--map-column-hive cost="DECIMAL",date="DATE" \
--target-dir /user/hive/warehouse/xi \
--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语句执行两次,在执行第二次时会出现错误:
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更新导入没法进行。
#从MySQL导入数据到HBase
[hdfs@node196 bin]$ sqoop import \
--connect jdbc:mysql://192.168.184.12/angel --username anqi --password anqi_mima \
--query "SELECT * FROM xi WHERE 1=1 \
AND \$CONDITIONS" \
--hbase-table hxi --hbase-create-table \
--hbase-row-key id --split-by date -m 7 \
--column-family aitanjupt
上面SQL语句较简单。经检验,更复杂的SQL语句,Sqoop支持得很好,导入正常。
以上指定了HBase的Rowkey后,再次执行从MySQL导入数据到HBase的Sqoop语句,基于相同的Rowkey值,HBase内相应的行会进行更新替换。
CREATE EXTERNAL TABLE default.angel(
id BIGINT,
username STRING,
password STRING)
ROW FORMAT SERDE 'org.apache.hadoop.hive.hbase.HBaseSerDe'
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key, angel:username, angel:password")
TBLPROPERTIES("hbase.table.name" = "hxi");
关于Hive使用存储在HBase中的数据,更多详细信息能够查看《使用Hive或Impala执行SQL语句,对存储在HBase中的数据操做》一文。
架构上,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