Skip to content

tabVersion/URL_counter_mapreduce

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

URL_counter_mapreduce

PingCap interview

使用说明和详设在 usage&design.md

通过修改最大并发数量即可控制内存使用,若每个 map 任务的文件大小为128MB,则允许的最大并发数为8,考虑到每个线程的内部储存使用,允许的最大并发数应为 6~7(为了便于测试,代码中允许的最大并发数为3)

  • 通过修改 GoDistributed 的 nReduce 参数即可更改

题目

100GB url文件,使用1GB内存计算出出现次数top100的url和出现的次数。

架构说明

注:本程序所有的分布式情况均使用多线程进行模拟

  1. 面向用户

    1. 文件输入要求 为多个文件且每个均不超过128MB(数值取自Hadoop2.0)加起来可以达到10GB

    2. map/reduce

      1. map 将每个URL扩展成为{key, value}的键值对,其中key为url本身,value为1表示出现一次。将处理的所有的键值对根据key进行排序并依据reducer的数量进行划分,产生中间文件

      2. reduce 合并相邻的相同的URL,最终其value的值即为这个URL在所有的文件中出现的次数。因为在map阶段对key的集合进行了划分,所以不存在相同的key值分布在不同reducer上的情况。

  2. master 节点
    主线程,同时作为 rpc 线程的主机,负责任务调度和监控,同时。与 worker 节点所有的调用都是通过 rpc 服务进行的,避免了调用失败时阻塞主线程的情况。

  3. RPC
    作为 master 和 worker 的中间层,负责向双方传递消息,所有的 rpc 调用都是异步的。本质是 rpc.Dail 通过双方的 rpc 地址进行信息交换。

  4. worker 节点
    单独的线程,向 rpc 主机进行注册并汇报任务完成情况。对 worker 线程的调用也是异步的。

主调用流程

每日总结

  • 2.12
    明确目标是计算10GB的数据中出现次数top100的URL,但是可用的内存只有1GB,显然需要使用外存,迅速想到之前接触过的mapreduce。在MIT 6.824的课程中曾经进行过word count的实现,且在mapreduce的论文中明确提到这样的技术可以进行URL count 复习了论文并实现了其中单独的 map/reduce 部分和归并函数

  • 2.13
    实现任务调度函数 schedule,建立 rpc 通信并完成 map/reduce 部分和多线程部分的单元测试,成功通过

    • 改进schedule的任务分配部分。取消了任务分配通道(chan)的缓存,通过 channel 类型两方都准备好才发生通信的特性完成任务分配
    • 改进schedule的线程同步部分。通过统计成功完成的任务数量避免使用sync.WaitGroup(),简化程序结构
  • 2.14
    改动map部分以适应本次URL统计的需求。将每个URL作为统计的唯一键值,并生成测试数据,共八个文件,其中每个里面包含10000个随机生成的URL,为确保可以有重复的部分,统一使用3位(https://www.xxx.com)。顺利通过单一worker的测试,生成的数据中出现最多的URL出现了16次,期望为4.55次 在进行分布式测试时发现在schedule中出现死循环,经过go race测试,发现在分配任务到每个worker时稳定出现线程阻塞情况,且每个线程均有相同情况

    • 没有成功debug
  • 2.15
    上午通过打log的方式推测其中call函数在包装 rpc.Dial 时出现问题,在同步调用时因为某些问题导致阻塞,使主线程处于挂起状态,但是在查阅文档后发现此处正常 下午继续尝试发现此处的阻塞产生于registerChan中没有数据导致所有的线程都在等待通道内容(即worker的rpc地址)。 通过调用检测发现此处产生了死锁: 产生于schedule(mapreduce/schedule.go)和forwardRegistrations(mapreduce/master.go)

    • schedule要求有机器地址,待任务完成后将机器重新注册到master处
    • forwardRegistrations要求在master注册的可用机器数量大于0时才会分配机器的地址
    • 解决方案:在schedule进行任务分配之前对所有worker线程在master处进行注册

    ===> 不仅要关注函数的运行时情况,还要关注初始化

  • 2.16
    完成所有代码部分并通过分布式的测试
    反思: 在构建分布式情况的函数 Distributed 时,将过多的关注放在了 schedule 部分,忘记了在分配任务后开启 worker,导致在请求 worker 的 rpc地址时出现线程阻塞
    完善文档

  • 2.17
    完成使用说明和详设的文档,开始写架构说明部分

  • 2.18
    完成全部文档,包括 readme 和 代码注释

    • 添加了 CI

About

for pingcap interview

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published