Hadoop API 通过租户代理访问 Kerberos 安全 Hadoop 集群
概述
访问HDFS其实很简单
这里记录一些方法,具备下面的特征:
- 通过租户代理访问 Kerberos 认证的 HADOOP 资源
- 获取 FileSystem 对象的技巧:FileSystem.get(URI, configuration)
- 通用 doAs模板
- 通用 hdfsCommand模板,使用 try-with-resources。
- 截取 hdfs://namenode/user/...,使得 namenode对应得 FileSystem 能够缓存。
- FileSystem.getDefaultUri(...) 如果使用这个方法,则路径必须以core-site.xml得 fs.defaultFs 为开头。会出现错误 Wrong FS: hdfs://dc1, expected: viewfs://ssss。
- 通过指定 FileSystem.get() 第一个参数,能保证和实际得 namenode 一致。
- 因此能同时访问 hdfs://或者viewfs://。
通用代理
public static <T> T doAs(Supplier<T> command, String clusterName) {
return UserGroupInformation.createProxyUser(clusterName, SecureYarn.ugi).doAs((PrivilegedAction<T>) command::get);
}
public static URI getFsUri(String filePath) {
URI fsUri;
if (filePath.startsWith("hdfs://")) {
String uri = filePath.substring(0, filePath.indexOf("/user"));
fsUri = new Path(uri).toUri();
} else {
fsUri = null;
}
return fsUri;
}
listFiles 和 hdfsCommand 模板
public static FileStatus[] listFiles(String filePath, String clusterName, Configuration configuration) {
return doAs(() -> hdfsCommand(c -> c.listStatus(new Path(filePath)), getFsUri(filePath), configuration), clusterName);
}
public static <V> V hdfsCommand(ThrowingFunction<FileSystem, V, Exception> command, URI path, Configuration hdfsConfig) {
try (FileSystem fileSystem = FileSystem.get(path == null ? FileSystem.getDefaultUri(hdfsConfig):path, hdfsConfig)) {
return command.apply(fileSystem);
} catch (Exception e) {
throw new RuntimeException(e);
}
}