MIT 6.824入门1--mapreduce与分片

394 阅读3分钟

从M哥的一道面试题说起

问题

你有一个社区需要管理,现在要开发点赞和显示点赞数量的功能,社区的使用人数很多(日活超过100w),同时点赞的次数也很多(每天人均点赞100次).

已知点赞的消息存储在消息队列中,应该如何设计分布式统计点赞的功能?

先分析下问题

  1. 每天的点赞量超过1亿的量级,分布式设计是必须的,单核早爆炸了.
  2. 存储层的事情肯定是需要支持持久化存储,可以用mysql+缓存层
  3. 需要考虑容错问题和幂等问题
  4. 消息消费应该按照批次进行,单条消息处理耗费太高.

面试同学的给的答案

  1. 批量消费数据,消费完成后通过ack确认
  2. 程序是原子的,当出现计算异常时回滚已经造成影响的操作
  3. 程序设计为幂等,当出现网络问题重入时计算结果不受影响.

面试同学答案存在的问题

  1. ack确认可能导致当消息未被正常消费时不再启动重新计算
  2. 原子性程序成本非常高,同时需要对回滚操作也加上异常处理,事实上的事务是很难保证的

可能的解决方式

  1. 需要有 master 节点通过记录消费情况来调度worker
  2. 通过判断 worker 的心跳来考虑是否需要任务重发
  3. 单个 worker 程序完整地处理的所需要的工作时再执行对后端缓存/DB的写入,临时数据存在内存里或者本地的存储里.同时通知 master 这部分数据已经完成了处理.

所以核心是什么呢? 当可接受的数据量是单机的100倍甚至更多时,如何用 分片+调度 解决数据的处理问题

分片.png

言归正传

理解了上面的问题对于理解mapreduce有很多帮助,今天我们主要关注 mapreduce 的分布式处理思想.只讨论理论上的问题,框架和使用不在考虑范围.

论文地址

英文版论文地址:static.googleusercontent.com/media/resea…

中译版论文:developer.aliyun.com/article/318…

核心问题:大数据量时如何进行数据处理

核心概念

  1. data 待计算的源数据,数据类型为<k,v>
  2. master master程序负责进行任务分配,当然,为了保证分配的合理性,功能会更复杂.
  3. worker 执行任务的程序,负责执行map方法或者reduce方法. 4.1 map方法
    map(k1,v1) ->list(k2,v2)
    

4.2 combine方法 combine(list(k2,v2)) -> (k2,list(v2)) 5. reduce方法 对map的结果进行处理 reduce(k2,list(v2)) ->list(v2)

流程

  1. 待处理的数据存储在磁盘上
  2. master分配map任务的worker,每个map任务去指定的数据位置取数据
  3. map函数的计算结果存放在内存或是本地的磁盘
  4. 通过combine过程对map的结果进行合并处理,相同key的被聚合
  5. 分配reduce程序对聚合后的mapRes进行reduce函数的处理
  6. 结果写入本地的磁盘
  7. 完成

mapreduce.png

举例

我们参照论文中的举例:统计文本中词语的出现次数为例子,看下一次完整的流程是怎么样的.

数字数.jpg

小结一下

我们今天暂时不去深究mapreduce的实现,只关注其中的对于大数据量的情况使用分片的逻辑进行处理的思路.