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好看太多了!

results matching ""

    No results matching ""