一. Sqoop介绍

Sqoop是一个用来将Hadoop和关系型数据库中的数据相互转移的工具,可以将一个关系型数据库(例如:MySQL、Oracle、Postgres等)中的数据导进到HadoopHDFS中,也可以将HDFS的数据导进到关系型数据库中。对于某些NoSQL数据库它也提供了连接器。Sqoop,类似于其他ETL工具,使用元数据模型来判断数据类型并在数据从数据源转移到Hadoop时确保类型安全的数据处理。Sqoop专为大数据批量传输设计,能够分割数据集并创建Hadoop任务来处理每个区块。

本文版本说明

hadoop版本 : hadoop-2.7.2

hive版本 : hive-2.1.0

sqoop版本:sqoop-1.4.6

二. Mysql 数据导入到 Hive

1). 将mysqlpeople_access_log表导入到hiveweb.people_access_log,并且hive中的表不存在。

mysql中表people_access_log数据为:

  1. 1,15110101010,1577003281739,'112.168.1.2','https://www.baidu.com'
  2. 2,15110101011,1577003281749,'112.16.1.23','https://www.baidu.com'
  3. 3,15110101012,1577003281759,'193.168.1.2','https://www.taobao.com'
  4. 4,15110101013,1577003281769,'112.18.1.2','https://www.baidu.com'
  5. 5,15110101014,1577003281779,'112.168.10.2','https://www.baidu.com'
  6. 6,15110101015,1577003281789,'11.168.1.2','https://www.taobao.com'

mysql数据导入hive的命令为:

  1. sqoop import \
  2. --connect jdbc:mysql://master1.hadoop:3306/test \
  3. --username root \
  4. --password 123456 \
  5. --table people_access_log \
  6. -m 1 \
  7. --hive-import \
  8. --create-hive-table \
  9. --fields-terminated-by '\t' \
  10. --hive-table web.people_access_log

该命令会启用一个mapreduce任务,将mysql数据导入到hive表,并且指定了hive表的分隔符为\t,如果不指定则为默认分隔符^A(ctrl+A)

参数说明

参数 说明
--connect mysql的连接信息
--username mysql的用户名
--password mysql的密码
--table 被导入的mysql源表名
-m 并行导入启用的map任务数量,与--num-mapper含义一样
--hive-import 插入数据到hive当中,使用hive默认的分隔符,可以使用--fields-terminated-by参数来指定分隔符。
-- hive-table hive当中的表名

2). 也可以通过--query条件查询Mysql数据,将查询结果导入到Hive

  1. sqoop import \
  2. --connect jdbc:mysql://master1.hadoop:3306/test \
  3. --username root \
  4. --password 123456 \
  5. --query 'select * from people_access_log where \$CONDITIONS and url = "https://www.baidu.com"' \
  6. --target-dir /user/hive/warehouse/web/people_access_log \
  7. --delete-target-dir \
  8. --fields-terminated-by '\t' \
  9. -m 1
参数 说明
--query 后接查询语句,条件查询需要\$CONDITIONS and连接查询条件,这里的\$表示转义$,必须有.
--delete-target-dir 如果目标hive表目录存在,则删除,相当于overwrite.

三. Hive数据导入到Mysql

还是使用上面的hiveweb.people_access_log,将其导入到mysql中的people_access_log_out表中.

  1. sqoop export \
  2. --connect jdbc:mysql://master1.hadoop:3306/test \
  3. --username root \
  4. --password 123456 \
  5. --table people_access_log_out \
  6. --input-fields-terminated-by '\t' \
  7. --export-dir /user/hive/warehouse/web.db/people_access_log \
  8. --num-mappers 1

注意:mysqlpeople_access_log_out需要提前建好,否则报错:ErrorException: Table 'test.people_access_log_out' doesn't exist。如果有id自增列,hive表也需要有,hive表与mysql表字段必须完全相同。

  1. create table people_access_log_out like people_access_log;

执行完一个mr任务后,成功导入到mysqlpeople_access_log_out中.

四. mysql数据增量导入hive

实际中mysql数据会不断增加,这时候需要用sqoop将数据增量导入hive,然后进行海量数据分析统计。增量数据导入分两种,一是基于递增列的增量数据导入(Append方式)。二是基于时间列的增量数据导入(LastModified方式)。有几个核心参数:

  • –check-column:用来指定一些列,这些列在增量导入时用来检查这些数据是否作为增量数据进行导入,和关系型数据库中的自增字段及时间戳类似.注意:这些被指定的列的类型不能使任意字符类型,如char、varchar等类型都是不可以的,同时–check-column可以去指定多个列
  • –incremental:用来指定增量导入的模式,两种模式分别为AppendLastmodified
  • –last-value:指定上一次导入中检查列指定字段最大值

1. 基于递增列Append导入

接着前面的日志表,里面每行有一个唯一标识自增列ID,在关系型数据库中以主键形式存在。之前已经将id在0~6之间的编号的订单导入到Hadoop中了(这里为HDFS),现在一段时间后我们需要将近期产生的新的订 单数据导入Hadoop中(这里为HDFS),以供后续数仓进行分析。此时我们只需要指定–incremental 参数为append–last-value参数为6即可。表示只从id大于6后即7开始导入。

1). 创建hive

首先我们需要创建一张与mysql结构相同的hive表,假设指定字段分隔符为\t,后面导入数据时候分隔符也需要保持一致。

2). 创建job

增量导入肯定是多次进行的,可能每隔一个小时、一天等,所以需要创建计划任务,然后定时执行即可。我们都知道hive的数据是存在hdfs上面的,我们创建sqoop job的时候需要指定hive的数据表对应的hdfs目录,然后定时执行这个job即可。

当前mysql中数据,hive中数据与mysql一样也有6条:

id user_id access_time ip url
1 15110101010 1577003281739 112.168.1.2 https://www.baidu.com
2 15110101011 1577003281749 112.16.1.23 https://www.baidu.com
3 15110101012 1577003281759 193.168.1.2 https://www.taobao.com
4 15110101013 1577003281769 112.18.1.2 https://www.baidu.com
5 15110101014 1577003281779 112.168.10.2 https://www.baidu.com
6 15110101015 1577003281789 11.168.1.2 https://www.taobao.com

增量导入有几个参数,保证下次同步的时候可以接着上次继续同步.

  1. sqoop job --create mysql2hive_job -- import \
  2. --connect jdbc:mysql://master1.hadoop:3306/test \
  3. --username root \
  4. --password 123456 \
  5. --table people_access_log \
  6. --target-dir /user/hive/warehouse/web.db/people_access_log \
  7. --check-column id \
  8. --incremental append \
  9. --fields-terminated-by '\t' \
  10. --last-value 6 \
  11. -m 1

这里通过sqoop job --create job_name命令创建了一个名为mysql2hive_jobsqoop job

3). 执行job

创建好了job,后面只需要定时周期执行这个提前定义好的job即可。我们先往mysql里面插入2条数据。

  1. INSERT INTO `people_access_log` (`id`,`user_id`,`access_time`,`ip`,`url`) VALUES
  2. (7,15110101016,1577003281790,'112.168.1.3','https://www.qq.com'),
  3. (8,15110101017,1577003281791,'112.1.1.3','https://www.microsoft.com');

这样mysql里面就会多了2条数据。此时hive里面只有id1 ~ 6的数据,执行同步job使用以下命令。

  1. sqoop job -exec mysql2hive_job

执行完成后,发现刚才mysql新加入的id7 ~ 8的两条数据已经同步到hive

  1. hive> select * from web.people_access_log;
  2. OK
  3. 1 15110101010 1577003281739 112.168.1.2 https://www.baidu.com
  4. 2 15110101011 1577003281749 112.16.1.23 https://www.baidu.com
  5. 3 15110101012 1577003281759 193.168.1.2 https://www.taobao.com
  6. 4 15110101013 1577003281769 112.18.1.2 https://www.baidu.com
  7. 5 15110101014 1577003281779 112.168.10.2 https://www.baidu.com
  8. 6 15110101015 1577003281789 11.168.1.2 https://www.taobao.com
  9. 7 15110101016 1577003281790 112.168.1.3 https://www.qq.com
  10. 8 15110101017 1577003281791 112.1.1.3 https://www.microsoft.com

由于实际场景中,mysql表中的数据,比如订单表等,通常是一致有数据进入的,这时候只需要将sqoop job -exec mysql2hive_job这个命令定时(比如说10分钟频率)执行一次,就能将数据10分钟同步一次到hive数据仓库。

2. Lastmodified 导入实战

append适合业务系统库,一般业务系统表会通过自增ID作为主键标识唯一性。Lastmodified适合ETL的数据根据时间戳字段导入,表示只导入比这个时间戳大,即比这个时间晚的数据。

1). 新建一张表

mysql中新建一张表people_access_log2,并且初始化几条数据:

  1. CREATE TABLE `people_access_log2` (
  2. `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
  3. `user_id` bigint(20) unsigned NOT NULL COMMENT '用户id',
  4. `access_time` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  5. `ip` varchar(15) NOT NULL COMMENT '访客ip',
  6. `url` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
  7. PRIMARY KEY (`id`)
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

插入数据:

  1. insert into people_access_log2(id,user_id, ip, url) values(1,15110101010,'112.168.1.200','https://www.baidu.com');
  2. insert into people_access_log2(id,user_id, ip, url) values(2,15110101011,'112.16.1.2','https://www.baidu.com');
  3. insert into people_access_log2(id,user_id, ip, url) values(3,15110101012,'112.168.1.2','https://www.taobao.com');
  4. insert into people_access_log2(id,user_id, ip, url) values(4,15110101013,'112.168.10.2','https://www.baidu.com');
  5. insert into people_access_log2(id,user_id, ip, url) values(5,15110101014,'112.168.1.2','https://www.jd.com');
  6. insert into people_access_log2(id,user_id, ip, url) values(6,15110101015,'112.168.12.4','https://www.qq.com');

mysql里面的数据就是这样:

id user_id access_time ip url
1 15110101010 2019-12-28 16:23:10 112.168.1.200 https://www.baidu.com
2 15110101011 2019-12-28 16:23:33 112.16.1.2 https://www.baidu.com
3 15110101012 2019-12-28 16:23:41 112.168.1.2 https://www.taobao.com
4 15110101013 2019-12-28 16:23:46 112.168.10.2 https://www.baidu.com
5 15110101014 2019-12-28 16:23:52 112.168.1.2 https://www.jd.com
6 15110101015 2019-12-28 16:23:56 112.168.12.4 https://www.qq.

2). 初始化hive表:

初始化hive数据,将mysql里面的6条数据导入hive中,并且可以自动帮助我们创建对应hive表,何乐而不为,否则我们需要自己手动创建,完成初始化工作。

  1. sqoop import \
  2. --connect jdbc:mysql://master1.hadoop:3306/test \
  3. --username root \
  4. --password 123456 \
  5. --table people_access_log2 \
  6. --hive-import \
  7. --create-hive-table \
  8. --fields-terminated-by ',' \
  9. --hive-table web.people_access_log2

可以看到执行该命令后,启动了二一个mapreduce任务,这样6条数据就进入hiveweb.people_access_log2了:

  1. hive> select * from web.people_access_log2;
  2. OK
  3. 1 15110101010 2019-12-28 16:23:10.0 112.168.1.200 https://www.baidu.com
  4. 2 15110101011 2019-12-28 16:23:33.0 112.16.1.2 https://www.baidu.com
  5. 3 15110101012 2019-12-28 16:23:41.0 112.168.1.2 https://www.taobao.com
  6. 4 15110101013 2019-12-28 16:23:46.0 112.168.10.2 https://www.baidu.com
  7. 5 15110101014 2019-12-28 16:23:52.0 112.168.1.2 https://www.jd.com
  8. 6 15110101015 2019-12-28 16:23:56.0 112.168.12.4 https://www.qq.com
  9. Time taken: 0.326 seconds, Fetched: 6 row(s)

3). 增量导入数据:

我们再次插入一条数据进入mysqlpeople_access_log2表:

  1. insert into people_access_log2(id,user_id, ip, url) values(7,15110101016,'112.168.12.45','https://www.qq.com');

此时,mysql表里面已经有7条数据了,我们使用incremental的方式进行增量的导入到hive:

  1. sqoop import \
  2. --connect jdbc:mysql://master1.hadoop:3306/test \
  3. --username root \
  4. --password 123456 \
  5. --table people_access_log2 \
  6. --hive-import \
  7. --hive-table people_access_log2 \
  8. -m 1 \
  9. --check-column access_time \
  10. --incremental lastmodified \
  11. --last-value "2019-12-28 16:23:56" \

2019-12-28 16:23:56就是第6条数据的时间,这里需要指定。报错了:

  1. 19/12/28 16:17:25 ERROR tool.ImportTool: Error during import: --merge-key or --append is required when using --incremental lastmodified and the output directory exists.

注意:可以看到--merge-key or --append is required when using --incremental lastmodified意思是,这种基于时间导入模式,需要指定--merge-key或者--append参数,表示根据时间戳导入,数据是直接在末尾追加(append)还是合并(merge),这里使用merge方式,根据id合并:

  1. sqoop import \
  2. --connect jdbc:mysql://master1.hadoop:3306/test \
  3. --username root \
  4. --password 123456 \
  5. --table people_access_log2 \
  6. --hive-import \
  7. --hive-table web.people_access_log2 \
  8. --check-column access_time \
  9. --incremental lastmodified \
  10. --last-value "2019-12-28 16:23:56" \
  11. --fields-terminated-by ',' \
  12. --merge-key id

执行该命令后,与直接导入不同,该命令启动了2个mapreduce任务,这样就把数据增量merge导入hive表了.

  1. hive> select * from web.people_access_log2 order by id;
  2. OK
  3. 1 15110101010 2019-12-28 16:23:10.0 112.168.1.200 https://www.baidu.com
  4. 2 15110101011 2019-12-28 16:23:33.0 112.16.1.2 https://www.baidu.com
  5. 3 15110101012 2019-12-28 16:23:41.0 112.168.1.2 https://www.taobao.com
  6. 4 15110101013 2019-12-28 16:23:46.0 112.168.10.2 https://www.baidu.com
  7. 5 15110101014 2019-12-28 16:23:52.0 112.168.1.2 https://www.jd.com
  8. 6 15110101015 2019-12-28 16:23:56.0 112.168.12.4 https://www.qq.com
  9. 6 15110101015 2019-12-28 16:23:56.0 112.168.12.4 https://www.qq.com
  10. 7 15110101016 2019-12-28 16:28:24.0 112.168.12.45 https://www.qq.com
  11. Time taken: 0.241 seconds, Fetched: 8 row(s)

可以看到id=6的数据,有2条,它的时间刚好是--last-value指定的时间,则会导入大于等于--last-value指定时间的数据,这点需要注意。

sqoop用法之mysql与hive数据导入导出的更多相关文章

  1. 利用sqoop将hive数据导入导出数据到mysql

    一.导入导出数据库常用命令语句 1)列出mysql数据库中的所有数据库命令  #  sqoop list-databases --connect jdbc:mysql://localhost:3306 ...

  2. Hive数据导入导出的几种方式

    一,Hive数据导入的几种方式 首先列出讲述下面几种导入方式的数据和hive表. 导入: 本地文件导入到Hive表: Hive表导入到Hive表; HDFS文件导入到Hive表; 创建表的过程中从其他 ...

  3. 如何利用sqoop将hive数据导入导出数据到mysql

    运行环境  centos 5.6   hadoop  hive sqoop是让hadoop技术支持的clouder公司开发的一个在关系数据库和hdfs,hive之间数据导入导出的一个工具. 上海尚学堂 ...

  4. Sqoop -- 用于Hadoop与关系数据库间数据导入导出工作的工具

    Sqoop是一款开源的工具,主要用于在Hadoop相关存储(HDFS.Hive.HBase)与传统关系数据库(MySql.Oracle等)间进行数据传递工作.Sqoop最早是作为Hadoop的一个第三 ...

  5. 从零自学Hadoop(16):Hive数据导入导出,集群数据迁移上

    阅读目录 序 导入文件到Hive 将其他表的查询结果导入表 动态分区插入 将SQL语句的值插入到表中 模拟数据文件下载 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并 ...

  6. Hive 实战(1)--hive数据导入/导出基础

    前沿: Hive也采用类SQL的语法, 但其作为数据仓库, 与面向OLTP的传统关系型数据库(Mysql/Oracle)有着天然的差别. 它用于离线的数据计算分析, 而不追求高并发/低延时的应用场景. ...

  7. 数据仓库Hive数据导入导出

    Hive库数据导入导出 1.新建表data hive (ebank)> create table data(id int,name string) > ROW FORMAT DELIMIT ...

  8. Hive数据导入导出

    Hive三种不同的数据导出的方式 (1)  导出到本地文件系统 insert overwrite local directory '/home/anjianbing/soft/export_data/ ...

  9. Hive数据导入/导出

    1.1 导入/导出规则 EXPORT 命令导出数据表或分区,与元数据一起输出到指定位置.又可以从这个输出位置移动到不同的Hadoop 或Hive 实例中,并且使用IMPORT 命令导入. 当导出一个分 ...

随机推荐

  1. 802.11抓包软件对比之Microsoft Network Monitor

    从事WiFi嵌入式软件开发的同学,802.11协议层抓包分析是一个需要熟练掌握的一个技能,需要通过分析WiFi底层802.11协议层的数据包来定位问题.同时从学习802.11协议的角度而言,最有效的学 ...

  2. thinkPHP 无法加载控制器:Hello

    出现这种问题的情况下要看看: (1).控制器的名称是否写对,控制器的命名规范(别忘下class) 控制器的命名规则1.必须采用大驼峰的命名规则2.必须以Controller.class.php来结尾I ...

  3. IO模式 select、poll、epoll

    阻塞(blocking).非阻塞(non-blocking):最常听到阻塞与非阻塞这两个词就是在函数调用中,比如waitid这个函数,通过NOHANG参数可以把waitid设置为非阻塞的,也就是问询一 ...

  4. TIOBE 11月指数:C语言居首,稳居宝座,Python直逼第二!

    官方网址:https://www.tiobe.com/tiobe-index/   ​ 这是自近20年前TIOBE指数开始以来,Java和C第一次不再占据前两位.C仍然是第一位的,但是现在第二个位置是 ...

  5. 测试:DOCX

    先拿到的是需求文档和接口文档以及测试用例模块,[以及之前写好的测试用例]再根据分配的任务进行编写用例 [智能看懂业务需求]现有功能点,在编写用例 [项目介绍]: 辽阳农商惠生活项目是作为一个农户和银行 ...

  6. 【NOIP2011模拟11.1】钓鱼

    钓鱼 题目 Description 我们把钓鱼的过程放在坐标系里来考虑.图中蓝色的点为船,初始时它的坐标记为(Ax,y).河深为y,河宽为x.某个时刻会从左边界或右边界游出来一条鱼(左边的往右边游,右 ...

  7. 音视频处理基础知识扫盲:数字视频YUV像素表示法以及视频帧和编解码概念介绍

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt+moviepy音视频剪辑实战 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一. ...

  8. Python中可迭代对象是什么?

    Python中可迭代对象(Iterable)并不是指某种具体的数据类型,它是指存储了元素的一个容器对象,且容器中的元素可以通过__iter__( )方法或__getitem__( )方法访问. __i ...

  9. PyQt(Python+Qt)学习随笔:QTabWidget部件选项卡可用状态访问方法isTabEnabled、setTabEnabled

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTabWidget的每个选项卡及页面可设置是否可用,如果选项卡不可用时,则不能通过操作手工切换到该 ...

  10. 第10.4节 Python模块的弱封装机制

    一. 引言 Python模块可以为调用者提供模块内成员的访问和调用,但某些情况下, 因为某些成员可能有特殊访问规则等原因,并不适合将模块内所有成员都提供给调用者访问,此时模块可以类似类的封装机制类似的 ...