分布式缓存Hadoop MapReduce 框架提供的一种数据缓存机制。可缓存只读文本文件,压缩文件,jar包等文件。一旦对文件执行缓存操作,每个执行 map/reduce 任务的节点都可以使用该缓存的文件。
分布式缓存具有一定的优势,如存储复杂的数据。分布式缓存分发了简单、只读的文本文件和复杂类型的文件,这些压缩包都将在各个slave节点解压。分布式缓存具有数据一致性优势,Hadoop 分布式缓冲追踪了缓存文件的修改时间戳,当job执行,会通知这些文件不能被修改,使用hash算法,缓冲引擎可以始终确定特定键值对在哪个节点上。因此缓冲cluster只有一个状态,它永远不会是不一致的。
分布式缓冲是一个跨越多个节点独立运行的进程,过程出现单个节点失败也不会导致整个缓存失败。
旧版本的 DistributedCache 已经被注解为过时,以下为 Hadoop-2.2.0 以上的新API接口:
Job job = Job.getInstance(conf);
//将hdfs上的文件加入分布式缓存
job.addCacheFile(new URI("hdfs://url:port/filename#symlink"));
新版API默认创建符号链接,因为不用再调用setSymlink(true) 方法了,可以下面代码来查看是否开启了创建符号连接。
System.out.println(context.getSymlink());
之后在 map/reduce 函数中可以通过 context 来访问到缓存的文件,一般是重写 setup 方法来进行初始化:
@Override
protected void setup(Context context) throws IOException, InterruptedException {
super.setup(context);
if (context.getCacheFiles() != null && context.getCacheFiles().length > 0) {
String path = context.getLocalCacheFiles()[0].getName();
File itermOccurrenceMatrix = new File(path);
FileReader fileReader = new FileReader(itermOccurrenceMatrix);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String s;
while ((s = bufferedReader.readLine()) != null) {
//TODO:读取每行内容进行相关的操作
}
bufferedReader.close();
fileReader.close();
}
}
获得PATH为本地文件系统上的路径。其中getLocalCacheFiles 方法也被注解为过时了,只能使用 context.getCacheFiles 方法,和 getLocalCacheFiles 不同的是,getCacheFiles 得到的路径是 HDFS 上的文件路径,如果使用这个方法,那么程序中读取的就不再试缓存在各个节点上的数据了,相当于共同访问 HDFS 上的同一个文件。可以直接通过符号连接来跳 过getLocalCacheFiles 获得本地的文件。
分布式缓存的大小可以在在文件 mapred-site.xml 中设置,默认为10GB。使用分布式缓存需要注意在分发文件要存储在HDFS上,文件只读且不能缓存太大文件。在执行task之前要对文件进行分发,大文件会 影响task的启动速度,如需帮助咨询华纳云官网客服团队。