使用HDFS完成wordcount词频统计
任务需求
统计HDFS上文件的
wordcount
,并将统计结果输出到HDFS
功能拆解
- 读取HDFS文件
- 业务处理(词频统计)
- 缓存处理结果
- 将结果输出到HDFS
数据准备
- 事先往HDFS上传需要进行词频统计的文件
word.txt、word2.txt(可以是多个)...
- 假设目录是
/user/hadoop/input/...
框架搭建
先把具体的功能
框架搭建
出来,再进行细节方面
的编写。
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
public class HDFSWordCountDemo{
public static void main(String[] args) throws Exception{
// 1.读取HDFS文件
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://localhost:9000"), conf, "hadoop");
// 使用Java API取出HDFS指定目录下所有要进行词频统计的单词文件,false表示不需要递归
RemoteIterator<LocatedFileStatus> files = fs.listFiles(new Path("input"), false);
// 用于循环取出多个单词文本
while (files.hasNext()) {
LocatedFileStatus file = files.next();
FSDataInputStream in = fs.open(file.getPath());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = null; // readLine每次读取一行
// 用于循环取出每个文本的每行内容
while ((line = reader.readLine()) != null) {
// 2.业务处理(词频统计)
/**
* 功能:
* 此处要进行单词的词频统计功能
* 输入:
* 每次循环读取的是一个文件,输入的是该文件的一行内容line
* 输出:
* 把每行内容line按指定分割符分割,成为一个个独立单词,进行累加统计,多个文本累计,返回结果数组
*/
}
reader.close();
in.close();
}
// 3.缓存处理结果:把统计结果写入缓存
// TODO...
// 4.将结果输出到HDFS
// 先在HDFS上创建一个空文本
FSDataOutputStream out = fs.create(new Path("output/result.txt"));
// 然后取出缓存中的内容,追加到该HDFS文本即可
// TODO...
}
}
词频统计实现
分为两步:
1)
实现上下文对象,用于保存每次的统计;2)
词频统计功能的封装调用
- 使用Map实现上下文对象
import java.util.HashMap;
import java.util.Map;
/**
* 自定义上下文对象,其实就是模仿缓存
*/
public class HDFSContext {
private Map<Object,Object> cacheMap = new HashMap<>();
// 用于从外部可以直接获取缓存
public Map<Object,Object> getCacheMap(){
return cacheMap;
}
/**
* 写数据到缓存
* @param key
* @param value
*/
public void write(Object key,Object value){
cacheMap.put(key, value);
}
/**
* 从缓存中读取数据
* @param key
* @return
*/
public Object get(Object key){
return cacheMap.get(key);
}
}
- 词频统计逻辑处理
// 自定义一个Mapper接口,封装词频统计功能
public interface HDFSMapper {
/**
* @param line 读取到的每一行数据
* @param context 上下文对象/缓存
*/
public void map(String line,HDFSContext context);
}
// 接口的功能实现
public class WordCountMapper implements HDFSMapper{
@Override
public void map(String line, HDFSContext context) {
String[] words = line.split(" "); // 按空格切割,words是一行内容的单词数组
for (String word : words) { // 遍历数组,取出每一个单词
Object value = context.get(word); // 取出缓存中的单词,
if (value == null){ // 如果value为null,则说明缓存中没有该单词
//不存在这个单词
context.write(word,1); // 第一次出现的单词,次数为1,并写入缓存
}else {
// 出现次数+1
int v = Integer.parseInt(value.toString()); // 取出单词的已经出现次数,转成int
context.write(word,v+1); // 次数+1,并写入缓存
}
}
}
}
- 调用
// 先声明类对象
HDFSContext context = new HDFSContext();
HDFSMapper mapper = new WordCountMapper();
// while里调用
while ((line = reader.readLine()) != null) {
mapper.map(line,context);
}
缓存处理结果
Map<Object,Object> contextMap = context.getCacheMap();
追加结果到HDFS
// 把Map集合转换为Set集合,进行迭代操作
Set<Map.Entry<Object, Object>> entries = contextMap.entrySet();
for (Map.Entry<Object, Object> entry : entries) {
// 取出key-value,即(word,次数),写入HDFS
out.write((entry.getKey().toString()+"\t"+entry.getValue()+"\n").getBytes());
}
System.out.println("词频统计运行成功!");
out.close();
fs.close();
完整代码
package com.hadoop.hdfs.wordcount;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.Map;
import java.util.Set;
public class HDFSWordCountDemo{
public static void main(String[] args) throws Exception{
// 1.读取HDFS文件
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI("hdfs://localhost:9000"), conf, "hadoop");
HDFSContext context = new HDFSContext();
HDFSMapper mapper = new WordCountMapper();
// 使用Java API取出HDFS指定目录下所有要进行词频统计的单词文件,false表示不需要递归
RemoteIterator<LocatedFileStatus> files = fs.listFiles(new Path("input"), false);
// 用于循环取出多个单词文本
while (files.hasNext()) {
LocatedFileStatus file = files.next();
FSDataInputStream in = fs.open(file.getPath());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = null; // readLine每次读取一行
// 用于循环取出每个文本的每行内容
while ((line = reader.readLine()) != null) {
mapper.map(line,context);
}
reader.close();
in.close();
}
// 3.缓存处理结果:把统计结果写入缓存
Map<Object,Object> contextMap = context.getCacheMap();
// 4.将结果输出到HDFS
// 先在HDFS上创建一个空文本
FSDataOutputStream out = fs.create(new Path("output/result.txt"));
// 然后取出缓存中的内容,追加到该HDFS文本即可
Set<Map.Entry<Object, Object>> entries = contextMap.entrySet();
for (Map.Entry<Object, Object> entry : entries) {
out.write((entry.getKey().toString()+"\t"+entry.getValue()+"\n").getBytes());
}
System.out.println("词频统计运行成功!");
out.close();
fs.close();
}
}
查看运行结果
$ hadoop fs -cat output/*
使用HDFS完成wordcount词频统计的更多相关文章
- 初学Hadoop之WordCount词频统计
1.WordCount源码 将源码文件WordCount.java放到Hadoop2.6.0文件夹中. import java.io.IOException; import java.util.Str ...
- Hadoop基础学习(一)分析、编写并执行WordCount词频统计程序
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jiq408694711/article/details/34181439 前面已经在我的Ubuntu ...
- 词频统计小程序-WordCount.exe
一. 背景 最近顶哥为了完成学历提升学业中的小作业,做了一个词频统计的.exe小程序.因为当时做的时候网上的比较少,因此顶哥决定把自己拙略的作品发出来给需要的人提供一种思路,希望各位看官不要dis ...
- 使用SparkSQL编写wordCount的词频统计
# 使用SparkSQL编写wordCount的词频统计 ## word.txt```hello hello scala sparkjava sql html java hellojack jack ...
- Hive简单编程实践-词频统计
一.使用MapReduce的方式进行词频统计 (1)在HDFS用户目录下创建input文件夹 hdfs dfs -mkdir input 注意:林子雨老师的博客(http://dblab.xmu.ed ...
- hive进行词频统计
统计文件信息: $ /opt/cdh-5.3.6/hadoop-2.5.0/bin/hdfs dfs -text /user/hadoop/wordcount/input/wc.input hadoo ...
- Hadoop之词频统计小实验
声明: 1)本文由我原创撰写,转载时请注明出处,侵权必究. 2)本小实验工作环境为Ubuntu操作系统,hadoop1-2-1,jdk1.8.0. 3)统计词频工作在单节点的伪分布上,至于真正实 ...
- Hadoop上的中文分词与词频统计实践 (有待学习 http://www.cnblogs.com/jiejue/archive/2012/12/16/2820788.html)
解决问题的方案 Hadoop上的中文分词与词频统计实践 首先来推荐相关材料:http://xiaoxia.org/2011/12/18/map-reduce-program-of-rmm-word-c ...
- MapReduce词频统计
自定义Mapper实现 import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; impor ...
随机推荐
- Java中的Null是什么?
对于Java程序员来说,null是令人头痛的东西.时常会受到空指针异常(NPE)的骚扰.连Java的发明者都承认这是他的一项巨大失误.Java为什么要保留null呢?null出现有一段时间了,并且我认 ...
- leanote折腾指南
持续更新. 过几天把自己的修改好的css放到github上给大家参考. https://github.com/whuwangyong/leanote-conf TODO leanote Linux/W ...
- form组件+cookie+session总结
1.forms 组件 -数据校验功能 1.定义 -新建一个py文件 -导入from django import forms -写一个类继承 forms.Form -把你需要校验的(字段的条件)属性写到 ...
- 【集训队作业2018】【XSY3372】取石子 DP
题目大意 有 \(n\) 堆石子,初始时第 \(i\) 堆石子有 \(a_i\) 个. 你每次取石子会取 \(k\) 个.在你取完一堆石子之后才能在下一堆中取石子. 游戏会进行 \(t\) 轮,每轮会 ...
- Django_ORM操作 - 查询
ORM 操作 必知必会13条 <1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 <3> get(* ...
- 「BZOJ2733」「洛谷3224」「HNOI2012」永无乡【线段树合并】
题目链接 [洛谷] 题解 很明显是要用线段树合并的. 对于当前的每一个连通块都建立一个权值线段树. 权值线段树处理操作中的\(k\)大的问题. 如果需要合并,那么就线段树暴力合并,时间复杂度是\(nl ...
- python: c_char_p指向的bitmap图像数据,通过c_char_Array最终赋值给PIL的Image对象
def GetCurrentImage(self): ok, bitmap, buff_len = self.GetCurrentFrameBitmap() #调用C函数,返回位图数据的指针. bit ...
- Atcoder刷题小记
1. 2019.4.27 agc016d 一道很坑的题. 首先判无解,求出异或值后排个序就可以. 然后直接让\(a_i\rightarrow b_i\)并查集维护,注意离散化和判重,答案加上联通块个数 ...
- CTR预估中GBDT与LR融合方案(转载)
1.背景 CTR预估,广告点击率(Click-Through Rate Prediction)是互联网计算广告中的关键环节,预估准确性直接影响公司广告收入.CTR预估中用的最多的模型是LR(Logis ...
- 散列(C++实现)
散列的构成:散列函数,散列表的存储方式,散列表的冲突解决方法. 1.散列函数 较常用的散列函数有除留余数法,数字分析法,平方取中法,折叠法. 2.散列表的存储方式 闭散列法(开地址法),用数组存储:开 ...