这段代码从包声明和导入语句来看,是与Hadoop相关的Java代码。

package com.lzpu.mr;声明了该代码所属的包为com.lzpu.mr ,用于组织和管理代码。

接下来一系列import语句导入了Hadoop相关的类,这些类用于操作Hadoop的配置、文件系统、数据类型以及MapReduce作业相关的功能。例如:

  • org.apache.hadoop.conf.Configuration:用于Hadoop的配置管理,比如设置作业的各种参数等。
  • org.apache.hadoop.fs.Path:用于表示Hadoop文件系统中的路径,比如指定输入输出文件的路径。
  • org.apache.hadoop.io.IntWritableorg.apache.hadoop.io.LongWritableorg.apache.hadoop.io.Text等:是Hadoop中用于序列化和反序列化的基本数据类型,用于在MapReduce作业中传递数据。
  • org.apache.hadoop.mapreduce.Job:用于定义和配置一个MapReduce作业。
  • org.apache.hadoop.mapreduce.Mapperorg.apache.hadoop.mapreduce.Reducer:分别是MapReduce作业中Mapper和Reducer的抽象类,用户需要继承它们来实现自己的Map和Reduce逻辑。
  • org.apache.hadoop.mapreduce.Partitioner:用于在MapReduce中对数据进行分区。
  • org.apache.hadoop.mapreduce.lib.input.FileInputFormatorg.apache.hadoop.mapreduce.lib.output.FileOutputFormat:用于指定MapReduce作业的输入输出格式和路径。

import java.io.IOException;导入了Java标准库中的IOException类,用于处理可能出现的I/O异常,因为在操作文件系统等I/O相关操作时可能会抛出此类异常。

整体来看,这段代码是为编写一个基于Hadoop MapReduce框架的程序做准备,后续应该会有继承Mapper和Reducer等类来实现具体的MapReduce逻辑的代码。

创建配置对象‌:Configuration conf = new Configuration();创建了一个Hadoop的配置对象conf,用于存储作业的各种配置信息。
设置配置属性‌:conf.set("fs.defaultFS", "hdfs://hadoop01-831");设置了Hadoop文件系统的默认地址,这里指定为hdfs://hadoop01-831。
获取作业对象‌:Job job = Job.getInstance(conf, "luo sort");通过配置对象conf获取一个Job对象,并给作业命名为luo sort。
设置作业相关类和属性‌:
job.setJarByClass(LsFen.class);设置了包含Mapper和Reducer等类的JAR包,这里是当前类LsFen所在的JAR包。
job.setMapperClass(LsFen.LsFenMapper.class);设置了Mapper类为LsFen.LsFenMapper。
job.setReducerClass(LsFen.LsFenReducer.class);设置了Reducer类为LsFen.LsFenReducer。
job.setMapOutputKeyClass(IntWritable.class);和job.setMapOutputValueClass(Text.class);设置了Mapper输出的键和值的数据类型分别为IntWritable和Text。
job.setOutputKeyClass(IntWritable.class);和job.setOutputValueClass(Text.class);设置了Reducer输出的键和值的数据类型分别为IntWritable和Text。
设置分区相关‌:
job.setNumReduceTasks(12);设置了Reducer的数量为12个。
job.setPartitionerClass(MyPartitioner.class);设置了分区类为MyPartitioner,用于对Mapper输出的数据进行分区。
设置输入输出路径‌:
FileInputFormat.addInputPath(job, new Path(args[0]));设置了作业的输入路径,从命令行参数args[0]获取。
FileOutputFormat.setOutputPath(job, new Path(args[1]));设置了作业的输出路径,从命令行参数args[1]获取,并且要求该路径在作业运行前不存在。

这段Java代码的作用是配置和设置一个基于Hadoop MapReduce框架的作业,包括设置作业的配置信息、Mapper和Reducer类、数据类型、分区信息以及输入输出路径等,并提交作业等待其执行完成,目的是实现一个特定的分布式数据处理任务(如排序等,从作业名称"luo sort"推测)

  1. 类定义‌:public static class MyPartitioner extends Partitioner<IntWritable, Text>定义了一个静态内部类MyPartitioner,它继承自Partitioner,泛型参数为IntWritableText,表示处理的数据类型为IntWritable类型的键和Text类型的值。
  2. 重写方法‌:@Override public int getPartition(IntWritable intWritable, Text text, int i)重写了Partitioner类中的getPartition方法。该方法接收三个参数:IntWritable类型的键intWritableText类型的值text,以及设置的总分区数i
  3. 分区逻辑‌:
    • 代码注释部分原本有一个假设,即map输出的key997value"2019-04-29,997",并尝试从value中提取月份,将其转换为数字后减1作为分区索引返回。
    • 实际执行的逻辑是从text(即map输出的值)中,按照空格进行分割,取分割后的第二个元素(索引为1),将其转换为整数后减1,并将结果作为分区索引返回。这个逻辑的目的是根据map输出值的特定格式(包含一个可以转换为整数的部分)来确定数据应该被分配到哪个分区。
    • 这段代码定义了一个在Hadoop MapReduce框架中用于数据分区的类MyPartitioner,通过重写getPartition方法,根据map输出值的特定格式,从值中提取部分信息转换为整数并减1,以此来确定数据应分配到的分区索引,实现对map输出数据的分区功能。

LsFenMapper类‌:
继承自Mapper<LongWritable, Text, IntWritable, Text>,重写了map方法。
map方法接收输入的键(类型为LongWritable,通常是文件中一行的偏移量)和值(类型为Text,通常是文件中的一行内容),以及上下文对象context。
具体操作是先将输入的Text类型的值转换为字符串,然后按照空格进行分割,获取分割后的第二个元素并将其转换为整数,作为销量sale 。
最后通过context.write方法将销量(封装为IntWritable类型)作为键,原始输入字符串(Text类型)作为值输出到MapReduce的下一个阶段。
LsFenReducer类‌:
继承自Reducer<IntWritable, Text, IntWritable, Text>,重写了reduce方法。
reduce方法接收一个键(类型为IntWritable,即Mapper输出的键,这里是销量),以及一个包含所有对应值(类型为Text,即Mapper输出的原始字符串)的可迭代对象values,还有上下文对象context。
在reduce方法中,它遍历values,并将每个值通过context.write方法输出,这里输出的键设置为null,将原始字符串作为值输出。

LsFenMapper类的作用是对输入数据进行处理,从每行数据中提取销量信息并将其作为键,原始数据作为值输出到下一个MapReduce阶段;LsFenReducer类的作用是接收Mapper输出的数据,遍历相同键对应的值集合,将每个值在键为null的情况下输出。

学习Hadoop是一段充满挑战与收获的旅程,从分布式系统的理论基础到实际集群的搭建运维,每一步都让我对大数据处理有了更深刻的理解。

最初接触Hadoop时,分布式文件系统HDFS的块存储、副本机制和NameNode的核心作用让我颠覆了传统单机存储的认知。通过实操HDFS Shell命令和Java API,我逐渐掌握了文件的上传下载、权限管理等操作,也明白了副本放置策略对数据可靠性和读写性能的重要性。MapReduce编程模型则是另一个难点,从理解“分而治之”的思想,到编写Mapper和Reducer处理海量数据,再到通过Combiner、Partitioner优化作业流程,每一次调试运行都让我对数据流转逻辑有了更清晰的认识。

YARN的资源调度机制让我看到了Hadoop生态的扩展性,ResourceManager、NodeManager、ApplicationMaster等组件的协同工作,让集群资源分配更加灵活高效。在搭建伪分布式和完全分布式环境的过程中,我踩过不少坑,比如SSH免密配置、防火墙问题、配置文件参数错误等,这些经历反而让我对Hadoop各组件的依赖关系和运行原理有了更直观的感受。

随着学习深入,我开始接触Hive、HBase等生态工具,发现它们能极大降低大数据处理的门槛。Hive的类SQL查询让非编程人员也能分析数据,HBase的列存储特性则适合处理非结构化和半结构化数据。但同时也意识到,工具的便捷性背后是对底层原理的深度封装,只有打好Hadoop基础,才能更好地理解和使用这些工具。

学习Hadoop不仅提升了我的技术能力,更培养了我的分布式思维。面对海量数据,如何设计高效的计算模型、如何保证数据一致性和系统容错性,这些问题都需要从全局角度思考。未来,我还会继续深入学习Spark等计算框架,探索Hadoop在更多场景的应用,让技术真正服务于业务需求。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐