muduo多机协作网络编程示例一:单词计数及排序
2013-01-13 04:02
387 查看
去年我写了《Muduo 网络编程示例》系列文章,这些文章已经收入《Linux 多线程服务端编程:使用 muduo C++ 网络库》一书。这些文章讲的基本都是运行在单机上的网络程序,每个例子都只有一个程序(第7.13节例外)。我接下来打算继续写几篇文章,谈一谈分布在多台机器上、协作发挥作用的网络编程例子。
今天先讲第一个,单词计数及排序。单词计数(word count),顾名思义就是统计一个文本文件里边每个词出现了多少次。排序指的是按出现次数从多到少排序,也可以把问题改为“找出出现次数最多的1000个单词”。
这个问题有三个层次,第一是输入文件比较小,能完全放入内存;第二是输入文件比较大,不能一次性都放入内存;第三是输入文件分布在多台机器上,这需要用到网络编程。
第一个层次很好解决,几十行代码就搞定了。https://gist.github.com/4519962
第二个层次不难解决,基本思路是分而治之,先hash分块统计单词出现次数,将每一块按出现次数排序,最后归并。代码见 https://github.com/chenshuo/recipes/blob/master/puzzle/query_freq.cc ,分析见 /article/4969856.html 。
第三个层次也不难,可以当做网络编程的练习来做。如果有合适的框架,可以轻松解决,因为单词计数是map reduce的经典范例,对出现次数排序也可以再用一步map reduce搞定(估计需要一个好的 shuffle 函数,简单hash是不行的)。
如果用普通网络编程,一种设计思路如下图,其中方框代表机器,椭圆代表输入输出文件,圆角矩形代表进程。思路跟第二个层次一样,先hash到多个shard文件(由hasher和receiver负责),再对每个shard文件排序(由sender负责),最后归并(merger)。
注意这种思路适合求top K元素,不适合按出现次数排序全部单词,因为最终结果收集在一台机器上。目前这个sender实现的一个限制是,每个shard必须能全部放入内存,因为sender对shard排序是在内存中进行的。如果数据更大,还需要实现单机外部排序。
图中hasher和receiver的代码见muduo示例中的 muduo/examples/wordcount ;sender和merger的代码见 https://github.com/chenshuo/recipes/tree/master/topk 。注意merger没有使用muduo,而是采用阻塞网络编程。有兴趣的读者可以思考其背后的原因。要想发挥 merger 正常的性能,需要修改 /usr/include/boost/asio/basic_socket_streambuf.hpp ,增大缓冲区,即 enum { buffer_size = 8192 };
这可以看作是map reduce的原始实现,或者说用map reduce的思想手写了一些原始工具。如果把map reduce比作C语言,这里的几个程序相当于汇编写的函数。
以后我再写一个按出现次数全排序的例子吧,需要替换这里的sender和merger。
(.完.)
今天先讲第一个,单词计数及排序。单词计数(word count),顾名思义就是统计一个文本文件里边每个词出现了多少次。排序指的是按出现次数从多到少排序,也可以把问题改为“找出出现次数最多的1000个单词”。
这个问题有三个层次,第一是输入文件比较小,能完全放入内存;第二是输入文件比较大,不能一次性都放入内存;第三是输入文件分布在多台机器上,这需要用到网络编程。
第一个层次很好解决,几十行代码就搞定了。https://gist.github.com/4519962
第二个层次不难解决,基本思路是分而治之,先hash分块统计单词出现次数,将每一块按出现次数排序,最后归并。代码见 https://github.com/chenshuo/recipes/blob/master/puzzle/query_freq.cc ,分析见 /article/4969856.html 。
第三个层次也不难,可以当做网络编程的练习来做。如果有合适的框架,可以轻松解决,因为单词计数是map reduce的经典范例,对出现次数排序也可以再用一步map reduce搞定(估计需要一个好的 shuffle 函数,简单hash是不行的)。
如果用普通网络编程,一种设计思路如下图,其中方框代表机器,椭圆代表输入输出文件,圆角矩形代表进程。思路跟第二个层次一样,先hash到多个shard文件(由hasher和receiver负责),再对每个shard文件排序(由sender负责),最后归并(merger)。
注意这种思路适合求top K元素,不适合按出现次数排序全部单词,因为最终结果收集在一台机器上。目前这个sender实现的一个限制是,每个shard必须能全部放入内存,因为sender对shard排序是在内存中进行的。如果数据更大,还需要实现单机外部排序。
图中hasher和receiver的代码见muduo示例中的 muduo/examples/wordcount ;sender和merger的代码见 https://github.com/chenshuo/recipes/tree/master/topk 。注意merger没有使用muduo,而是采用阻塞网络编程。有兴趣的读者可以思考其背后的原因。要想发挥 merger 正常的性能,需要修改 /usr/include/boost/asio/basic_socket_streambuf.hpp ,增大缓冲区,即 enum { buffer_size = 8192 };
这可以看作是map reduce的原始实现,或者说用map reduce的思想手写了一些原始工具。如果把map reduce比作C语言,这里的几个程序相当于汇编写的函数。
以后我再写一个按出现次数全排序的例子吧,需要替换这里的sender和merger。
(.完.)
相关文章推荐
- muduo多机协作网络编程示例一:单词计数及排序
- muduo多机协作网络编程示例一:单词计数及排序
- Muduo 网络编程示例之一:五个简单 TCP 协议
- windows网络编程示例
- Muduo 网络编程示例之七:“串并转换”连接服务器及其自动化测试
- Linux网络编程之socket文件传输示例
- Symbian 得到接入点ID-网络编程简单示例
- Muduo 网络编程示例之零:前言
- 黑马程序员--10.网络编程--07.【C_S编程中服务器端和客户端的读写流】【C_S常见的“双卡”现象和解决--TCP文本转换器示例】【TCP文本转换器客户端和服务器端循环结束分析】【网络流简化】
- Muduo 网络编程示例之八:用 Timing wheel 踢掉空闲连接
- java网络编程之socket网络编程示例(服务器端/客户端)
- spark-streaming 编程(二) word count单词计数统计
- 网络编程基础(4)——小结及两个示例
- Muduo 网络编程示例之一:五个简单 TCP 协议
- 网络扫描技术揭秘读书笔记2--扫描器中公用编程示例(2)
- Muduo 网络编程示例之七:“串并转换”连接服务器及其自动化测试
- 网络编程--IO模型示例
- linux网络编程用到的网络函数详解用和使用示例
- 网络编程示例代码(window+linux)