Hadoop 文件系统应该关闭吗?

Should Hadoop FileSystem be closed?

我正在构建一个 spring-boot 驱动的服务,该服务使用文件系统 API 将数据写入 Hadoop。一些数据写入 parquet 文件,大块缓存在内存中,因此当服务关闭时,可能需要将数百 Mb 的数据写入 Hadoop。

FileSystem 默认情况下自动关闭,因此当服务关闭时,有时 FileSystem 在所有编写器关闭之前关闭,导致 parquet 文件损坏。

文件系统 Configuration 中有 fs.automatic.close 标志,但是 FileSystem 实例是从多个线程使用的,我不知道有什么干净的方法可以等待它们全部完成手动关闭 FileSystem。我尝试使用专用的 filesysem 关闭 bean 实现 Spring SmartLifeCycle 最大 phase 所以它最后被销毁,但实际上它最后没有被销毁但最后通知关闭而其他 bean 仍在关机过程。

理想情况下,每个需要 FileSystem 的对象都会得到一个并负责关闭它。问题是 FileSystem.get(conf) returns 缓存实例。有 FileSystem.newInstance(conf),但不清楚在性能方面使用多个 FileSystem 实例的后果是什么。还有另一个问题 - 无法将 FileSystem 实例传递给 ParquetWriter - 它 gets one using path.getFileSystem(conf). And one would think that line would return a FileSystem instance assigned to that file only, but one would be wrong - most likely the same cached instance would be returned 所以关闭它是错误的。

是否有推荐的方法来管理 FileSystem 的生命周期?如果 FileSystem 是在 fs.automatic.close 设置为 true 的情况下创建的并且从未手动关闭,会发生什么情况?也许 spring-boot 支持一种干净的方式来关闭 FileSystem 在所有其他 bean 实际上被销毁(未被销毁)之后?

谢谢!

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

听起来问题确实来自 JVM shutdown hooks used by Spring and those employed by Hadoop, which is the mechanism used to automatically close FileSystem instances. Hadoop includes its own ShutdownHookManager 之间的不良交互,后者用于在关闭期间对事件进行排序; FileSystem shutdown 有意放在最后,以便其他关闭挂钩(例如,在 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?

推荐的方式一般是不管理,让系统帮你管理。自己管有龙,谨慎行事。