前言
在搭建公司的一些平台产品的时候,前端需要的渲染的数据往往是需要使用集群资源进行计算的,比如hive,spark等。然而web端对数据查询和显示有着较高的需求,所以查询端放在hive或者spark都变得不切实际,速度太慢。一般的处理方式是使用mysql当做结果存储,使用简单的select语句和where语句获取到直接的计算结果。而天级和小时级的数据需要从hdfs转移到mysql本身并不是一件难事,可以使用
hive -f
的形式将结果文件全部拉出来,然后再mysql端使用load的方式存储进mysql,但是这种方式显得太过丑陋且效率很低占用存储资源等.所以还是将整个项目数据转移形式做变革,以下是一些学习过程,记录一下,以备不时之需。
sqoop的安装
sqoop原理
sqoop快速部署
- 使用docker快速部署sqoop,这样就可以快速部署在多台离线(连接公司内网)的机器上,至于怎么搭建docker详见:Docker 学习笔记
sqoop基本操作
- 以下操作都在Docker中完成,如果部署在服务器上,一般而言,操作并没有区别
# 我安装了sqoop在docker上,现在需要重新启动容器并连接
$:~/myname$ docker restart f212703201f2 && docker attach f212703201f2 # 重启容器及进入容器
[用户名@f212703201f2 ansible]# source /etc/profile # 首先生效一下配置
[用户名@f212703201f2 ansible]# sqoop-version # 查看sqoop安装是否成功
18/09/11 06:30:41 INFO sqoop.Sqoop: Running Sqoop version: 1.4.7
Sqoop 1.4.7
git commit id 2328971411f57f0cb683dfb79d19d4d19d185dd8
Compiled by maugli on Thu Dec 21 15:59:58 STD 2017
# 连接mysql进行测试sqoop是否配置完全
[用户名@f212703201f2 ansible]# sqoop list-databases --connect jdbc:mysql://数据库ip地址:端口号/databases --username 用户名 --password 密码
-------------------- DEMO --------------------
############# 将集群上的数据导入到mysql库中 #############
sqoop export \
-D 提交的sqoop队列名 \
--connect jdbc:mysql://数据库ip地址:端口号/databases \
--username 用户名 \
--password 密码 \
--table tmp_test_sqoop \
--export-dir hdfs://xxxx/test/test_sqoop/test_sqoop \
--input-fields-terminated-by '@'
--- 字段解释
-D 为指定sqoop专属队列
--connect jdbc:mysql://数据库ip地址:端口号/databases 指定为databases数据库
--table tmp_test_sqoop 指定为databases库下的tmp_test_sqoop表
--export-dir hdfs://xxxx/test/test_sqoop/test_sqoop 导入mysql的集群上的数据源
[root@f212703201f2 ansible]# hadoop fs -cat hdfs://xxxx/test/test_sqoop/test_sqoop
a@b@c
--input-fields-terminated-by '@' 使用@进行分割
注意:
--input-fields-terminated-by:表示用于hive或hdfs数据导出到外部存储分隔参数;
--fields-terminated-by:表示用于外面存储导入到hive或hdfs中需要实现字段分隔的参数;
一顿操作之后
mysql> select * from databases.tmp_test_sqoop;
+------+--------+-----------+
| dt | poi_id | base_info |
+------+--------+-----------+
| a | b | c |
+------+--------+-----------+
1 row in set (0.05 sec)
############# 将hive数据导入到mysql #############
sqoop export \
-D 提交的sqoop队列名 \
--connect jdbc:mysql://数据库ip地址:端口号/databases \
--username 用户名 \
--password 密码 \
--table tmp_location_sqoop_0911_myname \
--export-dir hdfs://tmp_location_sqoop_0911_myname/ \
--input-fields-terminated-by '\001'
# 前提要求有对应mysql表,tmp_location_sqoop_0911_myname需要在mysql这里先建好,而路径:hdfs://tmp_location_sqoop_0911_myname/则是hive的数据存储路径,其实hive只是hdfs上数据的结构化映射而已,本质上还是集群的数据
############# mysql数据导入到hdfs #############
sqoop import \
-D 提交的sqoop队列名 \
--connect jdbc:mysql://数据库ip地址:端口号/databases \
--username 用户名 \
--password 密码 \
--table location_service_engine \
--target-dir hdfs://xxxx/test/sqoop2 \
-m 1
-P 可以用 -- password 密码 来表示,只是-P代表的是交互的密码,需要自己再手动输入一回
--target-dir 如果该目录存在,则会报错,自己测试的时候需要变更名字,目录自己会创建,并且会创建_SUCCESS文件
-m 1 使用一个map,可以杜绝因为mysql没有设置主键带来的问题,它将mysql的文件放在集群的和一个part里,因为没有主键,将不能进行hash,无法shuffle到不同的机器存储
使用
sqoop import --help
来详细查看参数的定义,import和export一般都是对集群而言的,比如说sqoop import
是指mysql的数据导入到hdfs上,sqoop export
则是集群上的数据输出到mysql
问题排查
-
sqoop无法提交任务
使用公司sqoop的专属队列进行提交
-
sqoop无法访问将hdfs数据写入到数据库
设置外部指定ip访问数据库数据表
grant all on databases.* to '用户名'@'10.83.xx.xx' identified by '密码' with grant option;
指定ip为10.83.xx.xx
用户 使用用户名:用户名
,密码
对数据库databases下的所有表拥有访问权限