hadoop文件系统应该关闭吗?

bnl4lu3b  于 2021-05-27  发布在  Hadoop
关注(0)|答案(1)|浏览(680)

我正在构建一个spring启动的服务,它使用文件系统api将数据写入hadoop。一些数据被写入parquet文件,大块数据被缓存在内存中,因此当服务关闭时,可能需要将几百mb的数据写入hadoop。 FileSystem 默认情况下自动关闭,因此当服务关闭时,有时 FileSystem 在关闭所有写入程序之前关闭,从而导致损坏的Parquet文件。
fs.automatic.close 文件系统中的标志 Configuration ,但是 FileSystem 示例是从多个线程中使用的,我不知道有什么干净的方法可以在关闭前等待它们全部完成 FileSystem 手动。我尝试使用专用的filesysem关闭bean来实现spring SmartLifeCycle 与max phase 所以它是最后销毁的,但实际上它不是最后销毁的,而是最后通知关闭的,而其他bean仍在关闭过程中。
理想情况下,每个需要 FileSystem 会得到一个并负责关闭它。问题是 FileSystem.get(conf) 返回缓存示例。有 FileSystem.newInstance(conf) ,但目前尚不清楚使用多个 FileSystem 示例性能方面。还有另一个问题-没有办法通过 FileSystem 示例到 ParquetWriter -它得到一个使用 path.getFileSystem(conf) . 有人会认为这条线会返回 FileSystem 示例只分配给该文件,但其中一个可能是错误的-很可能返回相同的缓存示例,因此关闭它将是错误的。
有没有一种推荐的方法来管理 FileSystem ? 如果 FileSystem 创建时使用 fs.automatic.close 设置为 true 从来没有手动关闭过?也许Spring Boot支持一种干净的关闭方式 FileSystem 在所有其他豆子都被销毁(没有被销毁)之后?
谢谢!

kmb7vmvb

kmb7vmvb1#

您可以禁用 FileSystem 使用缓存 fs.<scheme>.impl.disable.cache 配置(在这里找到,这里有一些讨论),在哪里 <scheme> 对你来说 hdfs (假设您使用的是hdfs)。这将迫使 ParquetWriter 创建新的 FileSystem 调用时的示例 path.getFileSystem(conf) . 这种配置没有文档化是有充分理由的——虽然在hadoop本身的单元测试中广泛使用,但在生产系统中使用它可能非常危险。为了回答有关性能的问题,假设您使用的是hdfs,则 FileSystem 示例将创建到hdfs namenode的单独tcp连接。应用程序和库代码的编写通常假定 path.getFileSystem(conf) 以及 FileSystem.get(conf) 它们既便宜又轻,所以经常使用。在一个生产系统中,我看到一个客户机系统ddos一个namenode服务器,因为它禁用了缓存。您需要谨慎地管理 FileSystem 您的代码创建的示例,以及您使用的库创建的示例。我一般不建议这样做。
听起来这个问题实际上是来自spring使用的jvm关闭钩子和hadoop使用的那些钩子之间的错误交互,hadoop是用来自动关闭的机制 FileSystem 示例。hadoop包含自己的shutdownhookmanager,用于在关闭期间对事件进行排序; FileSystem shutdown故意放在末尾,这样其他shutdown钩子(例如mapreduce任务之后的清理)可以首先完成。但是,hadoop的 ShutdownHookManager 只知道已注册到它的关闭任务,因此它不会知道spring的生命周期管理。听起来确实像是利用spring的关闭序列 fs.automatic.close=false 可能适合您的申请;我没有Spring的经验,所以在这方面我帮不了你。您还可以将spring的整个关闭序列注册到hadoop的 ShutdownHookManager ,使用非常高的优先级来确保spring的关闭序列位于关闭队列的第一位。
具体回答这一部分:
有没有推荐的方法来管理文件系统的生命周期?
建议的方法通常是不管理它,让系统为您做。每当你试图自己管理它的时候,就会有龙,所以要小心行事。

相关问题