一、介绍
Apache Hadoop 是一种开源框架,用于高效存储和处理从 GB 级到 PB 级的大型数据集。利用 Hadoop,您可以将多台计算机组成集群以便更快地并行分析海量数据集,而不是使用一台大型计算机来存储和处理数据。
二、核心组件
包含三个核心组件:HDFS,YARN,MapReduce
HDFS:一个在标准或低端硬件上运行的分布式文件系统。
YARN:资源调度系统
-
ResourceManager
-
资源管理者,它负责整个集群的资源管理和分配。
-
-
NodeManager
-
它运行在集群中的每个节点上,负责管理单个节点的资源和任务的运行。NodeManager的主要职责包括:
-
管理容器
-
监控应用
-
节点健康监测
-
-
MapReduce:分布式运算框架
三、MapReduce
MapReduce是一种编程模型,该模型可以将大型数据处理任务分解成很多单个的、可以在服务器集群中并行执行的任务,而这些任务的计算结果可以合并在一起来计算最终的结果。它由Google提出,后来由Apache Hadoop项目实现。
MapReduce的核心原理可以概括为两个步骤:Map(映射)和Reduce。
-
Map阶段:在这一阶段,输入数据被分割成多个小块,然后分配给集群中的不同节点进行处理。每个Map任务接收输入数据,然后使用用户提供的Map函数将数据转换成中间键值对(key-value pairs)。一个输入记录可能会转换成多个中间结果,即"1进N出"。
-
Reduce阶段:Map阶段产生的中间结果被Shuffle过程重新分配,使得具有相同键(key)的值(value)聚集在一起。然后,每个Reduce任务使用用户提供的Reduce函数对这些聚集的值进行处理,以生成最终的输出结果。
MapReduce框架还包括了Shuffle和Sort过程,Shuffle负责将Map输出的数据分发给Reduce任务,Sort则确保了数据在分发前是有序的1。
MapReduce的使用情况在当前依然存在,尽管随着Spark等其他大数据处理框架的兴起,MapReduce可能不再是唯一的选择。但是,MapReduce在处理大规模数据集方面依然有其优势,特别是在需要高吞吐量和容错性的场景中7。
依赖于MapReduce的服务功能包括但不限于:
- 搜索引擎的网页索引:例如,爬虫抓取网页后,使用MapReduce生成倒排索引8。
- 用户行为分析:分析用户在网站上的行为数据,使用MapReduce进行数据聚合和统计8。
- 广告效果评估:通过MapReduce处理广告数据,计算点击率和投资回报率8。
- 社交网络分析:使用MapReduce来分析用户关系和社交网络影响力8。
- 新闻热点检测:分析新闻内容,使用MapReduce找出热门话题8。
- 图像处理:在大规模图像分类或标签生成中使用MapReduce进行数据处理8。
- 金融领域:信用评分模型训练中使用MapReduce处理个人信用记录8。
- 基因组学研究:在基因序列比对和变异检测中使用MapReduce8。
这些应用场景展示了MapReduce在大数据处理中的多样性和实用性。尽管有新的技术出现,MapReduce依然是大数据处理领域的一个重要工具。
四、MapReduce开发案例
作为Java开发人员,使用Hadoop集群进行大数据处理通常涉及编写MapReduce程序。MapReduce是一个编程模型,用于处理和生成大数据集。下面是一个真实的MapReduce案例,模拟了一个常见的日志分析场景:统计网站的访问量。
需求场景
假设你有一个大型的网站,每天会产生大量的访问日志。你需要统计每个页面的访问次数,以便进行性能分析和优化。
数据格式
日志文件的每一行包含以下信息:
格式:
timestamp, user_id, page_url
例如:
2023-01-01 10:00:00, user123, /home
2023-01-01 10:01:00, user456, /about
2023-01-01 10:02:00, user789, /home
MapReduce程序
1. Map阶段
Map阶段读取日志文件的每一行,提取 page_url
作为键,输出 (page_url, 1)
的键值对。
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
public class LogMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
private static final IntWritable one = new IntWritable(1);
private Text pageUrl = new Text();
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
String[] parts = line.split(", ");
if (parts.length == 3) {
pageUrl.set(parts[2]);
context.write(pageUrl, one);
}
}
}
2. Reduce阶段
Reduce阶段接收Map阶段的输出,对每个 page_url
的访问次数进行累加。
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public class LogReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable value : values) {
sum += value.get();
}
context.write(key, new IntWritable(sum));
}
}
3. 驱动程序
驱动程序配置和启动MapReduce作业。
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;
public class LogAnalyzer {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "Log Analyzer");
job.setJarByClass(LogAnalyzer.class);
job.setMapperClass(LogMapper.class);
job.setCombinerClass(LogReducer.class);
job.setReducerClass(LogReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
运行MapReduce作业
-
将日志文件上传到Hadoop集群的HDFS(Hadoop Distributed File System)。
-
编译和打包MapReduce程序为JAR文件。
-
使用Hadoop命令运行JAR文件:
hadoop jar LogAnalyzer.jar LogAnalyzer /input/logs /output/results