Mapreduce 是谷歌提出的一个分布式计算框架, 利用该框架, 能够让用户方便地利用多机并行处理数据。 该框架有两个重要的函数: Map 和 Reduce, Map 函数对整个输入数据进行处理, 按照用户定义的处理方式, 从输入的数据中产生中间键值对( key, value)。Reduce 函数对这些键值对进行处理, 相同 key 的键值对由同一个 Reduce 进程进行处理。最终将处理的结果进行合并。 整个处理流程如下:
Phoenix 是由斯坦福大学基于多核多处理器系统实现的一套 mapreduce 框架, Phoenix框架能够自动管理线程的创建, 动态任务调度, 数据划分和故障容错。 本质上与用户写的多线程程序没有区别, 只不过通过这个框架, 能够更容易编写出能够划分为“map-reduce-merge”模式的数据处理业务。
Metis 框架是在 Phoenix 的基础上改进而来, Phoenix 中在 map 阶段使用哈希表, 对于哈希表中的每条条目使用排序数组进行保存, 而 Metis 采用了 BTree 的方式进行了代替, 以此来提高速度。
struct SPFA: public map_reduce{
bool split(split_t *out, int ncores);
void map_function(split_t *ma);
void reduce_function(void *k, void **v, size_t length);
int key_compare(const void *s1, const void *s2);
};
split: 数据切分函数, 在这里根据 ncores 参数, 用户 自定义如何划分数据, 并将数据切分信息保存在 out 中。
Map_funcion:对每个数据分片进行处理, 产生键值对。
Reduce_function:对键值对进行处理。
Key_compare: 用户自定义键值对的比较函数
SPFA app;
app.set_reduce_task(reduce_tasks);
app.set_ncore(nprocs);
mapreduce_appbase::initialize();
app.sched_run();
mapreduce_appbase::deinitialize();
set_reduce_task: 设置 reduce 线程的数量
set_ncore: 设置使用的核数
sched_run: 程序启动, 内部会先后调用数据切分, map, reduce, merge 等操作
map 线程数量: 由数据切分函数间接控制, 数据分块的数量对应 map_tasks。
SPFA 的思想十分简单, 简单说是加队列优化后的 bellman-ford 算法, 利用松弛操作, 更新距离。 通过引入队列, 有以下几个优化:
减少松弛操作: bellman-ford 算法每次迭代中, 不需利用所有的点对其他的点进行松弛操作, 减少了松弛次数。
负环判断: 通过点进入队列的次数, 可以判断是否存在负环, 如果进入队列 n 次, 则说明存在负环。
Dijkstra 算法采用贪心的方式, 每次从更新的节点中, 选出最小并且该点的值不可能再由剩下的节点来更新(无负环的情况下)。
图的存储方式: 二维数组
数据处理模式: map_only
Mapreduce 处理过程:
数据划分: 将整个图的节点集合按 map_tasks 数量进行均匀划分, 每个 map 处理其中一部分。
Map: 在一个数据分片中, 使用更新队列
替换更新队列: 清空更新队列, 将标记数组中标记过的节点加入更新队列, 用
于下一次迭代对其他节点进行松弛操作。
如果更新队列为空, 迭代结束, 否则继续下一次迭代。
说明:
[1] 更新队列: 节点被更新后放入的队列, 依次使用该队列中的节点对整个图的节点进行松弛操作。
[2] 标记数组: 用来标记该节点在当前迭代中是否被更新过, 作为是否放入下一次迭代中更新队列的依据。
[3] dist 数组: 源点到其他点的最近距离, 初始值为无穷大。
图的存储方式: 二维数组
数据处理模式: map_reduce
Mapreduce 处理过程:
数据划分: 将整个图的节点集合按 map_tasks 数量进行均匀划分, 每个 map 处理其中一部分。
Map: 在一个数据分片中, 使用当前未使用中离源点最近的点来对数据分片中
点的距离进行松弛操作, 如果出现更新操作, 发送以(点的编号%reduce_tasks)的值作为 key,点的编号作为 value 的键值对。
Reduce: 在每个 reduce 中, 找出当前离源点最近的点, 发送(点的编号, 点的距离)的键值对。
寻找最近的点: 在最终处理完的结果数组 result_中,挑选出离源点最近的点, 用
来在下一次迭代中更新其他点。 如果 result_数组为空, 退出迭代。
说明: 将整个找离源点最近的点分为了两个阶段, 先在 reduce 阶段求出了局部最近, 最后在局部最近的结果集中求出全局最近的点。
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/sunliymonkey/article/details/47982915