2023-02-16
数据 hive 开发
我们需要知道,所谓的“大数据”,指的是非常庞大的数据集。在一般的中型企业中,数据的规模往往能够轻松的到达PB的规模,更不用提大型的企业了。这些数据中蕴藏着非常丰富的价值,而大数据开发人员需要使用各种工具,对这样的数据集进行高效率的处理,从而挖掘出其中蕴藏的价值,让其发光发热。于是要解决的第一个问题就是数据存储的问题。庞大的数据集,造成了在一台机器上存储不下的问题,此时就需要使用分布式的数据存储方式,而HDFS就是来解决这样的问题而存在的。
存储的问题解决了,下面就是对这些数据进行计算、处理的问题了。我们需要对分布式文件系统上的数据文件进行计算,势必会涉及到分布式计算的思想。但是如果在我们处理每一个需求的时候,都去从0开始开发一个分布式计算程序,会有很多的弊端。首先,对于开发人员来说,就是一个极大的学习成本,需要去了解到分布式计算的底层是如何实现的。其次,几乎所有的分布式计算程序中,涉及到分布式计算的部分可以是共用的。因此只需要将这部分单独的抽离出来即可,没必要每一次做分布式计算程序的时候,都去关注底层的实现细节。于是就出现了MapReduce,解决了分布式计算的问题。
MapReduce的出现,确实在一定程度上简化了开发人员的压力,使得开发人员只需要将自己的工作重心放在业务逻辑的实现上面即可,不需要考虑到分布式计算的底层细节是如何实现的。但是,MapReduce的程序其实还是非常的麻烦的。想要去开发一个完整的MapReduce的程序,你必须设计至少3个类: Mapper、Reduer、Driver,而如果还需要处理更加复杂的数据的时候,可能还得设计分区器、自定义数据类型、Combiner、自定义分组等等类型,使得一个MR的程序非常的复杂。这还只是一个Job。如果你的业务逻辑比较复杂,此时可能还需要有多个Job串联,又大大的增加了开发的难度。于是,在此基础上,Hive诞生了!
Apache Hive是Apache旗下的顶级项目,是在大数据开发中非常非常热门的组件,也是大数据开发必需要使用到的技术组件之一。什么是Hive呢?Hive是一个构建在Hadoop上的数据仓库工具(框架),可以将结构化的数据文件映射成一张数据表,并可以使用类SQL的方式对这样的数据文件进行读、写以及管理的操作。有很多人在提到Hive的时候,都会把Hive称为是一个数据库。但是Hive只是一个数据计算的工具,并不是一个数据库!
而为什么一定要使用到Hive呢?其实使用Hive可以极大的简化开发人员的开发成本,缩短项目周期。我们以一个案例为例,来对比一下MapReduce和Hive来处理同样的需求的时候,有什么区别?
案例:
一个文件中记录着手机流量的信息,记录着手机号码、MAC地址、访问网址、上行流量、下行流量等信息。需要从这个文件中查询出来每一个手机号码的总上行、总下行、总流量信息。
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
/**
* @author 千锋大数据教研院 - 章鱼哥
* @company 北京千锋互联科技有限公司
*/
public class PhoneFlowReducer extends Reducer<text, text="" text,="" phoneflowbean,=""> {
@Override
protected void reduce(Text key, Iterablevalues, Context context) throws IOException, InterruptedException {
// 定义一个变量,用来统计总流量
int total = 0;
int total_up = 0;
int total_down = 0;
// 遍历每一个手机号码对应的一条流量信息
for (PhoneFlowBean value : values) {
total += value.getTotalFlow();
total_up += value.getUpFlow();
total_down += value.getDownFlow();
}
String res = String.format("%d\t%d\t%d", total_up, total_down, total);
context.write(key, new Text(res));
}
}
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
/**
* @author 千锋大数据教研院 - 章鱼哥
* @company 北京千锋互联科技有限公司
*/
public class PhoneFlowMapper extends Mapper<longwritable, text,="" phoneflowbean=""> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String[] props = value.toString().split("\t");
// 拆出手机号码
String phoneNumber = props[1];
// 拆出上行流量
int upFlow = Integer.parseInt(props[8]);
// 拆出下行流量
int downFlow = Integer.parseInt(props[9]);
PhoneFlowBean bean = new PhoneFlowBean(phoneNumber, upFlow, downFlow);
context.write(new Text(phoneNumber), bean);
}
}
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
/**
* @author 千锋大数据教研院 - 章鱼哥
* @company 北京千锋互联科技有限公司
*/
public class PhoneFlowReducer extends Reducer<text, text="" text,="" phoneflowbean,=""> {
@Override
protected void reduce(Text key, Iterablevalues, Context context) throws IOException, InterruptedException {
// 定义一个变量,用来统计总流量
int total = 0;
int total_up = 0;
int total_down = 0;
// 遍历每一个手机号码对应的一条流量信息
for (PhoneFlowBean value : values) {
total += value.getTotalFlow();
total_up += value.getUpFlow();
total_down += value.getDownFlow();
}
String res = String.format("%d\t%d\t%d", total_up, total_down, total);
context.write(key, new Text(res));
}
}
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
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 java.io.IOException;
/**
* @author 千锋大数据教研院 - 章鱼哥
* @company 北京千锋互联科技有限公司
*/
public class PhoneFlowDriver {
public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
Configuration configuration = new Configuration();
configuration.set("mapreduce.framework.name", "local");
Job job = Job.getInstance(configuration);
job.setMapperClass(PhoneFlowMapper.class);
job.setReducerClass(PhoneFlowReducer.class);
job.setJarByClass(PhoneFlowDriver.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(PhoneFlowBean.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
FileInputFormat.setInputPaths(job, new Path("file/HTTP_20130313143750.dat"));
FileOutputFormat.setOutputPath(job, new Path("file/out2"));
System.exit(job.waitForCompletion(true) ? 0 : -1);
}
}
看到了吧,用MapReduce实现上述需求的时候,需要设计至少3个类:Mapper、Reducer、Driver,有些复杂的需求还需要自定义序列化类型,例如上述的PhoneFlowBean类。那么使用Hive如何解决这个需求呢?
# 建表
CREATE TABLE flow(
id string COMMENT 'this is id column',
phonenumber string,
mac string,
ip string,
url string,
urltype string,
uppacket int,
downpacket int,
upflow int,
downflow int,
issuccess int
)
COMMENT 'this is log table'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
LINES TERMINATED BY '\n'
stored as textfile;
# 查询结果
select
phonenumber,
sum(upflow) total_up,
sum(downflow) total_down,
sum(upflow+downflow) total
from
flow
group by
phonenumber;
看到了吧,使用Hive来做同样的需求,就是这么简单!对HDFS上的结构化的数据文件进行表的映射,然后一条SQL就可以实现同样的需求了!
因此,当我们需要处理到非常复杂的需求的时候,使用Hive来进行数据的处理将会变得非常的简单,可以极大的减少开发人员的开发压力,缩短开发人员的开发周期!
上一篇:前端的职业规划
下一篇:企业为什么会使用大数据?
开班时间:2021-04-12(深圳)
开班盛况开班时间:2021-05-17(北京)
开班盛况开班时间:2021-03-22(杭州)
开班盛况开班时间:2021-04-26(北京)
开班盛况开班时间:2021-05-10(北京)
开班盛况开班时间:2021-02-22(北京)
开班盛况开班时间:2021-07-12(北京)
预约报名开班时间:2020-09-21(上海)
开班盛况开班时间:2021-07-12(北京)
预约报名开班时间:2019-07-22(北京)
开班盛况Copyright 2011-2023 北京千锋互联科技有限公司 .All Right 京ICP备12003911号-5 京公网安备 11010802035720号