作者:李佩京
时间:2018-12-25


问题:

某日需要升级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查询等服务。

记一次namenode关机导致的问题相关推荐

  1. 非法关机 mysql_一次非法关机导致mysql数据表损坏的实例解决 -电脑资料

    排查修复数据表的经过: 2.启动mysql服务,卸载和关闭rpm安装的mysql服务 (昨天安装postfix好像yum安装了mysql),用netstat -anp |grep mysqld 命令查 ...

  2. 台式计算机无法访问网络,台式机关机导致局域网内LAN设备无法连接网络

    本帖最后由 星空约翰 于 2019-1-15 00:28 编辑 2018.1.14更新: 测试了几天,似乎找错方向了,经历了绑定全部设备MAC,GEN10多次重装系统.重刷BIOS,不停更换GEN10 ...

  3. 电脑非正常关机导致软件无法使用怎么办?

    当我们的电脑在某些情况下,导致非正常关机,这个时候,关机之前使用的一些软件就无法运行,最长见的就是浏览器打开网络连接不上,打不开网页,还有QQ启动时:Initialization failure:0x ...

  4. openjdk platform binary 内存_记一次内存溢出导致的生产事故

    背景 因为同事的离职,半路被迫接手的一个可视化项目,使用ElasticSearch作为OLAP数据库.Docker作为部署工具等,突然有一天项目现场环境出现JVM内存溢出问题,被迫披挂上阵定位问题的原 ...

  5. easypoi 导入oracle,记一次由openjdk导致的poi错误(easyexcel)

    项目中尝试使用了easyexcel替换了原生poi.测试时线下没啥问题,放到服务器里导出的文件就被损坏. 由于这篇记录是后补的,所以没有报错截图. 大致的错误是:缺少字体样式文件导致的null报错,而 ...

  6. adb一打开就闪退_记一次龙骨动画导致Android版闪退过程

    此文背景: 微信体验版和pc调试版本都没有问题,但是上了Android手机就有问题,百思不得其解.并且有的同事遇到,有的同事没遇到.后面定位之后才发现,不是其没遇到,而是还没到触发时机. 引擎版本: ...

  7. 黑苹果强制关机导致硬盘挂在失败问题

    问题是黑苹果在使用过程中出现卡死的现象,只能强行关机,关机前百度云在下载文件,重新进入Mac系统后发现百度云无法下载,提示原因是文件创建失败,去finder下发现找不到以前的磁盘,在Mac的磁盘管理里 ...

  8. 记一次磁盘挂载导致mysql服务启动失败的问题

    问题背景: 服务器某个目录(/data目录)磁盘空间已满,并且该目录下有个子目录还是mysql的数据存储目录(/data/mysql):采用额外新增一块数据盘,并将该数据盘挂载到/data目录下的方式 ...

  9. mysql 频繁连接中断_记一次网络原因导致的mysql连接中断问题(druid)

    date: 2018-04-19 21:00 tag: java,mysql,exception,mat,调试,jvm 线上系统出现一个诡异的bug,通过heap dump分析 分析: 通过日志确认系 ...

  10. 服务器不正常断电关机导致sqlserver被标记为“可疑”

    1.修改数据库为紧急模式 ALTER DATABASE 库名 SET EMERGENCY 2.使数据库变为单用户模式 1ALTER DATABASE 库名 SET SINGLE_USER 3.修复数据 ...

最新文章

  1. Android不同分辨率和不同密度适配
  2. 前端页面如何引入公用的页面header和footer
  3. python中的字符串常用函数
  4. powerdesigner设置主键为自增字段,设置非主键为唯一键并作为表的外键
  5. jQuery在页面加载的时候自动调用某个函数的方法(转载)
  6. mongodb内存映射原理
  7. Linux 系统的启动顺序
  8. arcgis计算地形起伏度
  9. 制作CAB自解压文件的工具——IExpress
  10. poi,HSSFWorkbook,Excel导出,代码示例
  11. springboot+cxf框架 WebService
  12. android版本连击,死神vs火影无限能量连招版本-死神vs火影无限连招版v3.2 安卓版-腾牛安卓网...
  13. 离散数学复习--Modular Arithmetic
  14. mysql ibd文件一直增加_为什么 MySQL 回滚事务也会导致 ibd 文件增大?
  15. 2022-2027年(新版)中国LCP行业发展前景及需求规模预测报告
  16. python干货:如何使用Python对音频进行特征提取?
  17. 京东2017校招:4,7幸运数
  18. Spiking-YOLO:脉冲神经网络高效的目标检测
  19. flask python web优品课堂_Python Flask Web网站编程全栈开发系列高清视频教程-价值2499...
  20. php对接阿里巴巴开放平台

热门文章

  1. 【JAVA学习】六、设计模式
  2. FIFO读数据异常分析
  3. 2017年下半年网络工程师真题+答案解析
  4. 广播电台常用51首背景音乐~甘醇永久
  5. ubuntu 上交叉编译 linaro 的库
  6. idea 类存在,但是报错
  7. 有赞亿级订单同步的探索与实践
  8. 人工智能能写剧本了 还被拍成了9分钟的短片
  9. 车载娱乐系统开发术语记录
  10. 惊恐!监控拍到神秘人形机器人凌晨三点出逃