一、问题描述:

主要解决一个问题,就是两个表做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中做分布式缓存的问题的更多相关文章

  1. MapReduce中的分布式缓存使用

    MapReduce中的分布式缓存使用 @(Hadoop) 简介 DistributedCache是Hadoop为MapReduce框架提供的一种分布式缓存机制,它会将需要缓存的文件分发到各个执行任务的 ...

  2. .NET Core应用中使用分布式缓存及内存缓存

    .NET Core针对缓存提供了很好的支持 ,我们不仅可以选择将数据缓存在应用进程自身的内存中,还可以采用分布式的形式将缓存数据存储在一个“中心数据库”中.对于分布式缓存,.NET Core提供了针对 ...

  3. .net core中的分布式缓存和负载均衡

    通过减少生成内容所需的工作,缓存可以显著提高应用的性能和可伸缩性,缓存对不经常更改的数据效果最佳,缓存生成的数据副本的返回速度可以比从原始源返回更快.ASP.NET Core 支持多种不同的缓存,最简 ...

  4. hadoop中的分布式缓存——DistributedCache

    分布式缓存一个最重要的应用就是在进行join操作的时候,如果一个表很大,另一个表很小很小,我们就可以将这个小表进行广播处理,即每个计算节点 上都存一份,然后进行map端的连接操作,经过我的实验验证,这 ...

  5. (转)C# 中使用分布式缓存系统Memcached

    转自:http://blog.csdn.net/devgis/article/details/8212917 缘起: 在数据驱动的web开发中,经常要重复从数据库中取出相同的数据,这种重复极大的增加了 ...

  6. Redis中的Java分布式缓存

    为什么在分布式Java应用程序中使用缓存?今天学习了两节优锐课讲解分布式缓存的内容,收获颇多,分享给大家. 在提高应用程序的速度和性能时,每毫秒都是至关重要的.例如,根据Google的一项研究,如果网 ...

  7. JEESZ-Redis分布式缓存安装和使用

    独立缓存服务器: Linux CentOS Redis 版本: 3.0下面我们针对于Redis安装做下详细的记录:编译和安装所需的包:# yum install gcc tcl创建安装目录:# mkd ...

  8. .net 分布式架构之分布式缓存中间件

    开源git地址: http://git.oschina.net/chejiangyi/XXF.BaseService.DistributedCache 分布式缓存中间件  方便实现缓存的分布式,集群, ...

  9. springboot+mybatis+redis实现分布式缓存

    大家都知道springboot项目都是微服务部署,A服务和B服务分开部署,那么它们如何更新或者获取共有模块的缓存数据,或者给A服务做分布式集群负载,如何确保A服务的所有集群都能同步公共模块的缓存数据, ...

随机推荐

  1. Windows Path设置

    win7系统环境变量path的两种设置方法   环境变量Path    环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息.例如Windows和DOS操作系统中 ...

  2. 第九篇:在SOUI中使用多语言翻译

    为UI在不同地区显示不同的语言是产品国际化的一个重要要求. 在SOUI中实现了一套类似QT的多语言翻译机制:布局XML不需要调整,程序代码也不需要调整,只需要为不同地区的用户提供不同的语言翻译文件即可 ...

  3. Codeforces Round #369 (Div. 2) C. Coloring Trees DP

    C. Coloring Trees   ZS the Coder and Chris the Baboon has arrived at Udayland! They walked in the pa ...

  4. java的安装环境配置详细步骤

    --------------------声明,如果你有什么建议或者不懂的地方,欢迎回复,我们可以互相学习,转载请注明出处,谢谢---------------- 首先得安装jdk(Java Develo ...

  5. this和super

    1.this * 每个类的每个非静态方法(没有被static修饰)都会隐含一个this引用名称,它指向调用这个方法的对象. * 当在方法中使用本类的属性时,都会隐含地使用this名称,当然也可以明确指 ...

  6. static 类成员变量 和 static const类成员变量

    1.使用static类的优点: (1)避免与其他类的成员或者全局变量冲突 (2)可以封装 (3)阅读性好 2.static 数据成员独立于该类的任意对象而存在 static数据成员的类型可以是该成员所 ...

  7. node.js整理 01代码的组织和部署

    模块 require(函数) 用于在当前模块中加载和使用别的模块,传入一个模块名,返回一个模块导出对象. 模块名可使用相对路径(以./开头),或者是绝对路径(以/或C:之类的盘符开头:注意单个模块名默 ...

  8. 20145223《Java程序程序设计》第3周学习总结

    20145223 <Java程序设计>第3周学习总结 教材学习内容总结 第四章内容 1.类与对象 如何定义一个包含有几个值域(Field成员)就是需要我们定义一个类(Class),书上给的 ...

  9. Spring Data JPA 查询方法支持的关键字

    Table 2.3. Supported keywords inside method names Keyword Sample JPQL snippet And findByLastnameAndF ...

  10. MFC CPen CBrush CFont

    在OnDraw函数内定义后使用 使用时,要pDC->SelectObject(),如pDC->SelectObject(font); CPen://draw line Pen.Create ...