基于浏览器的 MapReduce

简介: 本文讲的是基于浏览器的 MapReduce,在分布式计算和海量数据中摸爬滚打了很久之后,你一定会感谢优雅的 Google Map-Reduce 框架。它的 map ,emit 和 reduce模块既通用又简洁,这使它成为了一个强有力的工具。
本文讲的是基于浏览器的 MapReduce,

在分布式计算和海量数据中摸爬滚打了很久之后,你一定会感谢优雅的 Google Map-Reduce 框架。它的 map ,emit 和 reduce模块既通用又简洁,这使它成为了一个强有力的工具。虽然 Google 公开了理论,但是底层的软件实现仍然是闭源的,而这可以说是他们最大的竞争优势之一(GFSBigTable,等等)。当然,现在有很多开源的分支(Apache HadoopDiscoSkynet,以及其他),但是人们总会发现,优美简洁的理论和惨痛的实现之间存在的断层:诸如自定义协议,自定义服务器,文件系统,冗余,等等等等。问题来了,我们怎样能把这个差距缩短一点?

大规模并行计算

在我和 Michael Nielsen 进行了多次迭代、试错、深入的对话之后,一个念头突然闪现出来: HTTP + Javascript!如果简单的通过浏览器打开一个 URL 就能为计算任务( Map-Reduce )做贡献会怎样?你的社交网络肯定不会介意多开一个后台 tab 帮你压缩一两个数据集!

 与其关注高吞吐率的专有协议和高效的数据通道来分发和传递数据,我们可以用实战检验过的方法: HTTP 和你喜欢的浏览器。而且全世界还有无数的 Javascript 处理器 ——每个浏览器都可以执行。比起其他语言,它是一个完美的数据处理平台。

Google 据说有数以百万计的服务器(而且还在猛增),这是一个惊人的数量。那想要组织一百万人,把他们的零碎计算时间贡献到其中该有多难?我认为这并不是难以实现的,毕竟开始的门槛很低。如果能做到,虽然计算的效率会很低,不过我们会得到一个超大的集群,可以让我们解决一些以前完全做不到的问题。

浏览器中的客户端计算

除了数据的存储和分发,计算任务中最重要的一块就是 CPU 时间。但是,通过把数据分割成可管理的小块,我们可以很容易构造一个基于 HTTP 的工作流,让用户的浏览器为我们处理这些事:

整个过程包括简单的 4 步。首先,客户端向追踪计算进度的 job 服务器申请加入集群。然后服务器分配一个工作单元,把客户端重定向(例如 301 HTTP Redirect)到一个包含数据和 Javascript map/reduce 方法的 URL。下面是一个简单的分布式 word-count 示例:

<html>
  <head>
    <script type="text/javascript">

      function map() {
        /* count the number of words in the body of document */
        var words = document.body.innerHTML.split(/\n|\s/).length;
        emit('reduce', {'count': words});
      }

      function reduce() {
        /* sum up all the word counts */
        var sum = 0;
        var docs = document.body.innerHTML.split(/\n/);
        for each (num in docs) { sum+= parseInt(num) > 0 ? parseInt(num) : 0 }
        emit('finalize', {'sum': sum});
      }

      function emit(phase, data) { ... }
    </script>
  </head>

  <body onload="map();">
    ... DATA ...
  </body>
</html>

一旦页面加载和 Javascript 被执行之后(因为有了 Javascript VM wars,这个过程越来越快了),结果被发回( POST )job 服务器,上述过程不断重复,直到所有任务( map 和 reduce )完成。所以加入集群只需要简单的打开一个 URL,而分发由 HTTP 协议完成。

用 Ruby 写一个简单的 job 服务器

最后的一块拼图是 job 服务器,用来协调分发的工作流。借助 Sinatra web framework ,只需要如下 30 行 Ruby 代码:

require "rubygems"
require "sinatra"

configure do
  set :map_jobs, Dir.glob("data/*.txt")
  set :reduce_jobs, []
  set :result, nil
end

get "/" do
  redirect "/map/#{options.map_jobs.pop}" unless options.map_jobs.empty?
  redirect "/reduce"                      unless options.reduce_jobs.empty?
  redirect "/done"
end

get "/map/*"  do erb :map,    :file => params[:splat].first; end
get "/reduce" do erb :reduce, :data => options.reduce_jobs;  end
get "/done"   do erb :done,   :answer => options.result;     end

post "/emit/:phase" do
  case params[:phase]
  when "reduce" then
    options.reduce_jobs.push params['count']
    redirect "/"

  when "finalize" then
    options.result = params['sum']
    redirect "/done"
  end
end

# To run the job server:
# > ruby job-server.rb -p 80

bmr-wordcount - 浏览器 Map-Reduce: word-count 示例

就这些。启动服务器然后在浏览器里打开 URL 。剩下的完全自动化,并且很容易并行 —— 打开更多的浏览器就好了。加上一些负载均衡,数据库,它就真的可以干活了,很酷吧。





原文发布时间为:2016年09月12日

本文来自云栖社区合作伙伴掘金,了解相关信息可以关注掘金网站。
目录
相关文章
|
Web App开发 存储 前端开发
浏览器原理 01 # Chrome架构:仅仅打开了1个页面,为什么有4个进程?
浏览器原理 01 # Chrome架构:仅仅打开了1个页面,为什么有4个进程?
400 0
浏览器原理 01 # Chrome架构:仅仅打开了1个页面,为什么有4个进程?
|
JavaScript 前端开发 API
浏览器原理 27 # WebComponent
浏览器原理 27 # WebComponent
156 0
浏览器原理 27 # WebComponent
|
存储 移动开发 缓存
浏览器存储
WebApp 优异的性能表现,要归功于浏览器存储技术的广泛应用——这其中除了我们上节提到的缓存,本地存储技术也功不可没。
238 42
|
消息中间件 Web App开发 JavaScript
「web浏览器」通过 rAF,聊聊浏览器的任务调度
本文主要介绍浏览器相关知识点,通过 rAF,了解浏览器的任务调度。
423 0
|
存储 移动开发 缓存
|
Windows
如何在浏览器上在线看hdfs的数据
如何在浏览器上在线看hdfs的数据
291 0
如何在浏览器上在线看hdfs的数据
|
Web App开发 缓存 前端开发
浏览器工作原理和实践(一)——浏览器
  《浏览器工作原理与实践》是极客时间上的一个浏览器学习系列,在学习之后特在此做记录和总结。
浏览器工作原理和实践(一)——浏览器
html+css实战93-浏览器效果
html+css实战93-浏览器效果
108 0
html+css实战93-浏览器效果
html+css实战3-了解-初识-浏览器
html+css实战3-了解-初识-浏览器
97 0
html+css实战3-了解-初识-浏览器
|
Web App开发 JavaScript Java
推荐一个好用的浏览器记笔记工具
不知道大家平常在浏览网页的过程中,对比较重要的内容,有没有记笔记的习惯。强哥在阅读比如SpringBoot等项目的官方文档,或者是看到一些比较好的博客文章时,都比较喜欢做一些笔记。
推荐一个好用的浏览器记笔记工具