转自http://www.cnblogs.com/cherri/archive/2013/08/24/3279602.html
序:终于开始接触hadoop了,从wordcount开始
1. 采用hadoop streamming模式
优点:支持C++ pathon shell 等多种语言,学习成本较低,不需要了解hadoop内部结构
调试方便:cat input | ./map | sort | ./reduce > output
hadoop 就是提供了一个分布式平台实现了上述脚本的功能,这是一次mapreduce的过程
一个例子:
2. map :cat input | ./map >> temp
1)hadoop平台做了什么:
a.切分文件:把input文件按照一定的策略切割分成若干个小文件
b.将若干个小文件分别分发到不同节点上
c. 每个节点上都有一个map程序,然后将任务分发到不同的节点上
2)自己要写的wordcount_map要做什么:
wordcount_map从input中按行进行读取,然后按照业务逻辑将读取到的内容拼成 key \t value的形式 ,这个输出将会作为reduce程序的输入
在这里输出的是 word 1 此处 word是key 1是value
注意:此处是标准输出、输入 std::cout std::cin in C++
key与value之间用\t分割,第一个\t之前的值作为key,之后的都作为value 注意:这个key会被hadoop平台用到 平台不关注value值
#include<iostream> #include<string> #include<vector> using namespace std; void split(string src,vector<string>& dest,string separator) { string str = src; string substring; string::size_type start = 0, index; do { index = str.find_first_of(separator,start); if (index != string::npos) { substring = str.substr(start,index-start); dest.push_back(substring); start = str.find_first_not_of(separator,index); if (start == string::npos) return; } }while(index != string::npos); substring = str.substr(start); dest.push_back(substring); } void map() { string line; vector<string> vec(2); while(cin>>line) { vec.clear(); split(line,vec," "); vector<string>::iterator it=vec.begin(); for(;it!=vec.end();++it) { cout<<*it<<"\t"<<"1"<<"\t"<<"fuck"<<endl; } } } int main() { map(); } //wordcount_map
3. reduce: sort | ./reduce > output
等到所有的map任务都结束:
1)hadoop平台做了这些事情
a.将所有的map程序的输出结果中key相同的key value pair 放到相同的节点上,这点很重要,这是保证最终输出结果正确的保证,后面会按照key进行hash , 并且相同 key之间不会有其他的key,其实是按照key值做了一个排序
注意:相同的key一定在一个节点上,但是一个节点上不止有一个个key
b 然后在各个节点上开始reduce任务
2)自己写的wordcount_map做了什么
a. 读取这些具有相同key的键值对,处理自己的业务逻辑,此处就是将统计相同的key值的键值对一共出现了几次,然后将结果输出,此处也是标准输入和标准输出
#include<vector> #include<map> #include<string> #include<iostream> using namespace std; void reduce() { string key; string value; string value1; //vector<string> vec(2); map<string,int> mapTemp; while(cin>>key>>value>>value1) { if(mapTemp.find(key)!=mapTemp.end()) mapTemp[key]+=1; else mapTemp[key]=1; } map<string,int>::iterator it = mapTemp.begin(); for(;it!=mapTemp.end();++it) { cout<<it->first<<"\t"<<it->second<<endl; } } int main() { reduce(); } //wordcount_reduce