9.3.1 map端连接- DistributedCache分布式缓存小数据集
1.1.1 map端连接- DistributedCache分布式缓存小数据集
当一个数据集非常小时,可以将小数据集发送到每个节点,节点缓存到内存中,这个数据集称为边数据。用map函数将小数据集中的数据按键聚合到大的数据集中,输出连接数据集,进行连接操作。
(1) 分布式缓存指定缓存文件
执行命令行时,采用hadoop jar hadoop-example.jar MapSideJoinMain -files input/cityfile/tb_dim_city.dat input/data/all output
-files input/cityfile/tb_dim_city.dat指定需要缓存的文件,会被复制到各个节任务点。
(2)指定缓存文件的三种类型
Hadoop 命令行选项中,有三个命令可以实现文件复制分发到任务的各个节点。用户启动一个作业,Hadoop 会把由 -files、-archives、和 -libjars 等选项所指定的文件复制到分布式文件系统之中,任务运行前,节点管理器从分布式文件系统中复制文件到本地。
1) -files 选项指定待分发的文件,文件内包含以逗号隔开的 URL 列表。文件可以存放在本地文件系统、HDFS、或其它 Hadoop 可读文件系统之中。 如果尚未指定文件系统,则这些文件被默认是本地的。即使默认文件系统并非本地文件系统,这也是成立的。
2) -archives 选项向自己的任务中复制存档(压缩)文件,比如JAR 文件、ZIP 文件、tar 文件和 gzipped tar文件,这些文件会被解档到任务节点。
3) -libjars 选项把 JAR 文件添加到 mapper 和 reducer 任务的类路径中。如果作业 JAR 文件并非包含很多库 JAR 文件,这点会很有用。
(3)缓存文件删除机制
节点管理器为缓存中的文件各维护一个计数器,任务运行时,文件计数器加1,任务完成后,计数器减1,计数器为0时才能删除文件,当节点缓存容量大于一定值(yarn.nodemanger.localizer.cache.target-size-mb设置,默认10GB),才会删除最近最少使用的文件。
(4)Job的分布式缓存API
除了可以用命令行参数指定缓存文件外,还以通过Job的API指定缓存文件;即通过job对象调用下面的函数设置缓存文件。
//以下两组方法将文件或存档添加到分布式缓存
public void addCacheFile(URI uri);
public void addCacheArchive(URI uri);
//以下两组方法将一次性向分布式缓存中添加一组文件或存档
public void setCacheFiles(URI[] files);
public void setCacheArchives(URI[] archives);
//以下两组方法将文件或存档添加到 MapReduce 任务的类路径
public void addFileToClassPath(Path file);
public void addArchiveToClassPath(Path archive);
public void createSymlink();
(6)DistributedCache缓存小数据集实现hadoop map端连接实例
下面的实例是将城市名称的数据集和用户信息的数据集进行连接,城市名称的数据集很小,而用户信息的数据集很大,所以可以采用缓存文件的方式,将城市信息数据集发送到任务,map任务通过setup方法从缓存中读取小数据集文件tb_dim_city.dat,在内存中形成map映射,map函数处理用户信息数据,根据用户信息中的城市id去map映射中找到城市名称,然后合并输出。
- package Temperature;
- import java.io.BufferedReader;
- import java.io.FileReader;
- import java.io.IOException;
- import java.util.HashMap;
- import org.apache.hadoop.conf.Configuration;
- import org.apache.hadoop.conf.Configured;
- import org.apache.hadoop.filecache.DistributedCache;
- import org.apache.hadoop.fs.Path;
- import org.apache.hadoop.io.Text;
- import org.apache.hadoop.mapreduce.Job;
- import org.apache.hadoop.mapreduce.Mapper;
- import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
- import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
- import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
- import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
- import org.apache.hadoop.util.Tool;
- import org.apache.hadoop.util.ToolRunner;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- /**
- *
- * 用途说明:
- * Map side join中的left outer join
- * 左连接,两个文件分别代表2个表,连接字段table1的id字段和table2的cityID字段
- * table1(左表):tb_dim_city(id int,name string,orderid int,city_code,is_show),
- * 假设tb_dim_city文件记录数很少,tb_dim_city.dat文件内容,分隔符为"|":
- * id name orderid city_code is_show
- * 0 其他 9999 9999 0
- * 1 长春 1 901 1
- * 2 吉林 2 902 1
- * 3 四平 3 903 1
- * 4 松原 4 904 1
- * 5 通化 5 905 1
- * 6 辽源 6 906 1
- * 7 白城 7 907 1
- * 8 白山 8 908 1
- * 9 延吉 9 909 1
- * -------------------------风骚的分割线-------------------------------
- * table2(右表):tb_user_profiles(userID int,userName string,network string,double flow,cityID int)
- * tb_user_profiles.dat文件内容,分隔符为"|":
- * userID network flow cityID
- * 1 2G 123 1
- * 2 3G 333 2
- * 3 3G 555 1
- * 4 2G 777 3
- * 5 3G 666 4
- * -------------------------风骚的分割线-------------------------------
- * 结果:
- * 1 长春 1 901 1 1 2G 123
- * 1 长春 1 901 1 3 3G 555
- * 2 吉林 2 902 1 2 3G 333
- * 3 四平 3 903 1 4 2G 777
- * 4 松原 4 904 1 5 3G 666
- */
- public class MapSideJoinMain extends Configured implements Tool{
- private static final Logger logger = LoggerFactory.getLogger(MapSideJoinMain.class);
- public static class LeftOutJoinMapper extends Mapper {
- private HashMap city_info = new HashMap<String,String>();
- private Text outPutKey = new Text();
- private Text outPutValue = new Text();
- private String mapInputStr = null;
- private String mapInputSpit[] = null;
- private String city_secondPart = null;
- /**
- * 此方法在每个task开始之前执行,这里主要用作从DistributedCache
- * 中取到tb_dim_city文件,并将里边记录取出放到内存中。
- */
- @Override
- protected void setup(Context context)
- throws IOException, InterruptedException {
- BufferedReader br = null;
- //获得当前作业的DistributedCache相关文件
- Path[] distributePaths = DistributedCache.getLocalCacheFiles(context.getConfiguration());
- String cityInfo = null;
- for(Path p : distributePaths){
- if(p.toString().endsWith("tb_dim_city.dat")){
- //读缓存文件,并放到mem中
- br = new BufferedReader(new FileReader(p.toString()));
- while(null!=(cityInfo=br.readLine())){
- String[] cityPart = cityInfo.split("\\|",5);
- if(cityPart.length ==5){
- city_info.put(cityPart[0], cityPart[1]+"\t"+cityPart[2]+"\t"+cityPart[3]+"\t"+cityPart[4]);
- }
- }
- }
- }
- }
- /**
- * Map端的实现相当简单,直接判断tb_user_profiles.dat中的
- * cityID是否存在我的map中就ok了,这样就可以实现Map Join了
- */
- protected void map(Object key, Text value, Context context)
- throws IOException, InterruptedException {
- //排掉空行
- if(value == null || value.toString().equals("")){
- return;
- }
- mapInputStr = value.toString();
- mapInputSpit = mapInputStr.split("\\|",4);
- //过滤非法记录
- if(mapInputSpit.length != 4){
- return;
- }
- //判断链接字段是否在map中存在
- city_secondPart = (String) city_info.get((Object) mapInputSpit[3]);
- if(city_secondPart != null){
- this.outPutKey.set(mapInputSpit[3]);
- this.outPutValue.set(city_secondPart+"\t"+mapInputSpit[0]+"\t"+mapInputSpit[1]+"\t"+mapInputSpit[2]);
- context.write(outPutKey, outPutValue);
- }
- }
- }
- public int run(String[] args) throws Exception {
- Configuration conf=getConf(); //获得配置文件对象
- DistributedCache.addCacheFile(new Path(args[1]).toUri(), conf);//为该job添加缓存文件
- Job job=new Job(conf,"MapJoinMR");
- job.setNumReduceTasks(0);
- FileInputFormat.addInputPath(job, new Path(args[0])); //设置map输入文件路径
- FileOutputFormat.setOutputPath(job, new Path(args[2])); //设置reduce输出文件路径
- job.setJarByClass(MapSideJoinMain.class);
- job.setMapperClass(LeftOutJoinMapper.class);
- job.setInputFormatClass(TextInputFormat.class); //设置文件输入格式
- job.setOutputFormatClass(TextOutputFormat.class);//使用默认的output格式
- //设置map的输出key和value类型
- job.setMapOutputKeyClass(Text.class);
- //设置reduce的输出key和value类型
- job.setOutputKeyClass(Text.class);
- job.setOutputValueClass(Text.class);
- job.waitForCompletion(true);
- return job.isSuccessful()?0:1;
- }
- public static void main(String[] args) throws IOException,
- ClassNotFoundException, InterruptedException {
- try {
- int returnCode = ToolRunner.run(new MapSideJoinMain(),args);
- System.exit(returnCode);
- } catch (Exception e) {
- // TODO Auto-generated catch block
- logger.error(e.getMessage());
- }
- }
- }
实例参考文献:
https://www.cnblogs.com/cssdongl/p/6018806.html
自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:
https://www.cnblogs.com/bclshuai/p/11380657.html
9.3.1 map端连接- DistributedCache分布式缓存小数据集的更多相关文章
- 使用map端连接结合分布式缓存机制实现Join算法
前面我们介绍了MapReduce中的Join算法,我们提到了可以通过map端连接或reduce端连接实现join算法,在文章中,我们只给出了reduce端连接的例子,下面我们说说使用map端连接结合分 ...
- Hadoop DistributedCache分布式缓存的使用
做项目的时候遇到一个问题,在Mapper和Reducer方法中处理目标数据时,先要去检索和匹配一个已存在的标签库,再对所处理的字段打标签.因为标签库不是很大,没必要用HBase.我的实现方法是把标签库 ...
- hadoop中的分布式缓存——DistributedCache
分布式缓存一个最重要的应用就是在进行join操作的时候,如果一个表很大,另一个表很小很小,我们就可以将这个小表进行广播处理,即每个计算节点 上都存一份,然后进行map端的连接操作,经过我的实验验证,这 ...
- .net 分布式架构之分布式缓存中间件
开源git地址: http://git.oschina.net/chejiangyi/XXF.BaseService.DistributedCache 分布式缓存中间件 方便实现缓存的分布式,集群, ...
- 分布式缓存DistributedCache
本文是对MR案例:Map-Join的解读. 在hadoop中,共享全局变量或全局文件的几种方法 使用Configuration的set()方法,只适合数据内容比较小的场景 将缓存文件放在HDFS上,每 ...
- 分布式缓存DistributedCache的使用
分布式缓存用于将使用的小文件首先分发到各个datanode节点上,然后利用map/reduce阶段的setup()方法将文件内容读入内存,加快程序执行.具体实现方法如下: http://demievi ...
- Hadoop 之 分布式缓存的原理和方法——DistributedCache
1.什么时Hadoop的分布式缓存 答:在执行MapReduce时,可能Mapper之间需要共享一些信息,如果信息量不大,可以将其从HDFS中加载到内存中,这就是Hadoop分布式缓存机制. 2.如何 ...
- 大数据【四】MapReduce(单词计数;二次排序;计数器;join;分布式缓存)
前言: 根据前面的几篇博客学习,现在可以进行MapReduce学习了.本篇博客首先阐述了MapReduce的概念及使用原理,其次直接从五个实验中实践学习(单词计数,二次排序,计数器,join,分 ...
- hadoop 分布式缓存
Hadoop 分布式缓存实现目的是在所有的MapReduce调用一个统一的配置文件,首先将缓存文件放置在HDFS中,然后程序在执行的过程中会可以通过设定将文件下载到本地具体设定如下: public s ...
随机推荐
- caffe实战笔记
Caffe简要介绍: Caffe还没有windows版本,所以我需要远程登录linux服务器 Caffe主要处理图片/图片序列 Caffe读取的数据格式 从专用的数据库中读取(lmdb.leveldb ...
- 简单快速破解IDEA
====================================2019.09.16更新==================================== 可以直接去掉第三步,直接在激活 ...
- 小白学 Python 爬虫(38):爬虫框架 Scrapy 入门基础(六) Item Pipeline
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 转载 css截取td里面的内容 如何固定td th的宽度
源博客地址:http://blog.csdn.net/u011456552/article/details/53839255 效果图: 源码: <!DOCTYPE html> <ht ...
- CS0656 缺少编译器要求的成员“Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create”
问题出现原因:在net core使用动态类型dynamic,在编译的时候提示错误信息如上. 解决方案: 1.不用dynamic类型 2.在使用的地方添加一个dll,Microsoft.CSharp,或 ...
- C#实现DataTable转.CSV文件
将DataTable转换成CSV文件是一种常见的转换形式,主要通过遍历Table的每行,再对每行遍历每列,实现对数据的读取,然后用分隔符分隔Table的每个栏位数据,把读取的字符写入到CSV文件中.这 ...
- js的alert()
效果图: 图一: 图二: 图三: 代码: <script type="text/javascript"> // alert() ; 只允许一个参数,如果有多个参数只显示 ...
- 线性基 - 寻找异或第K大
XOR is a kind of bit operator, we define that as follow: for two binary base number A and B, let C=A ...
- scala基本语法
scala基本语法scala函数1 def定义方法2 方法的返回值类型可以省略3 方法体重最后一行计算结果可以返回 return 如果省略方法类型4 方法参数 要指定类型5 如果方法体可以一步搞定 方 ...
- 初探ASP.NET Core 3.x (3) - Web的运作流程和ASP.NET Core的运作结构
本文地址:https://www.cnblogs.com/oberon-zjt0806/p/12215717.html 注意:本篇大量地使用了mermaid绘制图表,加载需要较长的时间,请见谅 [TO ...