记一次namenode关机导致的问题

栏目: 服务器 · 发布时间: 5年前

内容简介:某日需要升级namenode系统,对一台namenode进行关机操作,但是关机后出现hive归档延迟。将之间关闭的机器开机后恢复正常。经过排查问题,关机的机器位于配置文件(hdfs-site.xml)中ns1的位置。spark和hive默认开启缓存机制,但因为某些原因实际使用中关闭了缓存,导致高可用Namenode ns1机器不能关机,关机会早成数据流计算延迟。首先为什么关闭缓存:

记一次namenode关机导致的问题

问题:

某日需要升级namenode系统,对一台namenode进行关机操作,但是关机后出现hive归档延迟。将之间关闭的机器开机后恢复正常。经过排查问题,关机的机器位于配置文件(hdfs-site.xml)中ns1的位置。

原因:

spark和hive默认开启缓存机制,但因为某些原因实际使用中关闭了缓存,导致高可用Namenode ns1机器不能关机,关机会早成数据流计算延迟。

具体原因:

首先为什么关闭缓存:

1. 复用FileSystem对象,比如spark要去连hdfs找那些文件,比如查一个表的时候,如果这个表有10个文件,不关闭缓存,它会去连10次namenode所以将该功能关闭。如果打开了缓存的话,就会直接从静态缓存对象中返回已经创建的实例。而缓存默认是打开的。缓存的方式就是常见的懒加载模式(存在就返回,不存在就创建并放在 cache 中)。

2. 为了防止非加密模式下的内存泄露,通过设置下面的参数为true禁用文件系统的缓存org.apache.hadoop.fs.FileSystem。

其次业务代码BUG:

业务代码中因为缓存未生效,会不断请求HDFS集群获取用户组信息,每次都会先请求配置文件中ns1的机器。当ns1关机后,程序会等待ns1返回信息,等待超时后才会连接ns2。同理hive和spark缓存机制未开启,导致每次请求都会经过ns1,最终导致数据流计算明显延迟。

解决方案

修改hive和spark配置,增加缓存机制,修改程序代码中的缓存机制。

详细操作步骤

修改配置文件(默认该两项为false状态)

<property>

<name>fs.hdfs.impl.disable.cache</name>

<value>false</value>

</property>

<property>

<name>fs.file.impl.disable.cache</name>

<value>false</value>

</property>

在hive-site.xml文件中增加缓存功能(默认是开启状态),**spark和hive的相关配置都得修改**并重启相关服务。

修改业务代码

/**

* 配置缓存

*/

private static Cache<String, UserGroupInformation> ugis = CacheBuilder.newBuilder().build();

public UserGroupInformation getUserGroupInformation(String userName) {

boolean isKerberosEnabled = configLoaderServer.getKerberosConfig().isKdcEnabled();

if (isKerberosEnabled) {

//Kerberos authentication

log.info(“Kerberos authentication isKdcEnabled=true”);

return UserGroupInformation.createProxyUser(userName, hadoopKerberosService.getUserGroupInformation(LoginPrincipalType.HDFS));

} else {

log.info(“SIMPLE authentication”);

UserGroupInformation ugi = null;

try {

ugi = ugis.get(userName, () -> UserGroupInformation.createRemoteUser(userName));

} catch (ExecutionException e) {

e.printStackTrace();

log.error(e);

}

return ugi;

//return UserGroupInformation.createRemoteUser(userName); //SIMPLE authentication

}

}

/**

* 注释下面closeFileSystem代码。

*/

@Override

public void closeFileSystem(FileSystem fs) {

//TODO 暂时停止closeFileSystem,因为会使缓存失效

// try {

// if (fs != null)

// fs.close();

// } catch (IOException e) {

// log.error(e.getMessage(), e);

// }

}

问题总结

1. 当Spark和HDFS api同时存在时,当你的hdfs api去调用FileSystem的close方法时,会报java.io.IOException: Filesystem closed,因为他们都是去cache中获取连接,而你的api close了fileSystem,导致spark的hdfs连接不能用,所以会报错。

2. hadoop运行mapreduce任务时,由于多个datanode节点需要读取hdfs filesystem,此时,如果一个节点因为网络或者其他原因关掉了该filesystem,而其他节点仍然使用的cache中的filesystem,导致触发IOException,出现这个问题是在使用hive的时候。

3. **缓存**

FileSystem类中有一个Cache内部类,用于缓存已经被实例化的FileSystem。注意这个跟连接池还是有区别的,Cache中的缓存只是一个map,可以被多个线程拿到。这就会有一个问题,当你多线程同时get FileSystem的时候,可能返回的是同一个对象。所以切记,在多线程场景中,不要随意调用FileSystem.close,你关的连接可能会影响到其他正在使用的线程。

4. 业务代码中getUserGroupInformation函数会在获取ThriftHive操作的client对象、清空表的指定分区下内容用于overwrite、列出分区目录等功能中使用,如果不添加缓存机制,每次会从hdfs-site.xml文件中读取第一个namenode,如果ns1是关机状态会导致程序等待一个ssh超时时间(默认为900s)。再连接ns2,导致的结果是数据计算服务明显卡顿。

注意: 当你在其他框架上拿fileSystem对象需要额外注意,例如在spark上进行 FileSystem.get(),如果你想自定义某些配置,设置hdfs的副本数(dfs.replication) 之类,你必须在configuration中关闭FileSystem的缓存机制。hadoop的FileSystem实例底层默认是复用的,所以如果执行了两次fileSystem.close(),第二次会报错FileSystem Already Closed异常(即使表面上是对两个实例执行的),一个典型的场景是同时使用Spark和Hadoop-Api,Spark会创建FileSystem实例,Hadoop-Api也会创建,由于底层复用,两者其实是同一个。因为关闭钩子的存在,应用退出时会执行两次FileSystem.close(),导致报错。解决这个问题的办法是在hdfs-site.xml增加以下配置,关闭FileSystem实例。

问题解决了,我们看一下hive是什么?

Hive简介:

– Hive是一个构建于Hadoop顶层的数据仓库工具,可以查询和管理PB级别的分布式数据。

– 支持大规模数据存储、分析,具有良好的可扩展性

– 某种程度上可以看作是用户编程接口,本身不存储和处理数据。

– 依赖分布式文件系统HDFS存储数据。

– 依赖分布式并行计算模型MapReduce处理数据。

– 定义了简单的类似 SQL 的查询语言——HiveQL。

– 用户可以通过编写的HiveQL语句运行MapReduce任务。

– 可以很容易把原来构建在关系数据库上的数据仓库应用程序移植到Hadoop平台上。

– 是一个可以提供有效、合理、直观组织和使用数据的分析工具。

Hive分为三个角色:HiveServer、MetaStore、WebHcat。

– HiveServer:将用户提交的HQL语句进行编译,解析成对应的Yarn任务,Spark任务或者HDFS操作,从而完成数据的提取,转换,分析。

– MetaStroe:提供元数据服务。

– WebHcat:对外提供基于Htpps洗衣的元数据访问、DDL查询等服务。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Effective Modern C++

Effective Modern C++

Scott Meyers / O'Reilly Media / 2014-12 / USD 49.99

Learn how to program expertly with C++ with this practical book from Scott Meyers, one of the world's foremost authorities on this systems programming language. Scott Meyers takes some of the most dif......一起来看看 《Effective Modern C++》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具