经过一段时间的了解这个MIT 6.824,真的深深感觉,见识越多,就越知道自己有多菜。我登入6.824网站,可以看到别人一周的安排是怎样的,一周之内学会go语言,并完成lab 1,其中lab 1 又有五个部分。而我呢,我大概花了一周才了解了go语言,又看了一周才了解mapreduce,然后才开始做lab1,不得不说里面的introduction,Read,lab全是英文,真的超烦人,有时候写程序写着也会忘记go怎么用的,甚至和java,c++混淆了,说真的,这一个月真的搞这个东西搞到自闭,搞到脑袋都要炸了。
不过呢还是得承认这个过程还是挺不错的,知道了自己和别人的差距,做出来的过程中成就感还是有的哈哈哈。挺喜欢这种感觉。
如果想要学习的话可以去MIT 6.824学习。
一:MapReduce简介
首先就是理一理mapreduce了,其实是map and reduce,这是一个编程模型,一般笼统的分为map函数和reduce函数。
原理:通过输入key–value有map函数生成中间的key–value,并作为reduce的输入由reduce生成最终的value。
看看上面这个图片梳理一下大概的过程了。
1:首先就是用户是吧,根据具体的场景,选取具体的mapreduce编程模型。
2:mapreduce库里面的某些程序将输入文件分成M个数据片,如上图左边的split0,1,2,3…有的用户程序会在集群中创建大量副本,备用。
3:有个特殊的程序master程序,还有就是worker程序。master程序分配M个map任务和R个reduce任务,将他们分给空闲的worker程序
4:分配的map任务的worker程序读取相应的输入数据,解析出key-value,然后传递给map函数,map函数生成相应的中间文件key-value,这时一个key对应的是集合value,这些文件会缓存在该worker程序的内存中,尽量减少网络传输,和某些程序故障时,数据丢失。
5:缓存的中间文件key-value被分成R个区域,然后写入到本地磁盘上,他们的存储位置会被传回master,master将存储位置传给reduce。
6:当reduce接收到这些位置时,使用RPC从map worker所在的位置上读取这些中间文件作为输入文件,同时reduce需要对key进行排序。
7:reduce的worker程序遍历这些输入文件,传给reduce函数,并输出所需要的文件。
8:所有map,reduce任务完成,master唤醒用户程序,这个时候对Mapreduce的调用才会返回。
这时候虽然完成了,一般还有R个输出文件吧,它们其实也可以作为其他的分布式输入文件,在进行mapreduce的。
其实吧,在map过程中,都还有一定的优化过程:
~会有一个排序的过程
~会将同样的key配到一起,一般情况下是<a,“1”>,<b,“1”>,<c,“1”>,<a,“1”>,但 是这个过程会把a键值整合到一起,<a,{“1”.“1”}>
~还有个过程就是常说的combine过程,实质就是一个本地reduce,将整合的KeyValue值reduce,比如上面的变成了<a,“2”>,这都是可以优化的。
上面的我都只是以wordcount为例。
但是这真的知识个大概过程,具体的需求要设计对应的程序,刚刚也说了,mapreduce只是个编程模型而已,并没有明确怎么做。另外还有一些容错机制,mapreduce技巧,性能等各方面的原因都要考虑,其中很多东西非常复杂。
在看lab1的代码时,我们还是先看看rpc吧。
这是我写的一个简单的rpc目录结构。
ser_file:服务注册文件
在这里插入代码片package math
import "errors"
type Args struct{
A,B float32
}
type Result struct {
Value float32
}
type CountService struct{
fe float32
}
func (s *CountService) add(args *Args,result Result) error{
result.Value=args.A+args.B
return nil
}
func (s *CountService) Divide(args *Args, result *Result) error {
if args.B == 0 {
return errors.New("除数不能为零!")
}
result.Value = args.A / args.B
return nil
}
s