多个HDFS集群的fs.defaultFS配置一样,造成应用一直连接同一个集群的问题分析
背景
应用需要对两个集群中的同一目录下的HDFS文件个数和文件总大小进行比对,在测试环境中发现,即使两边HDFS目录下的数据不一样,应用日志显示两边始终比对一致,分下下来发现,应用连的一直是同一个集群。大数据集群:CDH6.2.1
定位分析
应用代码片段
Configuration mainconf = new Configuration();
mainconf.addResource(new Path(main_prefix+"/core-site.xml"));
mainconf.addResource(new Path(main_prefix+"/hdfs-site.xml"));
//Main集群hdfs操作,获取指定目录下文件
getHdfsDirectoryTailList("指定目录",mainConf)
Configuration slaveconf=new Configuration();
slaveconf.addResource(new Path(slave_prefix+"/core-site.xml"));
slaveconf.addResource(new Path(slave_prefix+"/hdfs-site.xml"));
//Slave集群hdfs操作,获取指定目录下文件
getHdfsDirectoryTailList("指定目录",slaveConf)
public static List<String> getHdfsDirectoryTailList(String path,Configuration conf) {
List<String> tailList = new ArrayList<String>();
try {
FileSystem hdfs = FileSystem.get(URI.create(path), conf);
if(!hdfs.exists(new Path(path))){
return tailList;
}
FileStatus[] fs = hdfs.listStatus(new Path(path));
Path[] listPath = FileUtil.stat2Paths(fs);
for (Path p : listPath) {
String[] tailSplit = p.toString().split("\\/");
String tail = tailSplit[tailSplit.length - 1];
if (tail.equals("_SUCCESS")) {
continue;
}
tailList.add(tail);
}
} catch (IOException e) {
logger.error("Extract: getHdfsDirectoryTailList exception", e);
throw e;
}
return tailList;
}
检查两个集群配置及应用代码,确认没有问题
fs.hdfs.impl.disable.cache参数
fs.hdfs.impl.disable.cache参数之前又遇到过,默认值为false,表示使用cache,怀疑又是cache的问题,所以FileSystem.get(URI.create(path), conf),第一次获取的是master集群,第二次使用了cache,所以一直连的是master集群。测试方法,在core-site.xml里加上下面配置,表示不使用cache,加上之后,应用能正常连接两个集群了。
<property>
<name>fs.hdfs.impl.disable.cache</name>
<value>true</value>
</property>
FileSystem.get源码分析
那么明明使用了两个集群,为什么会使用到Cache呢,分析FileSystem.get源码便知道原因了
public static FileSystem get(URI uri, Configuration conf) throws IOException {
String scheme = uri.getScheme();
String authority = uri.getAuthority();
if (scheme == null && authority == null) { // use default FS
return get(conf);
}
if (scheme != null && authority == null) { // no authority
URI defaultUri = getDefaultUri(conf);
if (scheme.equals(defaultUri.getScheme()) // if scheme matches default
&& defaultUri.getAuthority() != null) { // & default has authority
return get(defaultUri, conf); // return default
}
}
String disableCacheName = String.format("fs.%s.impl.disable.cache", scheme);
if (conf.getBoolean(disableCacheName, false)) {
LOGGER.debug("Bypassing cache to create filesystem {}", uri);
return createFileSystem(uri, conf);
}
return CACHE.get(uri, conf);
}
应用在获取FileSystem时,提供了完整的hdfs目录,同时没有设置fs.hdfs.impl.disable.cache为true,所以创建slave集群的filesystem对象时,会使用CACHE.get(uri, conf)获取,Cache内部使用一个HashMap来维护filesystem对象,很容易想到,当HashMap的key相同时,便返回了同一个filesystem对象,那么Cache中的key是什么样的呢,代码如下:
FileSystem get(URI uri, Configuration conf) throws IOException{
Key key = new Key(uri, conf);
return getInternal(uri, conf, key);
}
static class Key {
final String scheme;
final String authority;
final UserGroupInformation ugi;
final long unique; // an artificial way to make a key unique
Key(URI uri, Configuration conf) throws IOException {
this(uri, conf, 0);
}
Key(URI uri, Configuration conf, long unique) throws IOException {
scheme = uri.getScheme()==null ?
"" : StringUtils.toLowerCase(uri.getScheme());
authority = uri.getAuthority()==null ?
"" : StringUtils.toLowerCase(uri.getAuthority());
this.unique = unique;
this.ugi = UserGroupInformation.getCurrentUser();
}
@Override
public int hashCode() {
return (scheme + authority).hashCode() + ugi.hashCode() + (int)unique;
}
static boolean isEqual(Object a, Object b) {
return a == b || (a != null && a.equals(b));
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Key) {
Key that = (Key)obj;
return isEqual(this.scheme, that.scheme)
&& isEqual(this.authority, that.authority)
&& isEqual(this.ugi, that.ugi)
&& (this.unique == that.unique);
}
return false;
}
@Override
public String toString() {
return "("+ugi.toString() + ")@" + scheme + "://" + authority;
}
}
}
可以看到Key由四个要素构成,其中前2个跟URI相关,我们两集群的fs.defaultFS值均为CDH高可用集群创建时的默认值hdfs://nameservice1,应用比对的是两边集群的相同目录,ugi为安全认证的用户,应用使用的是同一个,unique为0,因此Key相同,第二次获取filesystem对象时,直接返回了第一次创建的filesystem对象,最终造成了应用虽然使用了不同的集群配置文件,但最中获取的是同一个filesystem对象。
解决
fs.hdfs.impl.disable.cache参数本身不建议修改,修改集群的fs.defaultFS,使不同集群的fs.defaultFS不一样
多个HDFS集群的fs.defaultFS配置一样,造成应用一直连接同一个集群的问题分析的更多相关文章
- 获取hdfs集群信息(fs.defaultFS)
[root@hive-dp-7bd6fd4d55-wctjn hive-1.1.0-cdh5.14.0]# hdfs getconf -confKey fs.default.name19/12/04 ...
- 大数据高可用集群环境安装与配置(08)——安装Ganglia监控集群
1. 安装依赖包和软件 在所有服务器上输入命令进行安装操作 yum install epel-release -y yum install ganglia-web ganglia-gmetad gan ...
- 使用DBeaver Enterprise连接redis集群的一些操作记录
要点总结: 使用DBeaver Enterprise连接redis集群可以通过SQL语句查看key对应的value,但是没法查看key. 使用RedisDesktopManager连接redis集群可 ...
- hdfs dfs ls /列出了本地根目录下文件夹和文件Warning: fs.defaultFS is not set when running "ls" command
[root@node01 customShells]# hdfs dfs -ls /Warning: fs.defaultFS is not set when running "ls&quo ...
- 【Spark】---- 在Linux集群上安装和配置Spark
1 安装JDK 1) 进入JDK官网 2) 下载JDK安装包 3)配置环境变量,在/etc/profile增加以下代码 JAVA_HOME=/home/hadoop/jdk1.6.0_38 PAT ...
- 大数据高可用集群环境安装与配置(06)——安装Hadoop高可用集群
下载Hadoop安装包 登录 https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/ 镜像站,找到我们要安装的版本,点击进去复制下载链接 ...
- Dubbo入门到精通学习笔记(十四):ActiveMQ集群的安装、配置、高可用测试,ActiveMQ高可用+负载均衡集群的安装、配置、高可用测试
文章目录 ActiveMQ 高可用集群安装.配置.高可用测试( ZooKeeper + LevelDB) ActiveMQ高可用+负载均衡集群的安装.配置.高可用测试 准备 正式开始 ActiveMQ ...
- hdfs的HA集群搭建的相关配置
前期准备就不详细说了 .修改Linux主机名 .修改IP .修改主机名和IP的映射关系 ######注意######如果你们公司是租用的服务器或是使用的云主机(如华为用主机.阿里云主机等) /etc/ ...
- Hadoop集群搭建-04安装配置HDFS
Hadoop集群搭建-05安装配置YARN Hadoop集群搭建-04安装配置HDFS Hadoop集群搭建-03编译安装hadoop Hadoop集群搭建-02安装配置Zookeeper Hado ...
随机推荐
- DWVA-命令注入漏洞闯关(Command Injection)
前言 Vulnerability: Command Injection LOW级别 代码: <?php if( isset( $_POST[ 'Submit' ] ) ) { // 几首一个变量 ...
- 详讲FL Studio通道设置菜单
我们在FL Studio"通道设置按钮"上右击鼠标就会弹出一个设置菜单,它包含了通道操作的各种常用命令.下文小编将会为大家详细讲解这些命令的具体作用,一起来学习吧! 1.首先,我们 ...
- python3 Redis未授权检测脚本
`import sys import getopt import socket def get_target(): opts, args = getopt.getopt(sys.argv[1:], ' ...
- Contest 991
A 先判合法然后容斥. 时间复杂度 \(O\left(1\right)\). B 贪心选最小的实验做成 \(5\) 分. 时间复杂度 \(O\left(n\right)\). 剩下的鸽了.
- NOIP2012 解题报告
TG Day1 T3 开车旅行 1. 预处理出从每座城市两人分别会到达的两座城市. 用 set 可以轻松实现. 2. 用倍增优化 DP 令 \(f_{i,j,k}\) 表示从城市 \(j\) 出发,行 ...
- 【ACwing 96】奇怪的汉诺塔——区间dp
(题面来自ACwing) 汉诺塔问题,条件如下: 1.这里有A.B.C和D四座塔. 2.这里有n个圆盘,n的数量是恒定的. 3.每个圆盘的尺寸都不相同. 4.所有的圆盘在开始时都堆叠在塔A上,且圆盘尺 ...
- JS指定音频audio在某个时间点进行播放,获取当前音频audio的长度,音频时长格式转化
前言: 今天接到一个需求,需要获取某个.mp3音频文件的时间长度和指定音频audio在某个时间点进行播放(比如说这个视频有4分钟,我要让它默认从第2秒的时候开始播放),这里当然想到了H5中的audio ...
- Gin + 七牛云对象存储
配置七牛云存储 创建存储空间 拿到密钥 安装七牛云对象存储SDK 推荐go.mod安装 // 将下面地址复制到go.mod,然后执行go mod download github.com/qiniu/a ...
- jvm系列(一)运行时数据区
C++程序员肩负着每一个对象生命周期开始到终结的维护责任.Java程序员则可以借助自动内存管理机制,不需要自己手动去释放内存.由虚拟机进行内存管理,不容易出现内存泄漏和内存溢出的问题,但是一旦出现这些 ...
- tomcat安装及环境变量配置
java环境的配置应该都学过吧,这里简单的讲一下. 下载安装java JDK,注意安装的路径,我们需要进行环境变量的配置. 2 安装完成以后,配置环境变量 环境变量的配置这里就以win7为例:右击计算 ...