sqoop1.99.7安装、使用及部分问题

一、安装环境

已具备java和hadoop的环境,本文的版本为ubuntu16.04、java1.8.0、hadoop2.7.5。
安装选择sqoop1.99.7,注意sqoop2中的sqoop1.99.6和1.99.7安装区别较大。附官网5分钟教程:sqoop1.99.7官网教程

二、sqoop2下载安装

1.直接在sqoop的官网下载
选择sqoop1.99.7版本。我直接下的bin版本,这个版本已经编译好了,直接用。sqoop1.99.7官网下载地址链接。选择其中的 sqoop-1.99.7-bin-hadoop200.tar.gz进行下载。
在这里插入图片描述
2.解压安装包

tar -xzvf sqoop-1.99.7-bin-hadoop200.tar.gz

mv sqoop-1.99.7-bin-hadoop200 sqoop1.99.7 sqoop1.99.7

3.添加环境变量
无论添加到/etc/profile还是在/etc/profile.d中创建一个脚本导入变量,亦或是在~/.bashrc文件中写,都可以。本文选择在~/.bashrc中添加

sudo vim ~/.bashrc

在已有的java、hadoop等环境变量基础上增加sqoop的几个变量
在这里插入图片描述
注意其中的SQOOP_SERVER_EXTER_LIB下的lib目录是本例中新建的,用户数据库驱动包,需要下载mysql的驱动jar文件复制到这个目录下。本例中下载的版本是mysql-connector-java-5.1.44-bin.jar。

source ~/.bashrc

4.修改配置文件
修改sqoop.properties中的hadoop配置文件路径

vim ./sqoop1.99.7/conf/sqoop.properties

在这里插入图片描述同时需要去掉安全验证方式部分的注释
在这里插入图片描述5.配置hadoop代理访问
因为sqoop访问Hadoop的MapReduce使用的是代理的方式,必须在Hadoop中配置所接受的proxy用户和组。找到Hadoop的core-site.xml配置文件:

vim $HADOOP_HOME/etc/hadoop/core-site.xml

添加如下内容,其中spark是我使用的系统用户名字,需要大家根据自身情况修改。
在这里插入图片描述
6.配置完成进行验证

cd $SQOOP-HOME
./bin/sqoop2-tool verify

在这里插入图片描述7.开启server

./bin/sqoop2-server start

通过jps命令可以看到SqoopJettyServer代表sqoop服务启动成功。
关闭命令为

./bin/sqoop2-server stop

三、sqoop1.99.7应用实践

使用sqoop2实现mysql与hdfs之间的相互转换。
1.准备mysql实验数据
在这里插入图片描述数据库名字为dbtest1,表名字为test1,表内有三条记录。
2.准备hdfs实验数据

$ vim test01.csv
 4,'kechuwen',22
 5,'liuzhangmin',22
$ hadoop fs -mkdir /hdfstest
$ hadoop fs -put test01.csv /hdfstest

3.为了能查看sqoop2 status,编辑hadoop的 mapred-site.xml

vim $HADOOP_HOME/etc/hadoop/mapred-site.xml

添加如下内容

<property>
  <name>mapreduce.jobhistory.address</name>
  <value>localhost:10020</value>
</property>

启动hadoop的historyserver及hadoop其他服务

cd  $HADOOP_HOME
sbin/mr-jobhistory-daemon.sh start historyserver
sbin/start-all.sh

4.进入sqoop

cd #SQOOP_HOME
./bin/sqoop2-server start
./bin/sqoop2-shell  或者./bin/sqoop.sh client

列举所有连接

sqoop:000> show connector
+------------------------+---------+------------------------------------------------------------+----------------------+
|          Name          | Version |                           Class                            | Supported Directions |
+------------------------+---------+------------------------------------------------------------+----------------------+
| generic-jdbc-connector | 1.99.7  | org.apache.sqoop.connector.jdbc.GenericJdbcConnector       | FROM/TO              |
| kite-connector         | 1.99.7  | org.apache.sqoop.connector.kite.KiteConnector              | FROM/TO              |
| oracle-jdbc-connector  | 1.99.7  | org.apache.sqoop.connector.jdbc.oracle.OracleJdbcConnector | FROM/TO              |
| ftp-connector          | 1.99.7  | org.apache.sqoop.connector.ftp.FtpConnector                | TO                   |
| hdfs-connector         | 1.99.7  | org.apache.sqoop.connector.hdfs.HdfsConnector              | FROM/TO              |
| kafka-connector        | 1.99.7  | org.apache.sqoop.connector.kafka.KafkaConnector            | TO                   |
| sftp-connector         | 1.99.7  | org.apache.sqoop.connector.sftp.SftpConnector              | TO                   |
+------------------------+---------+------------------------------------------------------------+----------------------+

建立hdfs的连接

sqoop:000> create link --connector hdfs-connector
Creating link for connector with name hdfs-connector
Please fill following values to create new link object
Name: hdfs-link01  (#连接名字,必填)

HDFS cluster

URI: hdfs://master:9000   (#hdfs的地址,必填)
Conf directory: /home/spark/app/hadoop/etc/hadoop   (#hadoop的配置地址,必填)
Additional configs::
There are currently 0 values in the map:
entry#
New link was successfully created with validation status OK and name hdfs-link01

建立mysql的连接

sqoop:000> create link --connector generic-jdbc-connector
Creating link for connector with name generic-jdbc-connector
Please fill following values to create new link object
Name: jdbc-link01   (#link名称,必填)

Database connection

Driver class: com.mysql.jdbc.Driver    (#jdbc驱动类,必填)
Connection String: jdbc:mysql://localhost:3306/dbtest1?userUnicode=true&characterEncoding=UTF8& useSSL=false    (# jdbc链接url,必填)
Username: root   (#数据库的用户,必填)
Password: ****      (#数据库密码,必填)
Fetch Size:
Connection Properties:
There are currently 0 values in the map:
entry#

SQL Dialect

Identifier enclose:   (#这里有一个空格,不然会报错)
New link was successfully created with validation status OK and name jdbc-link01

查看已经建好的link

sqoop:000> show link
+-------------+------------------------+---------+
|    Name     |     Connector Name     | Enabled |
+-------------+------------------------+---------+
| jdbc-link01 | generic-jdbc-connector | true    |
| hdfs-link01 | hdfs-connector         | true    |
+-------------+------------------------+---------+

创建job

sqoop:000>create job -f jdbc-link01 -t hdfs-link01
Creating job for links with from name jdbc-link01 and to name hdfs-link01
Please fill following values to create new job object
Name: jdbctohdfs01   (#job名字,必填)
Database source
Schema name: dbtest1   (#数据库名字,必填)
Table name: test1   (#数据表名字,必填)
SQL statement:  (#就是sql查询语句,可选的,直接回车就好)
Column names:   (# 重写数据相关的一些参数,可选,直接回车就好)
There are currently 0 values in the list:
element#
Partition column:    (#分割的列,也就是将最终文件分割为多个,默认导入到一个文件)
Partition column nullable:
Boundary query:
Incremental read
Check column:
Last value:
Target configuration
Override null value:
Null value:
File format:   (#文件格式,这里选择0,TEXT_FILE)
  0 : TEXT_FILE
  1 : SEQUENCE_FILE
  2 : PARQUET_FILE
Choose: 0
Compression codec:   (#压缩编码器,这里不压缩,选择0)
  0 : NONE
  1 : DEFAULT
  2 : DEFLATE
  3 : GZIP
  4 : BZIP2
  5 : LZO
  6 : LZ4
  7 : SNAPPY
  8 : CUSTOM
Choose: 0
Custom codec:    (#自定义的编码器,这里也不需要,直接回车)
Output directory: /hdfstest1    (#输出hdfs路径,必填切目录下必须为空,可以为没有建的目录)
Append mode:    (#用于指定是否是在已存在导出文件的情况下将新数据追加到数据文件中。可选回车)
Throttling resources
Extractors:   (#可选,对应 mapreduce 的 job 中 map 的数量。这里直接回车)
Loaders:     (#可选,对应 mapreduce 的 job 中的 reduce 的数量。这里直接回车)
Classpath configuration
Extra mapper jars:
There are currently 0 values in the list:
element#    (# Classpath配置,如:需要添加任务额外的jar包,这里直接回车)
Job was successfully updated with status OK

查看并启动job

sqoop:000> show job
+----+--------------+--------------------------------------+------------------------------+---------+
| Id |     Name     |            From Connector            |         To Connector         | Enabled |
+----+--------------+--------------------------------------+------------------------------+---------+
| 1  | jdbctohdfs01 | jdbc-link01 (generic-jdbc-connector) | hdfs-link01 (hdfs-connector) | true    |
+----+--------------+--------------------------------------+------------------------------+---------+
sqoop:000> start job -n jdbctohdfs01

执行结果生成如下文件
在这里插入图片描述

四、通过java api 实现转换

package com.plateform.api.utils;

import org.apache.sqoop.client.SqoopClient;
import org.apache.sqoop.model.*;
import org.apache.sqoop.submission.counter.Counter;
import org.apache.sqoop.submission.counter.CounterGroup;
import org.apache.sqoop.submission.counter.Counters;
import org.apache.sqoop.validation.Status;

import java.util.UUID;

/**
 * @author liuzhangmin
 * @date 2018/9/7 19:08
 */
public class SqoopUtil {

    public static SqoopClient sqoopInit() {
        //初始化
        String url = "http://10.4.20.136:12000/sqoop/";
        SqoopClient client = new SqoopClient(url);
        return client;
    }

    ;

    public static void mysqlToHDFS() {
        //初始化
        SqoopClient client = sqoopInit();
        System.out.println(client);

        //创建一个源链接 JDBC
        MLink fromLink = client.createLink("generic-jdbc-connector");
        fromLink.setName("jdbc-link" + UUID.randomUUID().toString().substring(0, 8));
        fromLink.setCreationUser("liuzhangmin");
        MLinkConfig fromLinkConfig = fromLink.getConnectorLinkConfig();
        fromLinkConfig.getStringInput("linkConfig.connectionString").setValue("jdbc:mysql://10.4.20.151:3306/spring?userUnicode=true&characterEncoding=UTF8&useSSL=false");
        fromLinkConfig.getStringInput("linkConfig.jdbcDriver").setValue("com.mysql.jdbc.Driver");
        fromLinkConfig.getStringInput("linkConfig.username").setValue("root");
        fromLinkConfig.getStringInput("linkConfig.password").setValue("Root@123");
        fromLinkConfig.getStringInput("dialect.identifierEnclose").setValue(" ");
        Status fromStatus = client.saveLink(fromLink);
        if (fromStatus.canProceed()) {
            System.out.println("创建JDBC Link成功,ID为: " + fromLink.getPersistenceId());
        } else {
            System.out.println("创建JDBC Link失败");
        }
        //创建一个目的地链接HDFS
        MLink toLink = client.createLink("hdfs-connector");
        toLink.setName("hdfs-link" + UUID.randomUUID().toString().substring(0, 8));
        toLink.setCreationUser("liuzhangmin");
        MLinkConfig toLinkConfig = toLink.getConnectorLinkConfig();
        toLinkConfig.getStringInput("linkConfig.uri").setValue("hdfs://10.4.20.136:9000");
        Status toStatus = client.saveLink(toLink);
        if (toStatus.canProceed()) {
            System.out.println("创建HDFS Link成功,ID为: " + toLink.getPersistenceId());
        } else {
            System.out.println("创建HDFS Link失败");
        }

        //创建一个任务
        String fromLinkName = fromLink.getName();
        String toLinkName = toLink.getName();
        MJob job = client.createJob(fromLinkName, toLinkName);
        job.setName("mysqltohdfs3");
        job.setCreationUser("liuzhangmin");
        // 设置源链接任务配置信息
        MFromConfig fromJobConfig = job.getFromJobConfig();
        fromJobConfig.getStringInput("fromJobConfig.tableName").setValue("test1");
//        fromJobConfig.getStringInput("fromJobConfig.partitionColumn").setValue("id");
        // 设置目标链接任务配置信息
        MToConfig toJobConfig = job.getToJobConfig();
        toJobConfig.getStringInput("toJobConfig.outputDirectory").setValue("/hdfs4jdbc");
        toJobConfig.getBooleanInput("toJobConfig.appendMode").setValue(true);
//        toJobConfig.getEnumInput("toJobConfig.storageType").setValue("HDFS");
        toJobConfig.getEnumInput("toJobConfig.outputFormat").setValue("TEXT_FILE");
        // Job resources
        MDriverConfig driverConfig = job.getDriverConfig();
        driverConfig.getIntegerInput("throttlingConfig.numExtractors").setValue(3);
//        driverConfig.getIntegerInput("throttlingConfig.loaders").setValue(1);

        Status status = client.saveJob(job);
        if (status.canProceed()) {
            System.out.println("JOB创建成功,ID为: " + job.getPersistenceId());
        } else {
            System.out.println("JOB创建失败。");
        }

        //启动任务
        String jobName = job.getName();
        MSubmission submission = client.startJob(jobName);
        System.out.println(jobName);
        System.out.println("JOB提交状态为 : " + submission.getStatus());
        while (submission.getStatus().isRunning() && submission.getProgress() != -1) {
            System.out.println("进度 : " + String.format("%.2f %%", submission.getProgress() * 100));
            //三秒报告一次进度
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("JOB执行结束... ...");
        System.out.println("Hadoop任务ID为 :" + submission.getExternalJobId());
        Counters counters = submission.getCounters();
        if (counters != null) {
            System.out.println("计数器:");
            for (CounterGroup group : counters) {
                System.out.print("\t");
                System.out.println(group.getName());
                for (Counter counter : group) {
                    System.out.print("\t\t");
                    System.out.print(counter.getName());
                    System.out.print(": ");
                    System.out.println(counter.getValue());
                }
            }
        }
        System.out.println("MySQL通过sqoop传输数据到HDFS统计执行完毕");
    }
}

五、遇到的问题

1.hdfs输出目录必须为空
2.mysql主键必须为int而不能是varchar(解决:mysql的数据类型改成utf-8)
3.输出多个hdfs文件
4.输出文件自动命名

听说sqoop2还在开发,不如sqoop1稳定,所以建议改用sqoop1来开发项目,虽然sqoop1 不提供各类接口但是shell脚本也是很简单方便的。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值