前言
本文通過僅使用HDFS的原生Java-API,不調用MapReduce,對文本單詞進行詞頻統計。輸入和輸出文件位置均存放在HDFS上。
本程序使用到了properties配置文件指定連接配置、輸入輸出地址以及類名等。注意,當把類名寫入配置文件並使用時,不能用new,而需要使用Java中的反射來獲取類。
一、樣例輸入輸出
1.樣例輸入
2.樣例輸出
二、程序步驟
1.引入maven依賴
首先需要創建一個普通的maven項目,然後引入Hadoop和Junit的maven依賴。Junit主要用於單元測試(本來只有main程序可以運行的,導入Junit之後可以在任意函數前加@Test之後便可直接運行該程序),因此Junit可以根據具體需要和偏好決定是否導入。
maven依賴添加於pom.xml之中,具體配置如下:
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.2</version>
</dependency>
<!--HDFS-->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
</dependencies>
2.配置properties文件
ADDRESS=hdfs://centos01:9000
USER=hadoop
INPUT_FILE=/test/HDFS/inputWords.txt
OUTPUT_FILE=/test/HDFS/realOut.txt
CONTEXT_CLASS=wordCount.Context
將該配置文件放在resources目錄下。
3.實現步驟
本項目的大致邏輯和實現步驟是:
1)從properties文件中讀入參數,如用戶名、hdfs連接地址和端口號等,進行連接並獲取FileSystem;
public class myConnection {
public static FileSystem fileSystem(Properties properties) throws URISyntaxException, IOException, InterruptedException {
URI address=new URI(properties.getProperty(Constants.ADDRESS.getValue()));
String user=properties.getProperty(Constants.USER.getValue());
Configuration conf=new Configuration();
FileSystem System=FileSystem.get(address,conf,user);
return System;
}
}
2)新建Context類,用於將原數據存入TreeMap(不使用HashMap的原因是HashMap本身是無序的,想要在輸出時排好順序),該類還包含分割和詞頻統計方法;
public class Context {
private TreeMap<String,Integer> map=new TreeMap<String,Integer>();
public void write(String vocabulary,int num)
{
vocabulary=vocabulary.toLowerCase();
if(map.containsKey(vocabulary))
shuffle(vocabulary);
else
map.put(vocabulary,num);
}
public void write(String vocabulary)
{
if(map.containsKey(vocabulary))
shuffle(vocabulary);
else
map.put(vocabulary,1);
}
public void shuffle(String key)
{
map.put(key,map.get(key)+1);
}
public TreeMap<String,Integer> read()
{
return map;
}
}
3)使用Context類,將從HDFS上讀取的源數據進行分割和詞頻統計操作並存入Context.java中的TreeMap中。
public class Reader {
public static Context read(Properties properties,FileSystem fileSystem) throws URISyntaxException, IOException, InterruptedException, ClassNotFoundException, IllegalAccessException, InstantiationException {
Path path=new Path(properties.getProperty(Constants.INPUT_FILE.getValue()));
FSDataInputStream in = fileSystem.open(path);
BufferedReader reader=new BufferedReader(new InputStreamReader(in));
String line="";
String contextClassName=properties.getProperty(Constants.CONTEXT_CLASS.getValue());
Class clazz=Class.forName(contextClassName);
Context context= (Context) clazz.newInstance();
while((line=reader.readLine())!=null)
{
//System.out.println(line);
String[] S=line.split(" ");
for(String s:S)
{
System.out.println(s);
context.write(s,1);
}
}
reader.close();
return context;
}
}
4)將結果輸出到properties中的指定HDFS路徑。
public static boolean output(Properties properties,FileSystem fileSystem,Context context) throws IOException {
TreeMap<String,Integer> myMap=context.read();
Iterator<Map.Entry<String, Integer>> it=myMap.entrySet().iterator();
FSDataOutputStream out = null;
Path outputPath=new Path(properties.getProperty(Constants.OUTPUT_FILE.getValue()));
if(fileSystem.exists(outputPath))
fileSystem.delete(outputPath);
out = fileSystem.create(outputPath);
while (it.hasNext())
{
java.util.Map.Entry<String,Integer> entry=it.next();
out.write((entry.getKey()+"\t"+entry.getValue()+"\n").getBytes());
}
out.flush();
out.close();
fileSystem.close();
return true;//若成功返回true
}
二、總結
以上就是本文要講的內容,本文通過僅使用HDFS的原生Java-API,不調用MapReduce,對來自HDFS文本單詞進行詞頻統計操作,並上傳到HDFS上。
最後附上本項目的github地址,供大家參考。github項目地址
第一次寫博客,如有不足之處還請大家多多指教、多多包涵。