什么是ETL?ETL是做什么的?

ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数据从来源端经过抽取(extract)、交互转换(transform)、加载(load)至目的端的过程。ETL是将业务系统的数据经过抽取、清洗转换之后加载到数据仓库的过程,因而也称为数据仓库技术。其目的是将分散、零乱、标准不统一的数据整合到一起,为企业的决策提供分析依据。

可以看出,ETL要做三部分工作,数据抽取、数据的清洗转换和数据的加载。数据抽取一般是通过工具从各个不同的数据源抽取到一个中间层中,其中可以做一些数据的清洗和转换,这个过程要注意抽取效率。数据清洗是指将不符合要求的数据除掉,包括错误数据、不完整数据、重复数据。数据转换要做的工作是把所有数据的模板、标准、计算规则等进行统一,如存储结构、数据编码等。清洗转换好的数据按着标准的ETL架构存储到数据仓库中,以备进行数据分析和决策。

实例:

比如我们有一份这样的数据:

相信大家都写过mapreduce的wordcount

在wc中。你进行了每行数据的处理,split(“ ”),等到每个数据,然后进行组合kv然后reduce合并。

但是如果我们拿到的数据不符合进入数据表中的格式呢。

所以我们要进行,数据的数据抽取、数据的清洗转换和数据的加载。

所就拿上面的数据我们做出分析:首先给出数据的数据结构:

可以看出10个字段:

根据这些字段做出表的结构:

create table gulivideo_ori(
    videoId string, 
    uploader string, 
    age int, 
    category array<string>, 
    length int, 
    views int, 
    rate float, 
    ratings int, 
    comments int,
    relatedId array<string>)
row format delimited 
fields terminated by "\t"
collection items terminated by "&"
stored as textfile;

 但对于这些原始数据呢?

肯定是插入失败的。

那么API怎么写呢?在这里我是用java。

共有三个类:【注使用的idea  maven项目】

首先pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.henu</groupId>
    <artifactId>ETL</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>2.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>2.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-yarn-common</artifactId>
            <version>2.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-yarn-client</artifactId>
            <version>2.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-yarn-server-common</artifactId>
            <version>2.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-yarn-server-resourcemanager</artifactId>
            <version>2.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-yarn-server-nodemanager</artifactId>
            <version>2.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-yarn-server-applicationhistoryservice</artifactId>
            <version>2.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-core</artifactId>
            <version>2.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-shuffle</artifactId>
            <version>2.6.0</version>
        </dependency>

    </dependencies>

</project>
ETLUtil
package com.henu;

/**
 * @author George
 * @description
 **/
public class ETLUtil {
    public static String oriString2ETLString(String ori){
        StringBuilder etlString = new StringBuilder();
        String[] splits = ori.split("\t");
        if(splits.length < 9) return null;
        splits[3] = splits[3].replace(" ", "");
        for(int i = 0; i < splits.length; i++){
            if(i < 9){
                if(i == splits.length - 1){
                    etlString.append(splits[i]);
                }else{
                    etlString.append(splits[i] + "\t");
                }
            }else{
                if(i == splits.length - 1){
                    etlString.append(splits[i]);
                }else{
                    etlString.append(splits[i] + "&");
                }
            }
        }
        return etlString.toString();
    }
}
VideoETLMapper
package com.henu;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;

/**
 * @author George
 * @description
 **/
public class VideoETLMapper extends Mapper<Object, Text, NullWritable, Text> {
    Text text = new Text();

    @Override
    protected void map(Object key, Text value, Context context) throws IOException, InterruptedException {
        String etlString = ETLUtil.oriString2ETLString(value.toString());

        if(StringUtils.isBlank(etlString)) return;

        text.set(etlString);
        context.write(NullWritable.get(), text);
    }
}
VideoETLRunner
package com.henu;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

import java.io.IOException;

/**
 * @author George
 * @description
 **/
public class VideoETLRunner implements Tool {
    private Configuration conf = null;

    public void setConf(Configuration conf) {
        this.conf = conf;
    }

    public Configuration getConf() {
        return this.conf;
    }

    public int run(String[] args) throws Exception {
        conf = this.getConf();
        conf.set("inpath", args[0]);
        conf.set("outpath", args[1]);

        Job job = Job.getInstance(conf);

        job.setJarByClass(VideoETLRunner.class);

        job.setMapperClass(VideoETLMapper.class);
        job.setMapOutputKeyClass(NullWritable.class);
        job.setMapOutputValueClass(Text.class);
        job.setNumReduceTasks(0);

        this.initJobInputPath(job);
        this.initJobOutputPath(job);

        return job.waitForCompletion(true) ? 0 : 1;
    }

    private void initJobOutputPath(Job job) throws IOException {
        Configuration conf = job.getConfiguration();
        String outPathString = conf.get("outpath");

        FileSystem fs = FileSystem.get(conf);

        Path outPath = new Path(outPathString);
        if(fs.exists(outPath)){
            fs.delete(outPath, true);
        }

        FileOutputFormat.setOutputPath(job, outPath);

    }

    private void initJobInputPath(Job job) throws IOException {
        Configuration conf = job.getConfiguration();
        String inPathString = conf.get("inpath");

        FileSystem fs = FileSystem.get(conf);

        Path inPath = new Path(inPathString);
        if(fs.exists(inPath)){
            FileInputFormat.addInputPath(job, inPath);
        }else{
            throw new RuntimeException("HDFS中该文件目录不存在:" + inPathString);
        }
    }

    public static void main(String[] args) {
        try {
            int resultCode = ToolRunner.run(new VideoETLRunner(), args);
            if(resultCode == 0){
                System.out.println("Success!");
            }else{
                System.out.println("Fail!");
            }
            System.exit(resultCode);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
}

下一步就是对项目进行打包,然后放在linux上运行了。

将原始的数据上传到hdfs上,然后运行jar包对数据进行处理。

执行命令:

[root@henu2 ~]# hadoop jar ETL-1.0-SNAPSHOT.jar com.henu.VideoETLRunner /guiliVideo/video/2008/0222 /guiliVideo/output/video/2008/022
2

运行:

 

具体操作类似:https://blog.csdn.net/qq_41946557/article/details/102785927

清洗后的数据展示:

ok!!!数据清洗好的,下一步就是导入数据,分析数据了》》》

且听下回分解!!!

 

  • 28
    点赞
  • 149
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
⼤数据什么是 ⼤数据什么是ETL ETL 概念 概念 ETL 这个术语来源于数据仓库,ETL 指的是将业务系统的数据经过抽取、清洗转换之后加载到数据仓库的过程。ETL 的⽬的是将企业中的 分散、零乱、标准不统⼀的数据整合到⼀起,为企业的决策提供分析依据。 ETL是 BI 项⽬重要的⼀个环节。 通常情况下,在 BI 项⽬中 ETL 会花掉整个项⽬⾄少 1/3 的时间,ETL 设计的好坏直接关接到 BI 项⽬的成 败。 BI 即商务智能,它是⼀套完整的解决⽅案,⽤来将企业中现有的数据进⾏有效的整合,快速准确地提供报表并提出决策依据,帮助企业 出明智的业务经营决策。 ETL 的设计分三部分:数据抽取(extract)、数据的清洗转换(transform)、数据的加载(load)。 在设计 ETL 的时候我们也是从这三部分出发。 数据的抽取是从各个不同的数据源抽取到 ODS(Operational Data Store,操作型数据存储,即⼀种常被⽤作数据仓库临时区域的数据库) 中,这个过程也可以⼀些简单的数据的清洗和转换。在抽取的过程中需要挑选不同的抽取⽅法,尽可能的提⾼ ETL 的运⾏效率。 ETL 三个部分中,花费时间最长的是 "T"(Transform,清洗、转换) 的部分,⼀般情况下这部分⼯作量是整个 ETL 的2/3。 数据的加载⼀般在数据清洗完了之后直接写⼊ DW(Data Warehousing,数据仓库) 中去。 ETL 的实现有多种⽅法,常⽤的有三种。 借助 ETL ⼯具(如 Oracle的 OWB、SQL Server 2000 的 DTS、SQL Server2005 的 SSIS 服务、Informatic 等) 实现 使⽤ SQL ⽅式实现 ETL ⼯具和 SQL 相结合 前两种⽅法各有各的优缺点,借助⼯具可以快速的建⽴起 ETL ⼯程,屏蔽了复杂的编码任务,提⾼了速度,降低了难度,但是缺少灵活 性。SQL 的⽅法优点是灵活,提⾼ ETL 运⾏效率,但是编码复杂,对技术要求⽐较⾼。第三种是综合了前⾯⼆种的优点,会极⼤地提⾼ ETL 的开发速度和效率。 数据的抽取( 数据的抽取(Extract) ) 这⼀部分需要在调研阶段⼤量的⼯作,⾸先要搞清楚数据是从⼏个业务系统中来,各个业务系统的数据库服务器运⾏什么 DBMS,是否存在 ⼿⼯数据,⼿⼯数据量有多⼤,是否存在⾮结构化的数据等等,当收集完这些信息之后才可以进⾏数据抽取的设计。 1、对于与存放 、对于与存放 DW 的数据库系统相同的数据源处理⽅法 的数据库系统相同的数据源处理⽅法 这⼀类数据源在设计上⽐较容易。⼀般情况下,DBMS(SQLServer、Oracle)都会提供数据库链接功能,在 DW 数据库服务器和原业务系统 之间建⽴直接的链接关系就可以写 Select 语句直接访问。 2、对于与 、对于与 DW 数据库系统不同的数据源的处理⽅法 数据库系统不同的数据源的处理⽅法 对于这⼀类数据源,⼀般情况下也可以通过 ODBC 的⽅式建⽴数据库链接——如 SQL Server 和 Oracle 之间。如果不能建⽴数据库链接, 可以有两种⽅式完成,⼀种是通过⼯具将源数据导出成 .txt 或者是 .xls ⽂件,然后再将这些源系统⽂件导⼊到 ODS 中。另外⼀种⽅法是通 过程序接⼝来完成。 3、对于⽂件类型数据源 、对于⽂件类型数据源(.txt,.xls),可以培训业务⼈员利⽤数据库⼯具将这些数据导⼊到指定的数据库,然后从指定的数据库中抽取。或者还可以借助⼯具实 ,可以培训业务⼈员利⽤数据库⼯具将这些数据导⼊到指定的数据库,然后从指定的数据库中抽取。或者还可以借助⼯具实 现。 现。 4、增量更新的问题 、增量更新的问题 对于数据量⼤的系统,必须考虑增量抽取。⼀般情况下,业务系统会记录业务发⽣的时间,我们可以⽤来增量的标志,每次抽取之前⾸先判 断 ODS 中记录最⼤的时间,然后根据这个时间去业务系统取⼤于这个时间所有的记录。利⽤业务系统的时间戳,⼀般情况下,业务系统没 有或者部分有时间戳。 数据的清洗转换( 数据的清洗转换(Cleaning、 、Transform) ) ⼀般情况下,数据仓库分为 ODS、DW 两部分。通常的法是从业务系统到 ODS 清洗,将脏数据和不完整数据过滤掉,在从 ODS 到 DW 的过程中转换,进⾏⼀些业务规则的计算和聚合。 1、 、 数据清洗 数据清洗 数据清洗的任务是过滤那些不符合要求的数据,将过滤的结果交给业务主管部门,确认是否过滤掉还是由业务单位修正之后再进⾏抽取。 不符合要求的数据主要是有不完整的数据、错误的数据、重复的数据三⼤类。 不完整的数据:这⼀类数据主要是⼀些应该有的信息缺失,如供应商的名称、分公司的名称、客户的

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值