hadoop集群分区及缓存随笔

1、分区是必须要经历Shuffle过程的,没有Shuffle过程无法完成分区操作
2、分区是通过MapTask输出的key来完成的,默认的分区算法是数组求模法:
--------------数组求模法:
-----------将Map的输出Key调用hashcode()函数得到的哈希吗(hashcode),此哈希吗是一个数值类型
,将此哈希吗数值直接与整数的最大值(Integer.MAXVALUE)取按位与(&)操作,将与操作的结果与ReducerTask
的数量取余数,将此余数作为当前Key落入的Reduce节点的索引
-------------------------
Integer mod = (Key.hashCode()&Integer.MAXVALUE)%NumReduceTask;

被除数=34567234
NumReduceTas=3
----结果:
0、1、2 这三个数作为Reduce节点的索引
数组求模法是有HashPartitioner类来实现的,也是MapReduce分区的默认算法

hadoop集群性能和效率:
------------
1、数据量需要达到一定的数量级,使用hadoop集群来处理才是划算的
2、集群的计算性能取决于任务数量的多少,设置任务数量必须充分考虑到集群的计算能力(比如:物理节
点数量):
-------
A、Map设置的任务数量作为最小值参考,与切片数量对比,取两者大值
B、Reduce的任务数量默认是1,如果设置了任务数量,则启用设置的任务数量
-------
3、不管MapTask还是ReduceTask,只要任务数量越多则并发能力越强,处理效率会在一定程度上越高,但
是,设置设置的任务数量必须参考集群中的物理节点数量,如果设置的任务数量过多,会导致每个物理节点上分摊的
任务数量过多,处理器并发每个任务产生的计算开销越大,任务之间因处理负载导致相互之间的影响很大,任务失败
率上升,计算性能反而下降(因为任务失败会重置),因此在设计MapTask与ReduceTask任务数量时必须权衡利弊,
折中考虑...

两张表链接操作(分布式缓存):
-------
假设:
------其中一张A表,只有20条数据记录
另外一张非常大,上亿的记录数量
----------------------------------
策略:
将数据集小的文件直接装载到内存,然后迭代大文件记录

分布式缓存的两种角度理解(针对较小数据集):
-----------------
1、将文件不切块,直接存储到各个节点上的本地磁盘中,这种模式的缓存只是减少了网络IO,磁盘IO并没
有减少
2、将文件不切块,直接存储到各个节点上的任务进程内存中,(MapTask进程,JVM会开辟一块任务内存)
,这种模式的缓存从根本上取消了该文件的读取IO操作

从集群中读取文件缓存到本地内存中:
代码:
-------1、
//从本地磁盘读取数据到内存中缓存起来,之后在Map方法的迭代中可直接使用
Configuration conf = context.getConfiguration();

// 下面是直接从集群路径中读取文件缓存到本地的内存中的操作方式
//FileSystem fs = FileSystem.get(conf);
URI[] uris = context.getCacheFiles();
URI uri=uris[0];

Path clusterPath=new Path(uri);
FileSystem fs=clusterPath.getFileSystem(conf);

InputStream fis = fs.open(clusterPath);
String line=null;
BufferedReader br=null;
try {
br=new BufferedReader(new InputStreamReader(fis));
while(null!=(line=br.readLine())){
String[] fields=line.split("\\s+");
smallMap.put(fields[0], fields[1]);
}
} catch (Exception e) {
// TODO: handle exception
}finally{
if(br!=null)br.close();
}

--------2、
//获取缓存文件的本地路径
Configuration conf = context.getConfiguration();
String[] localPaths = conf.getStrings(MRJobConfig.CACHE_LOCALFILES);
Path[] path = StringUtils.stringToPath(localPaths);

Path localPath=path[0];
URI localurl=localPath.toUri();
File fp=new File(localurl);

String line=null;
BufferedReader br=null;
try {
br=new BufferedReader(new InputStreamReader(new FileInputStream(fp)));
while(null!=(line=br.readLine())){
String[] fields=line.split("\\s+");
smallMap.put(fields[0], fields[1]);
}
} catch (Exception e) {
// TODO: handle exception
}finally{
if(br!=null){
br.close();
}
}

posted on 2017-12-18 18:08 程序源宝宝 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/pandazhao/p/8058953.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值