卿哥原创,转载请注明出处,谢谢

之前已经作出预告,那么今天就聊聊mapreduce,起源于Google的map reduce paper, 而后经历了mapreduce 1,和构建于yarn上的mapreduce 2,mapreduce1 除了提供一定的历史演变价值和了解一下mapreduce最初的设计之外就没有必要学了哈,毕竟现在意义上的mapreduce2,spark都是在yarn上。当然mapreduce这项技术本身可能现在也是逐年衰落,不是我说的,是michael stonebraker3年前就说了(stonebraker认为程序员只需要了解sql就行了,nosql啥的都应该直接或间接支持用sql来查询交互),而且google自己也早就不用了,不过mapreduce还是有自身一定的学习价值,比如map, combiner, shuffle/sort, practiioner, reducer,消息传递, data locality(即把运算移动到数据旁,而不是传输数据来节省网络带宽提高运算效率)都是分布式系统运算框架的一个里程碑。很多分布式系统设计课程比如MIT研究生著名的分布式系统设计的前几章必然要讲mapreduce。

分布式系统前言

分布式系统由于包括很多node,所以它的根基是unreliable component包括node,network和clock,上层的设计必然需要考虑到这一点。Unreliable node有如下三种表现形式:

  • fail-stop, 比如电力供应中断了(比如data center停电了,或者地震了发水灾了啥的),fail了就完了,无法恢复。
  • fail-recovery,比如node升级kernel,os,software,需要重启
  • 拜占庭 failure,这个比较狠,就是这个node看似正常,但是你说城门楼子它说胯骨轴子,你说往东,它往西走。相当于一个神经错乱的node或者说是被入侵了的node。

同时分布式系统涉及大量的网络传输,不管是RPC还是RESTFUL都是走网络,网络也是unreliable的,有如下三种表现形式:

  • 完美传输,即%0 loss, 100% in order,俗称happy home,这个资源成本比较高,适用于特别重要的服务
  • fair-loss, 这个最为常见,就是正常丢包,不已传输内容为转移。TCP/IP就是为了解决这个事儿而设计了3 way handshake,retry,sliding window,congestion control啥的
  • 拜占庭 failure,这个就基本相当于被man in the middle 了,anything is possible,good luck :)思考题:SSL/TLS 能有效解决man in the middle吗?

还没完,分布式系统还有一个问题就是clock,一方面每台机器的时间都可能不一样,俗称clock skew,另一方面,每台机器对每一秒的感知也不一样,俗称clock drift。所以伟大的lamport(2013图灵奖得主,分布式大神,latex,vector clock,paxos,etc)发明了logical clock,其中最著名的是vector clock。相当于让每个event有了自己的先后顺序。这个可以单独聊一次它的具体原理。插一句嘴,我觉得分布式系统这么多年敢称大神的只有两个,理论大师lamport和实战天王Jeff Dean(Jeff Dean当年在MIT淡定的给我们介绍谷歌分布式系统设计经验,然后说自己一个周末现学maching learning,搞出了个猫图片识别,当时我就在想他学machine learning干啥,然后tensor flow这个项目就横空出世了。。。orz)

还有就是分布式系统实现分为synchronous和asynchronous两种model,synchronous就是blocking callback with optional timeout,asynchronous就是event call back with optional timeout。

下面我们把以上几种情形组合一下:

  • fail-stop + 完美传输 + synchronous,比如超级计算机每个processor由local high speed bus相连,user case是OpenMP 和 MPI
  • fail-recovery + fair-loss + asynchronous,就是我们最近一直聊的hadoop eco system了
  • 拜占庭 node + 拜占庭网络+asynchronous,这就是分布于untrusted computer和untrusted network之中的grid computing了

map

先看一下python的map function,接下来会聊hadoop streaming

  1. >>> map(lambda x: x*x, [1,2,3,4,5])
  2. [1, 4, 9, 16, 25]
  3.  
  4. or>>> items = (1,2,3,4,5)
  5.  
  6. >>> def sqr(x): return x**2>>> map(sqr,items)
  7.  
  8. [1, 4, 9, 16, 25]

reduce

先看一下python的reduce function

  1. >>> reduce(operator.iadd, [1,4,9,16,25])
  2. 55
  3.  
  4. or
  5.  
  6. >>> reduce(lambda x,y: x+y, [1,4,9,16,25])
  7. 55

data flow

map 和 reduce的input/output都是key/value pair。注意map或者reduce不一定都需要,比如grep,map=grep,reduce=None

在sort和shuffling阶段,sorting用的是external sorting,所以不用担心内存爆了。

实现

上图中,intermidiate result是存放在local disk中而不是HDFS,因为就算丢了,也可以通过map重新得到,所以不用使用HDFS做multiple copy。

上图可以看出yarn分为resource manager和node manager,resource manager会launch application master,application master会请求resource根据resource富余程度launch application process。

下面这张图也是这个意思:

具体来说,input data会被Hadoop切割为固定大小的input splits,Hadoop 会为每个split creates一个map task,map task会对split中的每一个record运行user-defined map function. 对于大部分job来说,a good split size是一个HDFS block,128MB。Hadoop尽量通过data locality optimization来让map task运行在存有input data的节点上。如果不行,就选择同一个rack上的其它node,如果还不行,就选择旁边rack上的node。

reduce就没有data locality一说了,input都是通过网络传过去的。这中间还会有一个shuffle&&sort的过程,通常就是通过一个hash function来把相同的key放在一起,保证对于每一个given key来说,所有的records都在一个partition里。所以当reducer处理的时候可以保证input data都是按照key sorting好的了。

Hadoop Streaming

首先,说说distributed cache, 比如你有个文件需要在运算的时候用到如何传给map/reduce task呢?答,是通过-files/-archives/-libjars 传过去的,比如-files mapper.py, reducer.py, some_file.txt, 此时some_file.txt会被传到需要的node上,每个node只需要一个copy,注意some_files.txt是read only的,所以可以被tasks共享。 archives是打包传输,libjars是传jar格式。

following method 可以创建archive文件:

  1. tar -cf pack.tar a.txt b.txt c.txt

读的时候就用如下path:

  1. pack.tar/a.txtpack.tar/b.txt, pack.tar/c.txt

其次,说说environment variable, hadoop streaming可以通过-D some_var="some value"的方式把变量传给nodes。

第三,从task的角度可以通过reporter:status: 的方式把report传回去。

下面举个word count的实际例子,比如统计wikipedia的word count:

mapper.py

  1. #!/usr/bin/python
  2.  
  3. import sys
  4. import re
  5.  
  6. reload(sys)
  7. sys.setdefaultencoding('utf-8') # required to convert to unicode
  8.  
  9. for line in sys.stdin:
  10. try:
  11. article_id, text = unicode(line.strip()).split('\t', 1)
  12. except ValueError as e:
  13. continue
  14. words = re.split("\W*\s+\W*", text, flags=re.UNICODE)
  15. for word in words:
  16. print "%s\t%d" % (word.lower(), 1)

reducer.py

  1. #!/usr/bin/python
  2.  
  3. import sys
  4.  
  5. current_key = None
  6. word_sum = 0
  7.  
  8. for line in sys.stdin:
  9. try:
  10. key, count = line.strip().split('\t', 1)
  11. count = int(count)
  12. except ValueError as e:
  13. continue
  14. if current_key != key:
  15. if current_key:
  16. print "%s\t%d" % (current_key, word_sum)
  17. word_sum = 0
  18. current_key = key
  19. word_sum += count
  20.  
  21. if current_key:
  22. print "%s\t%d" % (current_key, word_sum)

本机运行:

  1. cat wiki.txt | ./mapper.py | sort | ./reducer.py

Hadoop streaming:

  1. OUT_DIR="wiki_wordcount_result_"$(date +"%s%6N")
  2. NUM_REDUCERS=
  3.  
  4. hdfs dfs -rm -r -skipTrash ${OUT_DIR} > /dev/null
  5.  
  6. yarn jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/hadoop-streaming.jar \
  7. -D mapred.jab.name="Streaming wordCount" \
  8. -D mapreduce.job.reduces=${NUM_REDUCERS} \
  9. -files mapper.py,reducer.py \
  10. -mapper "python mapper.py" \
  11. -combiner "python reducer.py" \
  12. -reducer "python reducer.py" \
  13. -input /wiki/en_articles_part \
  14. -output ${OUT_DIR} > /dev/null

好了,今天就写到这,happy mapreduce!

深入浅出Hadoop之mapreduce的更多相关文章

  1. 升级版:深入浅出Hadoop实战开发(云存储、MapReduce、HBase实战微博、Hive应用、Storm应用)

          Hadoop是一个分布式系统基础架构,由Apache基金会开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力高速运算和存储.Hadoop实现了一个分布式文件系 ...

  2. 从Hadoop骨架MapReduce在海量数据处理模式(包括淘宝技术架构)

    从hadoop框架与MapReduce模式中谈海量数据处理 前言 几周前,当我最初听到,以致后来初次接触Hadoop与MapReduce这两个东西,我便稍显兴奋,认为它们非常是神奇.而神奇的东西常能勾 ...

  3. Hadoop 新 MapReduce 框架 Yarn 详解

    Hadoop 新 MapReduce 框架 Yarn 详解: http://www.ibm.com/developerworks/cn/opensource/os-cn-hadoop-yarn/ Ap ...

  4. 用PHP编写Hadoop的MapReduce程序

    用PHP编写Hadoop的MapReduce程序     Hadoop流 虽然Hadoop是用Java写的,但是Hadoop提供了Hadoop流,Hadoop流提供一个API, 允许用户使用任何语言编 ...

  5. Hadoop之MapReduce程序应用三

    摘要:MapReduce程序进行数据去重. 关键词:MapReduce   数据去重 数据源:人工构造日志数据集log-file1.txt和log-file2.txt. log-file1.txt内容 ...

  6. 对于Hadoop的MapReduce编程makefile

    根据近期需要hadoop的MapReduce程序集成到一个大的应用C/C++书面框架.在需求make当自己主动MapReduce编译和打包的应用. 在这里,一个简单的WordCount1一个例子详细的 ...

  7. Hadoop基础-MapReduce入门篇之编写简单的Wordcount测试代码

    Hadoop基础-MapReduce入门篇之编写简单的Wordcount测试代码 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本文主要是记录一写我在学习MapReduce时的一些 ...

  8. Hadoop基础-MapReduce的常用文件格式介绍

    Hadoop基础-MapReduce的常用文件格式介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MR文件格式-SequenceFile 1>.生成SequenceF ...

  9. Hadoop基础-MapReduce的Join操作

    Hadoop基础-MapReduce的Join操作 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.连接操作Map端Join(适合处理小表+大表的情况) no001 no002 ...

随机推荐

  1. mysql习题

    如图表创建数据库. create table class( cid int auto_increment primary key, caption ) )engine=innodb default c ...

  2. 浏览器与CDN缓存行为

    @地址栏回车 1. 未过期: 浏览器拦截,直接返回: (expires/cache-control两个参数决定,如果两个参数都有,cache-control覆盖expires); 2. 已过期: et ...

  3. Tp框架查询分页显示与全部查询出来显示运行时间快慢有区别吗?

    8:08:01 青春阳光 2017/4/7 8:08:01 大神在吗? Tp框架查询分页显示与全部查询出来显示运行时间快慢有区别吗? 青春阳光 2017/4/7 8:08:20 还有个问题,上传到pu ...

  4. Python3 的数据类型

    Python3 的数据类型 整形,浮点型,布尔类型 类型转换 int() 整形 采用截断的方式即向下取整,比如 a=5.5 int (a) 返回值为5 怎样才能使int()按照"四舍五入&q ...

  5. php的底层原理

    PHP说简单,但是要精通也不是一件简单的事.我们除了会使用之外,还得知道它底层的工作原理. PHP是一种适用于web开发的动态语言.具体点说,就是一个用C语言实现包含大量组件的软件框架.更狭义点看,可 ...

  6. python通过scapy模块进行arp断网攻击

    前言: 想实现像arpsoof一样的工具 arp断网攻击原理: 通过伪造IP地址与MAC地址实现ARP欺骗,在网络发送大量ARP通信量.攻击者 只要持续不断发送arp包就能造成中间人攻击或者断网攻击. ...

  7. eclipse导入web项目变成java项目解决办法

    右键工程,properties-> Project Facets-> 点convert to faceted..连接 -> 把Dynamic Web Moudle勾上

  8. Appium移动自动化测试之—基于java的iOS环境搭建

    本文仅供参考,同时感谢帮助我搭建环境的同事 操作系统的名称:Mac OS X操作系统的版本:10.12.6 接下来我们开始踏上搭建Appium+java+ios之路,本文只说个大概,毕竟本机已经装过了 ...

  9. I like NetWorld

    liangfengbo.com ibobobo.com https.net.cn bobobo.com.cn scode.net scode.cc liangbolin.com linhe.cc li ...

  10. java项目导出war包

    @参考文档 假如项目名称为yanan,进入到yanan目录下打开cmd 执行:jar -cvf yanan.war ./* 命令详解: @参考文档1 @参考文档2 jar:jar工具是个java应用程 ...