java - Hadoop FileSystem 应该关闭吗?

标签 java spring-boot hadoop hdfs hadoop2

我正在构建一个由 spring-boot 驱动的服务,该服务使用文件系统 API 将数据写入 Hadoop。一些数据写入 parquet 文件,大块缓存在内存中,因此当服务关闭时,可能有数百 Mb 的数据必须写入 Hadoop。FileSystem默认自动关闭,所以当服务关闭时,有时 FileSystem在关闭所有编写器之前关闭,导致 Parquet 文件损坏。
fs.automatic.close文件系统中的标志 Configuration ,但是 FileSystem实例被多个线程使用,我不知道有什么干净的方法可以在关闭之前等待它们全部完成 FileSystem手动。我尝试使用专用的 filesysem 关闭 bean 实现 Spring SmartLifeCycle最大 phase所以它最后被销毁,但实际上它不是最后被销毁而是最后通知关闭,而其他bean仍在关闭过程中。
理想情况下,每个需要 FileSystem 的对象会得到一个并负责关闭它。问题是FileSystem.get(conf)返回一个缓存实例。有FileSystem.newInstance(conf) ,但不清楚使用多个 FileSystem 的后果是什么实例性能方面。还有另一个问题 - 无法通过 FileSystem实例到 ParquetWriter - 它gets one使用 path.getFileSystem(conf) .人们会认为该行会返回 FileSystem仅分配给该文件的实例,但有一个是错误的 - 很可能是相同的缓存实例 would be returned所以关闭它是错误的。
是否有推荐的方法来管理 FileSystem 的生命周期? ?如果 FileSystem 会发生什么是用 fs.automatic.close 创建的设置为 true并且从不手动关闭?也许 spring-boot 支持一种干净的关闭方式 FileSystem在所有其他 bean 实际被销毁(未被销毁)之后?
谢谢!

最佳答案

您可以禁用 FileSystem缓存使用 fs.<scheme>.impl.disable.cache配置(找到 here ,一些讨论 here ),其中 <scheme>在你的情况下是 hdfs (假设您使用的是 HDFS)。这将强制ParquetWriter新建FileSystem调用 path.getFileSystem(conf) 时的实例.这种配置没有记录是有充分理由的——虽然广泛用于 Hadoop 本身的单元测试,但在生产系统中使用它可能非常危险。回答有关性能的问题,假设您使用的是 HDFS,每个 FileSystem实例将创建一个单独的 TCP 连接到 HDFS NameNode。应用程序和库代码通常假设调用类似 path.getFileSystem(conf)FileSystem.get(conf)价格便宜且重量轻,因此经常使用。在生产系统中,我看到客户端系统 DDoS 是 NameNode 服务器,因为它禁用了缓存。您需要仔细管理不仅仅是 FileSystem 的生命周期您的代码创建的实例,以及您使用的库创建的实例。我通常会建议反对它。

听起来这个问题真的来自 JVM shutdown hooks 之间的不良交互。 Spring 使用的和 Hadoop 使用的,这是用于自动关闭的机制 FileSystem实例。 Hadoop 包括它自己的 ShutdownHookManager用于在关闭期间对事件进行排序; FileSystem有目的地将关闭放在最后,以便其他关闭 Hook (例如,在 MapReduce 任务之后进行清理)可以首先完成。但是,Hadoop 的 ShutdownHookManager只知道已经注册到它的关闭任务,所以它不会知道 Spring 的生命周期管理。听起来确实像利用 Spring 的关闭序列和利用 fs.automatic.close=false可能适合您的应用;我没有 Spring 经验,所以我无法在这方面为您提供帮助。您也可以使用 Hadoop 的 ShutdownHookManager 注册 Spring 的整个关闭序列。 ,使用非常高的优先级来保证Spring的关机顺序在关机队列中排在第一位。

具体回答这部分:

Is there a recommended way of managing a lifecycle of a FileSystem?



推荐的方式一般是不管理,让系统为你做。每当您尝试自己管理它时,都会有龙,因此请谨慎行事。

关于java - Hadoop FileSystem 应该关闭吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55168902/

相关文章:

Hadoop 安全模式恢复 - 花费的时间太长了!

java - 分配给在没有实例化对象的方法中声明的类变量

java - 在 Java 中使用 CipherOutputStream

java - 如何同步读取和写入套接字?

java - 使用 JPA 和 Spring Boot 查询实体类型(鉴别器)

java - Spring找不到 key 存储文件

spring-boot - 如何使用响应式(Reactive)沙发底座获取对象的嵌套列表?

java - 将错误消息从 Java 服务器代码传递到 XPage 客户端

hadoop - 将分区的数据插入分区的配置单元表

apache - 如何配置Apache Hive?