目录
一、前提准备工作
启动hadoop集群
windows可以访问
二、整体流程
三、核心代码讲解
四、生成jar包上传
五、运行程序
Gitee仓库Hadoop项目下载地址
其他系列技术教学、实战开发
一、前提准备工作
启动hadoop集群
必须已经成功搭建好了hadoop集群,打开主节点和子节点全部虚拟机,启动hadoop
windows可以访问
关闭主节点虚拟机的防火墙,在windows的hosts文件添加配置信息
二、整体流程
整体流程如下
程序内部执行过程如下
三、核心代码讲解
Mapper类
将单词文本进行切割,切割成一个个的单词,写入到上下文中
(1)按行读取,通过split函数进行切割,将切割出来的一个个单词放到数组ars中
(2)遍历数组ars,将存在的单词数据存储到word中,然后将word写入到context上下文(使Redcue程序能访问到数据)
package com.itcast;
import java.io.IOException;
import java.util.Date;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
/**
* FileName: WordMapper
* Author: Yuan-Programmer
* Date: 2021/11/8 23:29
* Description:
*/
// 创建一个 WordMapper类 继承于 Mapper抽象类
public class WordMapper extends Mapper<Object, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
// Mapper抽象类的核心方法,三个参数
public void map(Object key, // 首字符偏移量
Text value, // 文件的一行内容
Context context) // Mapper端的上下文,与 OutputCollector 和 Reporter 的功能类似
throws IOException, InterruptedException {
String[] ars = value.toString().split("['.;,?| \t\n\r\f]");
for (String tmp : ars) {
if (tmp == null || tmp.length() <= 0) {
continue;
}
word.set(tmp);
System.out.println(new Date().toGMTString() + ":" + word + "出现一次,计数+1");
context.write(word, one);
}
}
}
Reduce类(部分代码展示)
(1)将每个单词统计次数结果进行求和合并,写入到map集合里
(2)调用Utils工具类的sortValue方法对map集合进行排序
(3)遍历排序好的map集合,依次写入到context上下文中
package com.itcast;
import java.io.IOException;
import java.util.*;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
/**
* FileName: WordReduce
* Author: Yuan-Programmer
* Date: 2021/11/8 23:32
* Description:
*/
// 创建一个 WordReducer类 继承于 Reducer抽象类
public class WordReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
private IntWritable result = new IntWritable(); // 用于记录 key 的最终的词频数
HashMap<String, Integer> map = new HashMap();
// Reducer抽象类的核心方法,三个参数
public void reduce(Text key, // Map端 输出的 key 值
Iterable<IntWritable> values, // Map端 输出的 Value 集合(相同key的集合)
Context context) // Reduce 端的上下文,与 OutputCollector 和 Reporter 的功能类似
throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) // 遍历 values集合,并把值相加
{
sum += val.get();
}
map.put(key.toString(), sum);
System.out.println(new Date().toGMTString() + ":" + key + "出现了" + result);
}
@Override
protected void cleanup(Context context) throws IOException, InterruptedException {
// 根据map中的value进行排序
Map<String, Integer> sortedMap = MapUtils.sortValue(map);
Set<Map.Entry<String, Integer>> entries = sortedMap.entrySet();
Iterator<Map.Entry<String, Integer>> it = entries.iterator();
/**
* 不设置count,对全部单词进行排序
* 循环获取迭代器的Map对象,再获取对应K,V
* 将K,V封装到上下文中
*/
while (it.hasNext()) {
// 获取Map
Map.Entry<String, Integer> entry = it.next();
String key = entry.getKey();
Integer value = entry.getValue();
// 封装k3,v3
Text k3 = new Text();
k3.set(key);
IntWritable v3 = new IntWritable();
v3.set(value);
// 写入上下文
context.write(k3, v3);
}
}
}
Utils类(对map进行排序)
(1)继承Comparable类,复写compare方法
(2)通过map<k,v>集合的value(也就是单词次数)进行排序
(3)将排序好的map返回
package com.itcast;
/**
* FileName: MapUtils
* Author: Yuan-Programmer
* Date: 2021/11/9 0:05
* Description:
*/
import java.util.*;
/**
• Map工具类
*/
public class MapUtils {
/**
– 根据Map的value值降序排序
– @param map
– @param
– @param
– @return
*/
public static <K, V extends Comparable<? super V>> Map<K, V> sortValue(Map<K, V> map) {
List<Map.Entry<K, V>> list = new ArrayList(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
@Override
public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
/**
* o1-o2:升序
* o2-o1:降序
* 返回结果加上“-”表示取反操作(升序->降序,降序->升序)
*/
int compare = (o1.getValue()).compareTo(o2.getValue());
return -compare;
}
});
//将排序结果返回上一级
Map<K, V> returnMap = new LinkedHashMap<K, V>();
for (Map.Entry<K, V> entry : list) {
returnMap.put(entry.getKey(), entry.getValue());
}
return returnMap;
}
}
新建一个测试类测试一下,可以看到排序OK
四、生成jar包上传
先点击右边的 clean 清理一下,然后点击 package
运行完毕,会在左边生成一个 target
选中jar包,右键选择复制,粘贴到桌面
打开 winscp 工具,连接主节点虚拟机,将刚刚粘贴在桌面的jar包拷贝到虚拟机里(路径自己选,知道在哪就行)
打开虚拟机,跳转到刚刚复制的路径目录下,可以看到已经拷贝进来了
五、运行程序
(1)创建单词文本并上传
在下面可以看到有一个words.txt文本,这是我之前创好的
more指令查看文本,可以看到文本里有很多的英文单词
(2)上传到HDFS文件系统
首先创建一个文件夹存放统计前的单词文本(words.txt)
将单词文本(words.txt)上传到刚刚创建的文件夹下
hadoop jar jar包名称 包名称+主类名 输入路径 输出路径
包名称+主类名如下
回车执行命令,等待提示运行完毕,运行结束后
打开HDFS文件系统的output目录下,就能看到输出结果,打开文件点击Download下载
以文本方式打开,可以看到已经对单词进行了统计并且对其进行降序操作