当前位置: 首页>数据库>正文

sqoop需要mysql连接 sqoop mysql到mysql

最近需要使用hive做离线计算,但是现有的样例数据是mysql导出的sql文件。进到hive直接source导入是不行的,会报错,因为CREATE的语法貌似不太一样。找了一圈也没有直接能处理整个数据库迁移的,使用sqoop也需要一个一个表的导入,还好sqoop可以创建表,不然还得自己写创建表的语句就太崩溃了。sqoop会报很多错,一个个解决,用网上的说法和打地鼠样的,哈哈。解决方法在第二节配置里有写。然后因为懒,每个表的迁移执行命令写成了脚本循环去跑,表名提取写了个函数提取了,所以整个要做的就是整个sql文件导入到mysql中,hive创建数据库,配置脚本然后执行。

一、安装部署sqoop

1、下载解压

http://mirror.bit.edu.cn/apache/sqoop/1.4.7/sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz

2、配置/conf/sqoop-env.sh

把template拷贝一下,添加以下内容

export HADOOP_COMMON_HOME=/opt/hadoop-2.7.7

export HADOOP_MAPRED_HOME=/opt/hadoop-2.7.7

export HIVE_HOME=/opt/apache-hive-2.3.6-bin

3、添加lib

将mysql-connector的jar包拷贝到sqoop的lib目录下。

4、测试

列出mysql所有的表:

./sqoop list-tables --connect jdbc:mysql://localhost:3306/test?useSSL=false --username root --password 123456

会列出所有的表,相当于mysql下执行show tables;

 

二、系统配置

1、拷贝hive的hive-site.xml复制到conf目录下

未拷贝涉及报错ERROR hive.HiveConfig: Could not load org.apache.hadoop.hive.conf.HiveConf

2、配置环境变量

vim /etc/profile,添加如下:

export CLASSPATH=.:$HIVE_HOME/lib

export HIVE_CONF_DIR=/opt/apache-hive-2.3.6-bin/conf

export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$HIVE_HOME/lib/*

export SQOOP_HOME=/opt/sqoop-1.4.7.bin__hadoop-2.6.0

保存后记得source一下,未配置可能报错涉及HiveConf

 

3、文件夹所属用户

使用root用户解压,不知道为什么解压后所有文件的用户均是非root用户。要保持和hive那些的用户一致。

chown -R root:root sqoop-1.4.7.bin__hadoop-2.6.0

 

4、报错ERROR Could not register mbeans java.security.AccessControlException: access denied

解决方法:

#vim $JAVA_HOME/jre/lib/security/java.policy

在grant{}内部添加如下内容:

permission javax.management.MBeanTrustPermission "register";

详细报错如下:

main ERROR Could not register mbeans java.security.AccessControlException: access denied ("javax.management.MBeanTrustPermission" "register")

       at java.security.AccessControlContext.checkPermission(AccessControlContext.java:457)

       at java.lang.SecurityManager.checkPermission(SecurityManager.java:585)

       at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.checkMBeanTrustPermission(DefaultMBeanServerInterceptor.java:1848)

       at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:322)

       at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:522)

       at org.apache.logging.log4j.core.jmx.Server.register(Server.java:380)

……

 

5、报错exec.DDLTask: java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ObjectMapper.readerFor

解决方法:

是由于sqoop的lib目录下面的jackson相关的包的版本与hive的lib目录下的jackson相关jar包的版本不一致导致的。

将hive下的所有jackson相关jar全部copy到sqoop的lib目录下面

#cp -r $HIVE_HOME/lib/jackson-*   $SQOOP_HOME/lib/

然后将重复的低版本的全部删掉就可以了。(切记不要全部删除,有些是不重复的)

详细报错如下:

ERROR exec.DDLTask: java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ObjectMapper.readerFor(Ljava/lang/Class;)Lcom/fasterxml/jackson/databind/ObjectReader;

       at org.apache.hadoop.hive.common.StatsSetupConst$ColumnStatsAccurate.<clinit>(StatsSetupConst.java:165)

       at org.apache.hadoop.hive.common.StatsSetupConst.parseStatsAcc(StatsSetupConst.java:297)

       at org.apache.hadoop.hive.common.StatsSetupConst.setBasicStatsState(StatsSetupConst.java:230)

       at org.apache.hadoop.hive.common.StatsSetupConst.setBasicStatsStateForCreateTable(StatsSetupConst.java:292)

       at org.apache.hadoop.hive.ql.plan.CreateTableDesc.toTable(CreateTableDesc.java:839)

FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. com.fasterxml.jackson.databind.ObjectMapper.readerFor(Ljava/lang/Class;)Lcom/fasterxml/jackson/databind/ObjectReader;

20/04/22 23:51:39 ERROR ql.Driver: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. com.fasterxml.jackson.databind.ObjectMapper.readerFor(Ljava/lang/Class;)Lcom/fasterxml/jackson/databind/ObjectReader;

参考链接:

https://www.clzg.cn/article/74991.html

 

三、Sqoop命令说明

参数说明

--connect #关系型数据库连接

--username #关系型数据库连接用户名

--password #关系型数据库连接密码

--table #关系型数据库的表

--split-by #如果-m的数量不为1,则一定要加上该参数且最好是数值类型,否则会报错

--direct #快速模式,使用mysql自带的mysqldump导出数据

--delete-target-dir #如果hdfs的目录已经存在则先删除

--target-dir #导入到hdfs时的目标目录

--export-dir #从hdfs导出时的源目录

--fields-terminated-by #导入到hdfs时的hdfs文件分隔符

--input-fields-terminated-by #从hdfs导出时的hdfs文件分隔符

--hive-drop-import-delims #导入hive中的数据某列中如果有换行符或回车键可以删除

--hive-database #hive的数据库

--hive-table #hive的表

--hive-overwrite #覆盖之前的分区插入数据

--hive-partition-key #hive分区字段

--hive-partition-value #hive分区值

-m #指定map数量,也是生成的文件数。不要大于hdfs的节点数量

特别说明:如果指定的map的数量不为1,则一定要加上–split-by参数且最好是数值类型

 

例如一个迁移apps表,在hive中有新建数据库test,但没有此表。

./sqoop import \
--connect "jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf8" \
--username root \
--password 123456 \
--table apps \
--delete-target-dir \
--hive-drop-import-delims \
--fields-terminated-by "\t" \
--lines-terminated-by "\n" \
--hive-import \
--hive-overwrite \
--create-hive-table \
--hive-database test \
--hive-table apps \
-m 1

另外还有

--query "SELECT * FROM emp WHERE 1=1" #只迁移select语句后的数据

--null-string '\\N'  #处理string类型的null值,用‘\\N’替代

--null-non-string '\\N'   #处理非string类型的null值,用‘\\N’替代

 

四、迁移数据库的脚本

sql文件需要自己source导入到mysql。hive里的数据库还是要自己创建的。

CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `test`;

新建一个sqoop_import.sh文件,如果没有执行权限,需要chmod 777一下,脚本如下:

#!/bin/sh

#mysql
mysql_name=root
mysql_passwd=123456
mysql_conn="jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf8"

#hive
hive_db=test

tables=(apps abilities)

for hive_table in ${tables[*]};do
  echo ${hive_table}

  ${SQOOP_HOME}/bin/sqoop import \
  --connect ${mysql_conn} \
  --username ${mysql_name} \
  --password ${mysql_passwd} \
  --table ${hive_table} \
  --delete-target-dir \
  --hive-drop-import-delims \
  --fields-terminated-by "\t" \
  --lines-terminated-by "\n" \
  --hive-import \
  --hive-overwrite \
  --create-hive-table \
  --hive-database ${hive_db} \
  --hive-table ${hive_table} \
  --null-string '\N' \
  --null-non-string '\N' \
  -m 1 \
  >> sqoop_import.log
done

tables=(apps abilities)变量括号里的就是表名列表字符串,可以使用show tables自己拼一下。我懒,所以就写了个提取的函数如下:

public static String getMysqlTables() {
        File fileIn = new File("test.sql");
        BufferedReader reader = null;
        String keyword = "CREATE TABLE";
        String tableList = "";

        try {
            reader = new BufferedReader(new FileReader(fileIn));
            String tempString = null;

            while ((tempString = reader.readLine()) != null) {
                if (tempString.indexOf(keyword) > -1) {
                    String tableName = tempString.substring(tempString.indexOf(keyword)+14);
                    tableName = tableName.substring(0, tableName.indexOf('`'));
                    System.out.println(tableName);
                    tableList = tableList + tableName + " ";
                }
            }
            reader.close();
            return tableList;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }

 


https://www.xamrdz.com/database/6z21925010.html

相关文章: