Java 使用map-reduce进行行计数

Java 使用map-reduce进行行计数,java,hadoop,mapreduce,Java,Hadoop,Mapreduce,我每天从别人那里下载几千个文件到一个目录,每个文件大约有400MB到1GB大小 我想计算目录中的行总数 我计划像下面这样做map reduce 制图员 public static class LineMapper extends Mapper<Object, Text, Text, IntWritable>{ private final static IntWritable one = new IntWritable(1); public void

我每天从别人那里下载几千个文件到一个目录,每个文件大约有400MB到1GB大小

我想计算目录中的行总数

我计划像下面这样做map reduce

制图员

public static class LineMapper
        extends Mapper<Object, Text, Text, IntWritable>{

    private final static IntWritable one = new IntWritable(1);

    public void map(Object key, Text value, Context context
    ) throws IOException, InterruptedException {

        context.write("static_key", one);
    }
}
公共静态类线条映射器
扩展映射器{
私有最终静态IntWritable one=新的IntWritable(1);
公共无效映射(对象键、文本值、上下文
)抛出IOException、InterruptedException{
编写(“静态_键”,一个);
}
}
减速器

public static class IntSumReducer
        extends Reducer<Text,IntWritable,Text,IntWritable> {
    private IntWritable result = new IntWritable();

    public void reduce(Text key, Iterable<IntWritable> values,
                       Context context
    ) throws IOException, InterruptedException {
        int sum = 0;
        for (IntWritable val : values) {
            sum += val.get();
        }
        result.set(sum);
        context.write(key, result);
    }
}
公共静态类IntSumReducer
伸缩减速机{
私有IntWritable结果=新的IntWritable();
public void reduce(文本键、Iterable值、,
语境
)抛出IOException、InterruptedException{
整数和=0;
for(可写入值:值){
sum+=val.get();
}
结果集(总和);
编写(键、结果);
}
}
但是仔细考虑之后,我觉得reducer节点会被淹没,因为只有一个键


有没有办法避免这种情况?

如果您想使用mapreduce进行此操作,那么最好的选择是使用计数器。将映射器更改为类似这样的值,并将还原数设置为0

public static class LineMapper extends Mapper<Object, Text, Text, IntWritable>{

        enum MyCounters {
            TOTAL_COUNT;
        }


        public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
                 context.getCounter(MyCounters.TOTAL_COUNT).increment(1L);
        }
}
公共静态类LineMapper扩展Mapper{
枚举数{
总数;
}
公共void映射(对象键、文本值、上下文上下文)引发IOException、InterruptedException{
getCounter(MyCounters.TOTAL_COUNT).增量(1L);
}
}

通过
Hive
这样做可能会更快。概述以下一种可能的方法:

创建HDFS目录以保存数据

$ hadoop fs -mkdir /hive-data
$ hadoop fs -mkdir /hive-data/linecount
创建配置单元表

hive> CREATE EXTERNAL TABLE linecount
(
  line string
)
LOCATION
  'hdfs:///hive-data/linecount'
在HDFS中加载数据文件

$ hadoop fs -put a.txt hdfs:///hive-data/linecount
$ hadoop fs -put b.txt hdfs:///hive-data/linecount
$ hadoop fs -put c.txt hdfs:///hive-data/linecount
通过配置单元查询计数

hive> select count(*) from linecount;

为什么要使用mapreduce进行此操作?你有Pig或Spark吗?对于字数计算,你只需在HDFS上做一个类似这样的cat即可,HDFS dfs-cat/path/somefile.csv | wc-l将给出#行我更喜欢这个选项,因为它不涉及编写、编译和部署MapReduce作业。你能解释一下,如何在reduce函数中获取这个计数器的值吗?如果我试图通过
context.getCounter(MyCounters.TOTAL_COUNT).getValue()获取它,它给我0。基本上,如何将此计数器的值从
map
转移到
reduce