很久没有原创了,说明我很久没有学习了。无论是比较忙还是比较懒,无所谓了,继续学习hadoop中。
不是所有人都喜欢java,我就不喜欢,并且从前还挺反感java程序的——效率低,而且把内存细节封装了,让我这个c/c++程序员很不适应。streaming是hadoop允许其他编程语言(c/c++、脚本语言、管道命令)融合到hadoop框架的一个工具。主要是通过输入输出流来交换数据,所以叫做streaming。对于map和reduce,都是用一行行的文本作为沟通的媒介。
列一下代码,mapper函数如下:
void map (void) { string sLine; while (getline (cin, sLine)) { istringstream isLine (sLine); vector<string> WordVec; copy (istream_iterator<string>(isLine), istream_iterator<string>(), back_inserter(WordVec)); vector<string>::iterator p = WordVec.begin(); while (p != WordVec.end()) { cout << *p << "\t" << "1" << endl; p++; } } } int main (int argc,char** argv) { map(); }
由于hadoop编程框架的限制,c/c++只能采用函数式编程。上述逻辑很简单,就是从输入中流获取文本,处理后再在输出流中输出。在terminal中敲入:
g++ hadoopMapFunc.cpp -o hadoopMapFunc
生成hadoopMapFunc可执行文件。
reduce函数如下:
#include <string> #include <vector> #include <iostream> #include <sstream> #include <iterator> using namespace std; void reduce (void) { string sLine; while (getline (cin, sLine)) { istringstream isLine (sLine); string sWord; isLine >> sWord; vector<string> NumVec; copy (istream_iterator<string>(isLine), istream_iterator<string>(), back_inserter(NumVec)); int iSum = 0; vector<string>::iterator p = NumVec.begin(); while (p != NumVec.end()) { int i = atoi (p->c_str()); iSum += i; p++; } cout << "line=" << sLine << " " << "word=" << sWord << "\t" << "sum=" << iSum << endl; } } int main (int argc,char** argv) { reduce(); }
在terminal输入
g++ hadoopReduceFunc.cpp -o hadoopReduceFunc
得到hadoopReduceFunc可执行文件。
最后,运行hadoop程序,在terminal中输入
bin/hadoop jar contrib/streaming/hadoop-0.20.2-streaming.jar -file /Volumes/Data/Works/hadoopWordCountStreaming/hadoopMapFunc -file /Volumes/Data/Works/hadoopWordCountStreaming/hadoopReduceFunc -input input -output outputStreaming -mapper /Volumes/Data/Works/hadoopWordCountStreaming/hadoopMapFunc -reducer /Volumes/Data/Works/hadoopWordCountStreaming/hadoopReduceFunc
参数 -file 表示把文件传到hdfs上,其余的参数含义比较明显。相比用java写的hadoop程序,java写的程序都单独打成jar包,在hadoop jar的命令下运行。而streaming是调用固定的hadoop-0.20.2-streaming.jar包,并把c++编译的map和reduce可执行文件作为jar包的参数,传递给jar包。输入上述命令后,可以看到正常运行,比起jar native程序和c++ pipe方式运行,streaming的速度似乎慢一些。
检查输出结果,发现输出结果不对。预期的,应该是各个单词求和的情况,而实际输出是map的输出,即”word 1“ 对儿。我又在reduce中加入打印信息,打印当前输入的行,以及我的输出行,结果(片段)如下:
line=-1 1 word=-1sum=1
line=-1 1 word=-1sum=1
line=-1 1 word=-1sum=1
line=-1 1 word=-1sum=1
line=-1 1 word=-1sum=1
line=-1 1 word=-1sum=1
line=-1 1 word=-1sum=1
line=-1 1 word=-1sum=1
line=-1 1 word=-1sum=1
line=-1 1 word=-1sum=1
line=-1 1 word=-1sum=1
line=-1 1 word=-1sum=1
line=-1 1 word=-1sum=1
可以看到,输入的是反复的 ”word 1“ 对儿。分析是hadoop过程中,没有进行shuffle的原因。目前不得其解。
未完。。。