7.3 RHadoop实验 – 统计邮箱出现次数
问题
RHadoop怎么用?
引言
通过RHadoop我们可以用R语言实现MapReduce的开发,比起上百行的Java代码来说,R的代码是这么的简洁。本节将介绍一个统计需求案例。
7.3.1 需求描述
本节使用的系统环境:
- Linux Ubuntu 12.04.2 LTS 64bit server
- R 2.15.3 64bit
- Java JDK 1.6.x
- Hadoop 1.0.3
通过给定的实验数据,计算邮箱域出现了多少次?并按邮箱域出现次数从大到小排序。用RHADOOP实现MapReduce算法。实验数据为hadoop15.txt。
wolys@21cn.com
zss1984@126.com
294522652@qq.com
simulateboy@163.com
zhoushigang_123@163.com
sirenxing424@126.com
lixinyu23@qq.com
chenlei1201@gmail.com
370433835@qq.com
cxx0409@126.com
viv093@sina.com
q62148830@163.com
65993266@qq.com
要求输出计算结果,如下格式。
163.com,14
sohu.com,2
7.3.2 算法实现
1. 计算邮箱域出现了多少次
~ R # 启动R程序
> library(rhdfs)
> library(rmr2)
> data<-read.table(file="hadoop15.txt") # 从本地读入数据到内存
> d0<-to.dfs(keyval(1, data)) # 从内存把数据上传到hdfs
> from.dfs(d0) # 查看HDFS上面的d0的数据
$key
[1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[39] 1 1 1
$val
V1
1 wolys@21cn.com
2 zss1984@126.com
3 294522652@qq.com
4 simulateboy@163.com
5 zhoushigang_123@163.com
6 sirenxing424@126.com
7 lixinyu23@qq.com
8 chenlei1201@gmail.com
9 370433835@qq.com
10 cxx0409@126.com
自定义mr()函数,计算邮箱域出现了多少次
> mr<-function(input=d0){ # 创建mr()函数
+ map<-function(k,v){
+ # 截取字符串@后面的部分
+ keyval(word(as.character(v$V1), 2, sep = fixed('@')),1)
+ }
+ reduce =function(k, v ) {
+ # 对有相同邮箱域名计数求和
+ keyval(k, sum(v))
+ }
+ d1<-mapreduce(input=input,map=map,reduce=reduce,combine=TRUE)
+ }
> d1<-mr(d0) # 运行mr()函数
> from.dfs(d1) # 查看HDFS上面的d0的数据
$key
[1] "126.com" "163.com" "21cn.com" "gmail.com" "qq.com"
[6] "sina.com" "sohu.com" "yahoo.cn" "yahoo.com.cn"
$val
[1] 9 14 1 1 9 2 2 1 2
2. 按次数从大到小排序
自定义sort()函数,按域名出现次数进行排序
> sort<-function(input=d1){ # 创建sort()函数
+ map<-function(k,v){
+ # 对上一步d1的结果集进行格式化
+ keyval(1,data.frame(k,v))
+ }
+ reduce<-function(k,v){
+ # 对数据集进行排序
+ v2<-v[order(as.integer(v$v),decreasing=TRUE),]
+ keyval(1,v2)
+ }
+ d2<-mapreduce(input=input,map=map,reduce=reduce,combine=TRUE)
+ }
> d2<-sort(d1) # 执行排序
> result<-from.dfs(d2) # 把结果从HDFS上读入内存
> result$val # 输出排序后的结果
k v
2 163.com 14
1 126.com 9
5 qq.com 9
6 sina.com 2
7 sohu.com 2
9 yahoo.com.cn 2
3 21cn.com 1
4 gmail.com 1
8 yahoo.cn 1
注:第二步排序的reduce过程,本节使用了基于单节点的写法,对于海量数据的情况这个代码还需要优化。短短的几行代码,就完成功能,从代码上看,比Java好看太多了!