在实现一个Yarn Application的过程中,免不了要在HDFS上暂存一些文件,需要用到LocalResource这么个东东。
LocalResource represents a local resource required to run a container.
The NodeManager is responsible for localizing the resource prior to launching the container.
LocalResource 就是Application Master或者其下管理的Task运行所需要从HDFS下载到本地的资源,你在提交APP时,要自己上传文件到HDFS,然后指定需要的LocalResource所在HDFS的Path。大概是下面这样的
ContainerLaunchContext clc = Records.newRecord(ContainerLaunchContext.class);
clc.setCommands(Lists.newArrayList("cmd1......", "cmd2......"));
Map<String, String> env = new HashMap<String, String>();
env.put("HADOOP_HOME", "/usr/lib/hadoop");
clc.setEnvironment(env);
Path path = new Path("/somewhere/xxx.zip");
FileSystem fs = path.getFileSystem(new Configuration());
FileStatus stat = fs.getFileStatus(path);
LocalResource localResource = LocalResource.newInstance(
ConverterUtils.getYarnUrlFromURI(path.toUri()),
LocalResourceType.ARCHIVE, LocalResourceVisibility.APPLICATION, stat.getLen(), stat.getModificationTime());
Map<String, LocalResource> localResources = new HashMap<String, LocalResource>();
localResources.put("resource1", localResource);
clc.setLocalResources(localResources);
然后,你可以启动一个新的Container了。这里需要注意的几点是:
- LocalResourceType是为了告诉NodeManager在启动这个Container之前,下载资源列表后,要按照何种方式来处理这些文件。比如,ARCHIVE表示这是一个压缩档,必须解压后程序才能使用。
- 在往Map<String, LocalResource>里添加资源时,这个key的作用是,这个文件被NodeManager本地化时会创建一个链接到该文件(这个文件会在一个缓存目录下,并不是在Container的工作区间),这个链接的命名就是你的key,对于普通文件还好,但是对于压缩包就意味着解压后一定会在key这个目录下,所以注意文件的路径变化。
更多请参考:http://zh.hortonworks.com/blog/resource-localization-in-yarn-deep-dive/