【Hadoop】基础概念2

Hadoop简单介绍

Hadoop,你是怎么来的?

今天的社会产生越来越多的数据,比如:你登录Facebook以后点击了哪些好友,你在Amazon上浏览了哪些产品,你在linkedin上浏览了哪些公司,甚至到从石油矿井里的钻头收集了哪些地质信息。

我们还发现,通过分析这些数据总结规律,我们可以让Facebook和Amazon显示让用户更感兴趣的广告,公司HR会更准确找到合适的求职者,石油公司也能用更低的成本开采更多的石油。

那找个软工写算法不就行了吗?

确实,这些决策都是通过算法找到规律的。可问题是现在的数据量太大了,一台机器要完成一个问题要算好久好久

那用多台机器处理不就行了吗?

确实,Hadoop以及其他任何大数据框架都是多台机器共同处理的。可问题是,这些算法都要完成一个特定的问题,给出一个答案,多台机器不能自己算自己的,他们要有不同的分工,联合起来共同算完这个问题。这里就是Hadoop等框架的特长。

我们举个例子吧:wordcount!

Google是大家常用的搜索引擎,作为业务的重要特征,它自然想知道大家对哪些关键字感兴趣,比如以天为单位,收集所有人搜过的关键字,统计其出现的次数。

这听起来像个哈希表就能干的问题对吧?可是,每天那么多人使用Google,它不可能把这些关键字都放在内存里,而且Google也是用很多服务器为大家完成搜索的,所以一天里所有搜过的关键字,都以文件的形式存在多台机器上。我们就叫这些机器1, 2, 3......n.

比如在机器1上存储了一个文件,内容是所有搜过的关键字:Deer, Bear, River …...

既然Log文件存放在多台机器中,那如何计算关键字出现的总次数呢?

一种直观的算法,就是先让每台机器统计本机上每个关键字的搜索次数,写段算法统计一个文件里的关键字很简单。比如机器1的处理结果为:

  • Deer 150000

  • River 110000

  • Car 100000

(参见图1的mapping)

注意到这里,每台机器知道的是本机上关键字的搜索次数,而我们关心的是所有机器上的关键字的搜索总次数。

那下一步再找一组机器,不妨称其为:A, B, C, D......

每台机器只统计一部分关键字出现在所有机器上的总次数,比如:

  • 让机器A统计 在机器1, 2, 3.......n上“Bear”出现的总次数;

  • 让机器B统计,在机器1, 2, 3.......n上“Car”出现的总次数;

  • 让机器C统计,在机器1, 2, 3.......n上“Deer”出现的总次数;

  • 让机器D统计,在机器1, 2, 3......n上“River”出现的总次数;

(参见图1的reducing)

这样,当A, B, C, D......完成自己的任务以后,我们就知道每个关键字在过去一天出现的次数了。

所以每台机器不但要计算自己的任务,还要和其他机器「合作」,在我们刚才的例子里就是机器A, B, C, D......要从机器1, 2, 3, 4......那里知道关键字的出现次数,而且,A, B, C, D.....还要沟通好,分别统计不同的关键字,即不能两台机器都统计同一个关键字,也不能有的关键字没有机器统计。

计算搜索引擎关键字出现次数的例子,就是一个使用Hadoop的经典案例。像我们刚才说的,大数据计算非常复杂,各个机器之间要协调工作。但是,当总结常用的大数据算法后,我们发现他们有一定的共同点(稍后介绍),很多算法都要做一些类似的工作。既然有共同点,我们就没有必要重造轮子。这些类似的工作可以做成Framework,以后再开发类似大数据分析软件可以重用这些Framework的功能。Hadoop就是这样一个Framework,它来源于Google一篇关于MapReduce的Paper.

那Hadoop总结了算法的哪些共同点呢?

那篇MapReduce Paper的作者发现,很多计算,就比如我们刚才的例子,都可以拆分成Map, Shuffle, Reduce三个阶段:

  • Map阶段中,每台机器先处理本机上的数据,像图1中各个机器计算本机的文件中关键字的个数。

  • 各个机器处理完自己的数据后,我们再把他们的结果汇总,这就是Shuffle阶段,像刚才的例子,机器A, B, C, D......从1-n所有机器上取出Map的结果,并按关键字组合。

  • 最后,进行最后一步处理,这就是Reduce,我们刚才的例子中就是对每一个搜索关键字统计出现总次数。

这几步我们就称为MapReduce Model。

为了完成MapReduce Model的计算,实际开发的软件需要一些辅助的功能。想像一下,起始时的一组机器上面存储了要处理的数据,但是Map, Shuffle, Reduce阶段的Function在哪儿呢?所以我们需要把Mapper Function, Reducer Function (Java code或者其他语言的code) 安装在机器 1-n 和A-Z上,并且执行。而且在Map阶段以后,计算结果保存在本机上,没办法Shuffle到Reduce的机器上。所以,也需要有软件按照Shuffle算法,把Mapper Function的结果搬运到Reduce阶段的机器上。

运行整个Hadoop Job的流程中,很多工作对于所有算法都是需要的,不同的算法只是Mapper Function和Reducer Function. 换句话说,Hadoop实现了通用的功能,开发人员只需要告诉Hadoop需要执行的Mapper, Reducer Function,就可以完成想要的计算,而不需要开发所有步骤。

word count的python代码(感觉网上挺少的)

map.py

import os
import sys

for line in sys.stdin:
        fields = line.strip().split('\t')
        date = fields[1]
        print date + "\t1" + [所要的字段]

reduce.py

import os
import sys

pre_key = ""
for line in sys.stdin:
        fields = line.strip().split('\t')
        key = fields[0]
        val = int(fields[1])
        if key == pre_key:
                count += val
        else:
                if pre_key == "":
                        count = val
                        pre_key = key
                else:
                        print pre_key + "," + str(count)
                        count = val
                        pre_key = key

print pre_key + "," + str(count)

运行的shell

 

Hadoop Streaming 实例

# 读取地址,数据集的存放路径
INPUT='afs://公司隐私/zhengxin/zx_join'
# 读取结果的存放地址,自己集群里的一个目录
OUTPUT='afs://个人隐私/myname/test'
#
REDUCE_NUM=50
# Hadoop在我的集群上的位置
HADOOP_CMD="/home/myname/companyname-client/hadoop-client/hadoop/bin/hadoop"
#PYTHON_BIN="/user/fpd_dm/tools/Python-2.7.5.tar.gz"

# 若是输出路径存在,则再运行的时候递归删除输出目录
$HADOOP_CMD fs -rmr ${OUTPUT}
# 
$HADOOP_CMD streaming \
    -D mapred.job.name="companyname_development_myname" \
    -D mapred.reduce.tasks=${REDUCE_NUM} \
    -D mapred.map.tasks=100 \
    -D mapred.job.map.capacity=100 \
    -D mapred.job.reduce.capacity=100 \
    -D mapred.job.priority=HIGH\
    -D stream.memory.limit=8000 \
    -D abaci.split.remote=false \
    -D num.key.fields.for.partition=1 \
# 自己编写的满足读取要求的map文件
    -file map.py \
# 自己编写的满足要求的reduce文件,若我只是从集群上下载数据集的某些字段,则这里删掉
    -file red.py \
    -input ${INPUT}  \
    -output ${OUTPUT} \
    -mapper "python map.py" \
# -file red.py文件删掉的话,这里要设置为-reducer "none"
    -reducer "python red.py"
~

从数据库上读取若干字段

hadoop运行原理之shuffle

请描述一下Hadoop的shuffle过程

 hadoop的核心思想是MapReduce,但shuffle又是MapReduce的核心。shuffle的主要工作是从Map结束到Reduce开始之间的过程。首先看下这张图,就能了解shuffle所处的位置。图中的partitions、copy phase、sort phase所代表的就是shuffle的不同阶段。

shuffle阶段又可以分为Map端的shuffle和Reduce端的shuffle。

  一、Map端的shuffle

  Map端会处理输入数据并产生中间结果,这个中间结果会写到本地磁盘,而不是HDFS。每个Map的输出会先写到内存缓冲区中,当写入的数据达到设定的阈值时,系统将会启动一个线程将缓冲区的数据写到磁盘,这个过程叫做spill。

  在spill写入之前,会先进行二次排序,首先根据数据所属的partition进行排序,然后每个partition中的数据再按key来排序。partition的目是将记录划分到不同的Reducer上去,以期望能够达到负载均衡,以后的Reducer就会根据partition来读取自己对应的数据。接着运行combiner(如果设置了的话),combiner的本质也是一个Reducer,其目的是对将要写入到磁盘上的文件先进行一次处理,这样,写入到磁盘的数据量就会减少。最后将数据写到本地磁盘产生spill文件(spill文件保存在{mapred.local.dir}指定的目录中,Map任务结束后就会被删除)。

  最后,每个Map任务可能产生多个spill文件,在每个Map任务完成前,会通过多路归并算法将这些spill文件归并成一个文件。至此,Map的shuffle过程就结束了。

  二、Reduce端的shuffle

  Reduce端的shuffle主要包括三个阶段,copy、sort(merge)和reduce。

  首先要将Map端产生的输出文件拷贝到Reduce端,但每个Reducer如何知道自己应该处理哪些数据呢?因为Map端进行partition的时候,实际上就相当于指定了每个Reducer要处理的数据(partition就对应了Reducer),所以Reducer在拷贝数据的时候只需拷贝与自己对应的partition中的数据即可。每个Reducer会处理一个或者多个partition,但需要先将自己对应的partition中的数据从每个Map的输出结果中拷贝过来。

  接下来就是sort阶段,也称为merge阶段,因为这个阶段的主要工作是执行了归并排序。从Map端拷贝到Reduce端的数据都是有序的,所以很适合归并排序。最终在Reduce端生成一个较大的文件作为Reduce的输入。

  最后就是Reduce过程了,在这个过程中产生了最终的输出结果,并将其写到HDFS上。

  现在来总结一下shuffle过程,我画了张图,希望能够帮助理解。

Hadoop中MR是怎么实现联表查询的?

 

来源:

Joseph Holy

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值