利用 Map-Reduce 从文件中找到出现频率最高的 10 个 URL(2021 VLDB Summer School Lab0)

这篇博客详细介绍了如何利用 Map-Reduce 完成VLDB Summer School Lab0任务,涉及Golang实现及性能优化。作者通过简化版的Map-Reduce框架,实现了对大量数据进行计数、排序和Top10过滤,最终提升运行效率约3倍。
摘要由CSDN通过智能技术生成

这篇博文主要是对 2021 VLDB Summer School Lab0 的一个总结

这个lab与MIT 6.824 的 lab1 相似,个人感觉比MIT 6.824 的 lab1 要稍微简单些,更容易上手。通过这个lab,可以学习到一些 Golang 的基础知识并对分布式系统有一个基础的了解,我做下来感觉文档写得十分完善,包括需要的一些前置知识都说得很清楚,同时还提供了一些学习资源,强烈推荐分布式系统的初学者做一下这个lab,传送门:https://github.com/tidb-incubator/vldbss-2021/tree/master/lab0

Map-Reduce简介

我之前对Map-Reduce只是简单听说过,没有仔细了解,我首先看了lab里推荐的 MIT 6.824 课程,不过一节课1个多小时,感觉节奏稍微有点慢,我就直接找的原始论文《MapReduce: simplified data processing on large clusters》 对Map-Reduce进行了一个简要地学习。

简单来说,Map-Reduce是一个分布式的用来处理大规模数据的High-Level框架,之所以称之为High-Level是因为在设计它时就是为了让它能够处理大部分分布式数据处理任务,即适用范围要广,所以它的抽象程度会比较高。

整个Map-Reduce框架的主要组成部分如下图所示:

 执行流程大致为:

  • 读入输入文件
  • Master分配分布式集群中的worker(一台可以用于计算的服务器)对输入数据执行map操作,并将执行结果写入该worker的本地磁盘
  • map操作的结果成功写入磁盘后会通知Master,此时Master会分配一个reduce任务给一台空闲worker 同时告诉它去哪可以取到map操作的结果,这时这台worker会通过RPC(Remote Procedure Call,远程过程调用)取到map操作的结果,然后以此作为输入执行reduce操作,最后将reduce操作的结果输出为一个单独的文件,注意此时与map操作结果直接写入worker本地不同,reduce操作结果的输出目的地一般是GFS等分布式文件系统或者是作为下一轮Map-Reduce的输入

在这整个过程中,只有Map操作和Reduce操作是由用户自己编写,其余的均由框架完成。

也就是说,我们只关心Map函数和Reduce函数应该完成哪些任务,就可以完成各种各样的分布式数据处理任务,使得分布式处理任务的编码成本得以降低,这也是Map-Reduce框架的主要意义所在。

Lab0 任务一:完成 Map-Reduce 框架

这次lab设计得对初学者十分友好,lab中提供的源码对Map-Reduce框架已经完成了很大一部分,包括Map阶段的代码都是完整的,所以初学者经过简单地学习go语言之后,可以通过阅读框架中已经写好的代码进行快速地上手。

从最简单的的开始,我们首先对Reduce阶段进行实现。

Reduce阶段需要拿到对应的map操作的执行结果,然后以此作为输入执行reduce操作,最后将执行结果输出为一个文件即可,具体代码如下:

				// YOUR CODE HERE :)
				// hint: don't encode results returned by ReduceF, and just output
				// them into the destination file directly so that users can get
				// results formatted as what they want.
				if t.phase != reducePhase {
					panic("unknown task phase")
				}

				reduceRes := make(map[string][]string)
				for i := 0; i < t.nMap; i++ {
					//通过文件名规则拿到对应map的结果
					mappedFileName := reduceName(t.dataDir, t.jobName, i, t.taskNumber)
					mappedFile, err := os.Open(mappedFileName)
					if err != nil {
						log.Fatalln("open mapped file error: ", mappedFileName, " error: ", err)
					}

					dec := json.NewDecoder(mappedFile)
					for {
						var kv KeyValue
						if err := dec.Decode(&kv); err != nil {
							break //EOF
						}
						if _, exist := reduceRes[kv.Key]; !exist {
							reduceRes[kv.Key] = make([]string, 0)
						}
						reduceRes[kv.Key] = append(reduceRes[kv.Key], kv.Value)
					}
					SafeClose(mappedFile, nil)
				}

				fs, bs := CreateFileAndBuf(mergeName(t.dataDir, t.jobName, t.taskNumber))
				for k, v := range reduceRes {
                    //输出Reduce结果
					WriteToBuf(bs, t.reduceF(k, v))
				}
				SafeClose(fs, bs)

观察发现,Map-Reduce 框架需要补充的部分就还剩:Master分发的Map任务都执行完毕之后的执行逻辑

分析得知,map任务都执行完毕之后需要接着分发Reduce任务,对着上面已经写好的Map任务分发逻辑,可以照猫画虎地对R

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Knight丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值