欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

mysql整个数据库迁移至hive:sqoop安装到配置、脚本使用全过程

程序员文章站 2022-07-12 23:51:09
...

最近需要使用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();
                }
            }
        }
    }

 

相关标签: 大数据

上一篇: vnc

下一篇: PS1的IP地址设置 ps1