文档章节

hadoop 分布式缓存(转载)

z
 zxwyc
发布于 2014/10/23 10:20
字数 2087
阅读 35
收藏 0

DistributedCache是Hadoop提供的文件缓存工具,它能够自动将指定的文件分发到各个节点上,缓存到本地,供用户程序读取使用。它具有以下几个特点:缓存的文件是只读的,修改这些文件内容没有意义;用户可以调整文件可见范围(比如只能用户自己使用,所有用户都可以使用等),进而防止重复拷贝现象;按需拷贝,文件是通过HDFS作为共享数据中心分发到各节点的,且只发给任务被调度到的节点。本文将介绍DistributedCache在Hadoop 1.0和2.0中的使用方法及实现原理。

Hadoop DistributedCache有以下几种典型的应用场景:1)分发字典文件,一些情况下Mapper或者Reducer需要用到一些外部字典,比如黑白名单、词表等;2)map-side join:当多表连接时,一种场景是一个表很大,一个表很小,小到足以加载到内存中,这时可以使用DistributedCache将小表分发到各个节点上,以供Mapper加载使用;3)自动化软件部署:有些情况下,MapReduce需依赖于特定版本的库,比如依赖于某个版本的PHP解释器,一种做法是让集群管理员把这个版本的PHP装到各个机器上,这通常比较麻烦,另一种方法是使用DistributedCache分发到各个节点上,程序运行完后,Hadoop自动将其删除。

Hadoop提供了两种DistributedCache使用方式,一种是通过API,在程序中设置文件路径,另外一种是通过命令行(-files,-archives或-libjars)参数告诉Hadoop,个人建议使用第二种方式,该方式可使用以下三个参数设置文件:

(1)-files:将指定的本地/hdfs文件分发到各个Task的工作目录下,不对文件进行任何处理;

(2)-archives:将指定文件分发到各个Task的工作目录下,并对名称后缀为“.jar”、“.zip”,“.tar.gz”、“.tgz”的文件自动解压,默认情况下,解压后的内容存放到工作目录下名称为解压前文件名的目录中,比如压缩包为dict.zip,则解压后内容存放到目录dict.zip中。为此,你可以给文件起个别名/软链接,比如dict.zip#dict,这样,压缩包会被解压到目录dict中。

(3)-libjars:指定待分发的jar包,Hadoop将这些jar包分发到各个节点上后,会将其自动添加到任务的CLASSPATH环境变量中。

前面提到,DistributedCache分发的文件是有可见范围的,有的文件可以只对当前程序可见,程序运行完后,直接删除;有的文件只对当前用户可见(该用户所有程序都可以访问);有的文件对所有用户可见。DistributedCache会为每种资源(文件)计算一个唯一ID,以识别每个资源,从而防止资源重复下载,举个例子,如果文件可见范围是所有用户,则在每个节点上,第一个使用该文件的用户负责缓存该文件,之后的用户直接使用即可,无需重复下载。那么,Hadoop是怎样区分文件可见范围的呢?

在Hadoop 1.0版本中,Hadoop是以HDFS文件的属性作为标识判断文件可见性的,需要注意的是,待缓存的文件即使是在Hadoop提交作业的客户端上,也会首先上传到HDFS的某一目录下,再分发到各个节点上的,因此,HDFS是缓存文件的必经之路。对于经常使用的文件或者字典,建议放到HDFS上,这样可以防止每次重复下载,做法如下:

比如将数据保存在HDFS的/dict/public目录下,并将/dict和/dict/public两层目录的可执行权限全部打开(在Hadoop中,可执行权限的含义与linux中的不同,该权限只对目录有意义,表示可以查看该目录中的子目录),这样,里面所有的资源(文件)便是所有用户可用的,并且第一个用到的应用程序会将之缓存到各个节点上,之后所有的应用程序无需重复下载,可以在提交作业时通过以下命令指定:

-files hdfs:///dict/public/blacklist.txt, hdfs:///dict/public/whilelist.txt

如果有多个HDFS集群可以指定namenode的对外rpc地址:

-files hdfs://host:port/dict/public/blacklist.txt, hdfs://host:port/dict/public/whilelist.txt

DistributedCache会将blacklist.txt和whilelist.txt两个文件缓存到各个节点的一个公共目录下,并在需要时,在任务的工作目录下建立一个指向这两个文件的软连接。

如果可执行权限没有打开,则默认只对该应用程序的拥有者可见,该用户所有应用程序可共享这些文件。

一旦你对/dict/public下的某个文件进行了修改,则下次有作业用到对应文件时,会发现文件被修改过了,进而自动重新缓存文件。

对于一些频繁使用的字典,不建议存放在客户端,每次通过-files指定,这样的文件,每次都要经历以下流程:上传到HDFS上—》缓存到各个节点上—》之后不再使用这些文件,直到被清除,也就是说,这样的文件,只会被这次运行的应用程序使用,如果再次运行同样的应用程序,即使文件没有被修改,也会重新经历以上流程,非常耗费时间,尤其是字典非常多,非常大时。

DistributedCache内置缓存置换算法,一旦缓存(文件数目达到一定上限或者文件总大小超过某一上限)满了之后,会踢除最久没有使用的文件。

在Hadopo 2.0中,自带的MapReduce框架仍支持1.0的这种DistributedCache使用方式,但DistributedCache本身是由YARN实现的,不再集成到MapReduce中。YARN还提供了很多相关编程接口供用户调用,有兴趣的可以阅读源代码。

下面介绍Hadoop 2.0中,DistributedCache通过命令行分发文件的基本使用方式:

(1)运行Hadoop自带的example例子, dict.txt会被缓存到各个Task的工作目录下,因此,直接像读取本地文件一样,在Mapper和Reducer中,读取dict.txt即可:

1
2
3
4
5
6
bin     /Hadoop     jar \
share     /hadoop/mapreduce/hadoop-mapreduce-examples-2     .2.0.jar \
wordcount \
-files hdfs:     ///dict/public/dict     .txt \
/test/input     \
/test/output

(2)Hadoop Streaming例子,需要通过-files指定mapper和reducer可执行文件或者脚本文件,这些文件就是通过DistributedCache分发到各个节点上的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
HADOOP_HOME=     /opt/yarn-client
INPUT_PATH=     /test/input/data
OUTPUT_PATH=     /test/output/data
echo     "Clearing output path: $OUTPUT_PATH"
$HADOOP_HOME     /bin/hadoop     fs -rmr $OUTPUT_PATH
 
${HADOOP_HOME}     /bin/hadoop     jar\
        ${HADOOP_HOME}     /share/hadoop/tools/lib/hadoop-streaming-2     .2.0.jar\
       -D mapred.reduce.tasks=2\
       -files mapper,reducer\
       -input $INPUT_PATH\
       -output $OUTPUT_PATH\
       -mapper mapper\
       -reducer reducer

(3)接下给出一个缓存压缩文件的例子,假设压缩文件为dict.zip,里面存的数据为:

1
2
3
4
data     /1     .txt
data     /2     .txt
mapper.list
reducer.list

通过-archives参数指定dict.zip后,该文件被解压后,将被缓存(实际上是软连接)到各个Task的工作目录下的dict.zip目录下,组织结构如下:

1
2
3
4
5
6
dict.zip/
         data/
             1.txt
             2.txt
         mapper.list
         reducer.list

你可以在Mapper或Reducer程序中,使用类似下面的代码读取解压后的文件:

 

1
2
3
File file2 = read(“dict.zip/data/1.txt”, “r”);
…….
File file3 = read(“dict.zip/mapper.list”, “r”);

如果你想直接将内容解压到Task工作目录下,而不是子目录dict.zip中,可以用“-files”(注意,不要使用-archives,“-files”指定的文件不会被解压)指定dict.zip,并自己在程序中实现解压缩:

1
2
3
4
#include <cstdlib>
…….
system     (“unzip –q dict.zip”);     //C++代码
……

总之,Hadoop DistributedCache是一个非常好用的工具,合理的使用它能够解决很多非常困难的问题。

原创文章,转载请注明: 转载自董的博客

本文链接地址: http://dongxicheng.org/mapreduce-nextgen/hadoop-distributedcache-details/

作者:Dong,作者介绍:http://dongxicheng.org/about/

本博客的文章集合:http://dongxicheng.org/recommend/

本文转载自:http://dongxicheng.org/mapreduce-nextgen/hadoop-distributedcache-details/

z
粉丝 0
博文 1
码字总数 0
作品 0
徐汇
私信 提问
hadoop 分布式缓存

Hadoop 分布式缓存实现目的是在所有的MapReduce调用一个统一的配置文件,首先将缓存文件放置在HDFS中,然后程序在执行的过程中会可以通过设定将文件下载到本地具体设定如下: public static ...

云栖希望。
2017/12/04
0
0
从Hadoop框架与MapReduce模式中谈海量数据处理(含淘宝技术架构)

前言 几周前,当我最初听到,以致后来初次接触Hadoop与MapReduce这两个东西,我便稍显兴奋,觉得它们很是神秘,而神秘的东西常能勾起我的兴趣,在看过介绍它们的文章或论文之后,觉得Hadoop是...

白志华
2015/09/19
50
0
Yarn(MapReduce 2.0)下分布式缓存(DistributedCache)的注意事项

1、问题 最近公司的集群从 Apache hadoop 0.20.203 升级到了 CDH 4,迈进了 Hadoop 2.0 的新时代,虽然新一代的 hadoop 努力做了架构、API 上的各种兼容,但总有“照顾不周”的地方,下面说的...

大数据之路
2014/03/08
3.8K
0
Spring Boot 中使用 kafka

Kafka 是一种高吞吐的分布式发布订阅消息系统,能够替代传统的消息队列用于解耦合数据处理,缓存未处理消息等,同时具有更高的吞吐率,支持分区、多副本、冗余,因此被广泛用于大规模消息数据...

PengLei
2017/10/17
0
0
Apache Hadoop 2.3.0 发布

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

fei
2014/02/25
9.7K
17

没有更多内容

加载失败,请刷新页面

加载更多

java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
今天
6
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
5
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
14
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
15
0
jquery--DOM操作基础

本文转载于:专业的前端网站➭jquery--DOM操作基础 元素的访问 元素属性操作 获取:attr(name);$("#my").attr("src"); 设置:attr(name,value);$("#myImg").attr("src","images/1.jpg"); ......

前端老手
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部