Sqoop 数据迁移工具
sqoop : SQL to hadOOP
两个功能:
1、 RDB 向HDFS导入
2、 HDFS向RDB导入
注:拷贝mysql-connector.jar 和 json.jar 到sqoop/lib目录下
HDFS导入使用
命令很长,一般写成shell脚本。(运行需要启动 HDFS 、Yarn[mapreduce作业必须]、SQL)
COLUMN 、WHERE限定
sqoop import \ #import指从sql导入到hdfs --connect jdbc:mysql://localhost:3306/test \ # 可选 --driver com.mysql.jdbc.Driver #test是目标数据库名 --table customers \ #目标表名 --columns "fname,lname" \ #可以使用columns指定字段 --where "order_date>'2019-1-1'" \ #可以使用where筛选原数据 --username root \ #数据库登陆用户名 --password rw \ #密码 --target-dir /sqoop/test_rdb/customers \ #hdfs 的目标路径,不指定的话会放在/user/【username】/【tbl_name】下 --delete-target-dir \ #覆盖到hdfs(即删除原目录),慎选 -m 3 #map工作者数目,决定最终文件数 #导入的结果是csv格式的文件
注意:斜杠符需要前空格
自由Query查询导入
sqoop import \ #import指从sql导入到hdfs --connect jdbc:mysql://localhost:3306/test \ #test是目标数据库名 #自由查询不需要指定--table,会冲突 #目标表名 --query "select * from userinfos where host!='127.0.0.1' and \$CONDITIONS" \ # '\$CONDITIONS' 查询必须以该语句结尾 --split-by 'username' \ #指定按照那个字段分区(split到各个mapper) --username root \ --password rw \ --target-dir /sqoop/test_rdb/customers \ #自由查询必须要指定,因为无法根据--table 自动生成目录名 -m 3
增量导入
--incremental append|lastmodified #指定增量方式,append追加记录,lastmodified更新 --check-column fieldname \ #指定增量列,排序列 --last-value 'xxxx' \ #上一次导入时,check-column的最大值,从这个值开始升序导入
注:lastmodified 要求排序列必须是时间戳(int)或者日期格式(yyyy-MM-dd)
HDFS导入总结:
必要参数: sqoop import \ --connect jdbc:mysql://ip:3306/dbname --username name \ --password passwd \ --table tbl_name \ 可选参数: -m 3 #指定mapper工作者数量 -as-sequencefile|textfile|parquetfile|avrodatafile #存储类型 自由查询: --query "select ... and \$CONDITIONS" \ --target-dir /path/ \ #必须 --split-by 'filedName' #可选 一般限定: --columns "field1,field2" \ #可选 --where "field<=value" \ #可选 --target-dir /path/ \ #可选
HIVE导入使用
sqoop import \ --connect jdbc.... --table orders \ #也可以使用query --username root \ --password rw \ --hive-import \ --create-hive-table \ #自动建表,表元数据同sql,名已存在会报错,一般不用。--hive-overwrite是自动覆盖旧表。 --hive-database dbname \ #目标hive数据库和表 --hive-table orders \ #也可以使用库名.表名的方式 -m 3
指定分区
--hive-partition-key "field_name" \ --hive-partition-value "value" \ #通过字段和值,指定要存储的分区。
可能的运行错误:
——————————————————————————————————
Q: ERROR hive.HiveConfig: Could not load org.apache.hadoop.hive.conf.HiveConf. Make sure HIVE_CONF_DIR is set correctly.
A:往/etc/profile最后加入
export HADOOP_CLASSPATH=HADOOP_CLASSPATH:$HIVE_HOME/lib/*
export HIVE_CONF_DIR=/opt/hive/conf
A2:复制hive/lib目录下的hive-common*包到sqoop/lib目录下
——————————————————————————————————
Q:ERROR Could not register mbeans java.security.AccessControlException: access denied
("javax.management.MBeanTrustPermission" "register")
A:将hive-site.xml复制到${SQOOP_HOME}/conf下即可.
A2:添加以下代码到${JDK_HOME}/jre/lib/security/java.policy
grant { permission javax.management.MBeanTrustPermission "register"; };
——————————————————————————————————
Q:ERROR exec.DDLTask: java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ObjectMapper.readerFor(Ljava/lang/Class;)Lcom/fasterxml/jackson/databind/ObjectReader;
A:jackson jar包版本冲突,将sqoop/lib下的jackson.jar备份(mv移动到另一个目录下), 然后将hive/lib包下的jackson.*拷贝到sqoop/lib下。
——————————————————————————————————
Q:IOException throw in HIVE
A:复制hive/lib/log4j-slf4j-impl* 包到sqoop/lib 目录下,或者export HADOOP_CLASSPATH=HADOOP_CLASSPATH:$HIVE_HOME/lib/*
HBase导入使用
sqoop import \ --connect jdbc:mysql://localhost:3306/test \ --username root \ --password rw \ --table customers \ --columns "customer_id,custmoer_firstname,customer_lastname" \ --hbase-table customerinfo \ --column-family CustomerName \ --hbase-row-key customernum \ -m 1
HDFS导出到mysql
sqoop export \ --connect jdbc:mysql://localhost:3306/test \ --username root \ --password rw \ --table customers \ #这是目标sql库中的表,表必须已存在 --export-dir /data/sqoop/emp \ #源文件路径 -m 1
#其他的同导入,运行时反过来就可以了 #!/bin/bash sqoop export \ --connect jdbc:mysql://localhost:3306/mytest \ --username root \ --password rw \ --table customers \ #这是目标sql库中的表,表必须已存在 --fields-terminated-by "\001" \ #默认字段分隔符是\001,如果DDL时指定了则使用指定的分隔符 --export-dir /user/hive/warehouse/customers \ #这是hive中表内容的存储目录,desc formatted tbl -m 1