在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服务的所有集群都能同步公共模块的缓存数据, ...
随机推荐
- BZOJ 3289: Mato的文件管理 莫队+BIT
3289: Mato的文件管理 Description Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份有一个大小和一个编号.为了防止他人偷拷,这些资料都是加密过的 ...
- Memcache升级版:CouchBase的安装配置与使用说明
Memcache基本上已经是开发的标配了,但是对于Memcache集群,很多线上部署仍然是很单薄的. 几个存在的问题:不健壮.数据不安全.配置变更可能导致存取异常.后备数据的一致性 鉴于存在以上问题, ...
- struts2框架快速入门小案例
struts2快速入门: index.jsp------>HelloAction--------->hello.jsp struts2流程 1.导入jar包 struts2的目录结构: a ...
- LR Analysis:详解FirstBufferTime
LR Analysis:详解FirstBufferTime 详解 第 一次缓冲时间 测试结果分析过程中,经常遇到第一次缓冲时间 FirstBufferTime,并且发现大 部分系统的响应时间也都浪 ...
- 判断App是否在后台运行
在一些场景中,经常会需要判断App是否在后台运行,比如是否显示解锁界面,收到新消息是否显示Notification等.需求可能是多样化的,但所依仗的原理是相通的,今天Stay打算说说这些需求的最优解. ...
- Linux profile File
umask 022alias vim="/pd/vim/7.1/bin/vim"if [ -e /usr/bin/vim ]; then alias vim="/usr/ ...
- AC自动机(二维) UVA 11019 Matrix Matcher
题目传送门 题意:训练指南P218 分析:一行一行的插入,一行一行的匹配,当匹配成功时将对应子矩阵的左上角位置cnt[r][c]++;然后统计 cnt[r][c] == x 的数量 #include ...
- MFC 动态修改对话框标题
在对应对话框的初始化函数OnInitDialog()中添加以下代码: CString title; title.Format("%d",Id);//在标题栏动态显示Id的值 thi ...
- HIT2543 Stone IV(一定费用内的最大流)
题目大概说,有n个从0到n-1的城市,要从城市0运送石头到城市1,运送石头的单价是p.城市间的有m条双向路相连,路都有能运送石头的限额c1,如果超过限额运送石头的单价就要提高c2.问在总花费c以内能运 ...
- Shell 编程基础之 Select 练习
一.语法 select 变量 in con1 con2 con3 # 自动列出 con1,con2,con3 的选择菜单 do #执行内容 break # select本身就是一个循环,break是当 ...