在mapreduce中做分布式缓存的问题
一、问题描述:
主要解决一个问题,就是两个表做join,两个表都够大,单个表都无法装入内存。
怎么做呢?思路就是对做join的字段做排序两个表都排序,然后针对一个表a逐行读取,希望能够在内存中加载到另一个表b的数据,针对表a当前记录希望b的对应记录在内存中,这就是缓存的作用,希望命中率越高越好!
这个问题其实关键就是做缓存!
如下的情形是针对两个表做join的字段是两个,比如字段1字段2,做法是将表b 按照字段1分成多个文件,然后每个文件内按照字段2做好排序;表a也是同样的操作!
表b做晚切割后会有多个文件,需要做个元数据结构就是将这个partition内的字段2的最小值和最大值以及partition的名字这个3元组存储起来,作用就是当表a中一个记录来了后,能够知道对应的partition文件的名字,--注意这个元数据结构是永久存在内存的数据结构是就是(BeginEndPosition)。
存储一个hashMap(CustomLRUMap),key是partition文件名字,value是这个partition的数据,上一部得到了partition名字,就去这个map坐查询,如果没有就去加载。
二、具体描述
就是针对每次mapreduce的计算的时候希望通过一个缓存可以做做些查找,希望针对map或者reduce到的每条记录可以直接在内存中找到数据,如果找不到那么需要加载到内存!

这个索引的结构也就是 <分区文件名字,开始position,结束position> 这个三元组。
原始数据如上图所示,现在还需要一个meta data去组织数据
比如固定key1以后的按照key2做排序后split形成的partition文件如下:

这个文件就是最后的partition文件,注意:
Note that each of these partitioned files has a range of position values (since they are sorted by position). We will use these ranges in our cache implementation. Therefore, given a chromosome_id=1 and a position, we know exactly which partition holds the result of a query. Let’s look at the content of one of these sorted partitioned files如下是partition文件的内容,最左边的就是position(就是key2)字段,然后这个partition name是和key1有关系的:

三、代码组织
0、首先组织元素据结构
You can see that all positions are sorted within each partition. To support meta‐ data for all partitions using LRU Map, we need an additional data structure to keep track of (begin, end) positions. For each partitioned file we will keep the (partition name, begin, end) information.
伪代码:
>>BeginEndPosition对象实现了 the partition data structure such that you can get the database name for a given composite key.--作用就是根据chrId+position得到database name。
>> 注意MapDBEntry class 代表了 sorted partition of 64MB as a Map data structure implemented in MapDB.
the MapDBEntry class defines a single entry of a MapDB object ,比如new一个MapDBEntry对象的过程
public static MapDBEntry create(String dbName){
DB db=DBMaker.newFileDB(new File(dbName)).closeOnJvmShutDown().readOnly().make();
Map<String,String> map=db.getTreeMap("collectionName");
//可以从外村加载数据到map中去
MapDBEntry entry=new MapDBEntry(db,map);
return entry;
}
>>1、然后是cacheManager的初始化过程分析,最为关键的数据结构就是 theCustomLRUMap,这玩意的key是 dbname,value就是一个partition数据,其实就是文件名和数据的对应关系
注意cacheManage管理的是每一个partition,所以做替换内存操作的是每一个partition的操作!!!!,这个初始化过程放在setup()方法内,因为setup()执行时间是
Setup gets called exactly once for each mapper, before map() gets called the first time.
It's a good place to do configuration or setup that can be shared across many calls to map
public static void init() throws Exception{
if(initialized)
return;
//注意这里的map类型 value是一个MapDBEntry类型的,其实
//这个数据结构说白了就是map中套map的类型
theCustomLRUMap=new CustomLRUMap<String,MapDBEntry<String,String>>(theLRUMapSize);
7 beginEnd=new BeginEndPosition(mapdbBeginEndDirName);//元数据加载过程
8 beginEnd.build(mapdbRootDirName);
initilized=true;
}
>>2、然后是使用
//首先是getDBName()
public static String getDBName(String key1,String key2){
List<Interval> results=beginEnd.query(key1,key2);
if(results==null || results.isEnpty()||results.size()==0) return null;
else return results.get(0).db();
}
//
public static String get(String key1,String key2) throws Exception{
String dbName=getDBName(key1,key2);
if(dbName==null) return null;
MapDBEntry<String,String> entry=theCustomLRUMap.get(dbName);
if(entry==null){
//需要做替换了
entry=MapDBEntryFactory.create(dbName);
theCustomLRUMap.put(dbName,entry);
}
return entry.getValue(key2);
}
在mapreduce中做分布式缓存的问题的更多相关文章
- MapReduce中的分布式缓存使用
MapReduce中的分布式缓存使用 @(Hadoop) 简介 DistributedCache是Hadoop为MapReduce框架提供的一种分布式缓存机制,它会将需要缓存的文件分发到各个执行任务的 ...
- .NET Core应用中使用分布式缓存及内存缓存
.NET Core针对缓存提供了很好的支持 ,我们不仅可以选择将数据缓存在应用进程自身的内存中,还可以采用分布式的形式将缓存数据存储在一个“中心数据库”中.对于分布式缓存,.NET Core提供了针对 ...
- .net core中的分布式缓存和负载均衡
通过减少生成内容所需的工作,缓存可以显著提高应用的性能和可伸缩性,缓存对不经常更改的数据效果最佳,缓存生成的数据副本的返回速度可以比从原始源返回更快.ASP.NET Core 支持多种不同的缓存,最简 ...
- hadoop中的分布式缓存——DistributedCache
分布式缓存一个最重要的应用就是在进行join操作的时候,如果一个表很大,另一个表很小很小,我们就可以将这个小表进行广播处理,即每个计算节点 上都存一份,然后进行map端的连接操作,经过我的实验验证,这 ...
- (转)C# 中使用分布式缓存系统Memcached
转自:http://blog.csdn.net/devgis/article/details/8212917 缘起: 在数据驱动的web开发中,经常要重复从数据库中取出相同的数据,这种重复极大的增加了 ...
- Redis中的Java分布式缓存
为什么在分布式Java应用程序中使用缓存?今天学习了两节优锐课讲解分布式缓存的内容,收获颇多,分享给大家. 在提高应用程序的速度和性能时,每毫秒都是至关重要的.例如,根据Google的一项研究,如果网 ...
- JEESZ-Redis分布式缓存安装和使用
独立缓存服务器: Linux CentOS Redis 版本: 3.0下面我们针对于Redis安装做下详细的记录:编译和安装所需的包:# yum install gcc tcl创建安装目录:# mkd ...
- .net 分布式架构之分布式缓存中间件
开源git地址: http://git.oschina.net/chejiangyi/XXF.BaseService.DistributedCache 分布式缓存中间件 方便实现缓存的分布式,集群, ...
- springboot+mybatis+redis实现分布式缓存
大家都知道springboot项目都是微服务部署,A服务和B服务分开部署,那么它们如何更新或者获取共有模块的缓存数据,或者给A服务做分布式集群负载,如何确保A服务的所有集群都能同步公共模块的缓存数据, ...
随机推荐
- 第二十一篇:SOUI中的控件注册机制
Win32编程中,用户需要一个新控件时,需要向系统注册一个新的控件类型.注册以后,调用::CreateWindow时才能根据标识控件类型的字符串创建出一个新的控件窗口对象. 为了能够从XML描述的字符 ...
- Android屏幕适配全攻略(最权威的官方适配指导) (转)
招聘信息: Cocos2d-X 前端主程 [新浪微博]手机客户端iOS研发工程师 20k-40k iOS 开发工程师 iOS高级开发工程师(中国排名第一的企业级移动互联网云计算公司 和创科技 红圈营销 ...
- Android LayoutInflater详解 (转)
在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById().不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例 ...
- "Project facet Java version 1.7 is not supported"的问题解决的办法
问题描述 在eclipse中,从SVN中检出project代码,拖拽式部署到local server中的时候,报出以下错误: 问题分析 问题产生的原因是,SVN中的代码是采用java 1.7开发编译的 ...
- ios调用系统导航
#import "ViewController.h" #import <MapKit/MapKit.h> @interface ViewController () @p ...
- AChartEngine使用View显示图表
学习过AChartEngine的人肯定都知道,使用ChartFactory创建一张图表可以使用Intent方法,之后调用StartActivity来启用这个Intent,但是这么左右一个坏处,就是当你 ...
- Big Event in HDU
Description Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe ...
- 廖雪峰js教程笔记6 generator一个坑 看完python在回来填坑
generator(生成器)是ES6标准引入的新的数据类型.一个generator看上去像一个函数,但可以返回多次. ES6定义generator标准的哥们借鉴了Python的generator的概念 ...
- JavaScript设计模式——单体模式
一:单体模式简介: 是什么:将代码组织为一个逻辑单元,这个单元中的代码通过单一的变量进行访问.只要单体对象存在一份实例,就可以确信自己的所有代码使用的是同样的全局资源. 用途:1.用来划分命名空间,减 ...
- [bzoj1068]压缩[区间动规]
看了lujiaxin的blog,感觉自己好浪啊....好难过 刷题的时候不够投入,每种算法都是只写一两道就过去了,这样怎么可能进步嘛 不要总是抱怨时间太少了 都是自己不努力>_< 好啦 看 ...