java - 如何找到哪个 Java/Scala 线程锁定了一个文件?

标签 java scala apache-spark hive

简述:

  1. 如何找到哪个 Java/Scala 线程锁定了一个文件? 我知道 JVM 中的一个类/线程锁定了一个具体文件(与文件区域重叠),但我不知道如何锁定。当我在断点处停止应用程序时,可以找出哪个类/线程正在执行此操作?

以下代码抛出 OverlappingFileLockException :

FileChannel.open(Paths.get("thisfile"), StandardOpenOption.APPEND).tryLock().isValid();
FileChannel.open(Paths.get("thisfile"), StandardOpenOption.APPEND).tryLock()..isShared();
  1. Java/Scala 如何锁定这个文件 (Spark)?我知道如何使用 java.nio.channels 锁定文件,但我没有在 github repository of Spark 中找到合适的调用.


关于我的问题的更多信息: 1. 当我在带有 Hive 的 Windows 操作系统中运行 Spark 时它工作正常,但是每次 Spark 关闭时,它无法删除一个临时目录(之前的其他临时目录被正确删除)并输出以下异常:

2015-12-11 15:04:36 [Thread-13] INFO  org.apache.spark.SparkContext - Successfully stopped SparkContext
2015-12-11 15:04:36 [Thread-13] INFO  o.a.spark.util.ShutdownHookManager - Shutdown hook called
2015-12-11 15:04:36 [Thread-13] INFO  o.a.spark.util.ShutdownHookManager - Deleting directory C:\Users\MyUser\AppData\Local\Temp\spark-9d564520-5370-4834-9946-ac5af3954032
2015-12-11 15:04:36 [Thread-13] INFO  o.a.spark.util.ShutdownHookManager - Deleting directory C:\Users\MyUser\AppData\Local\Temp\spark-42b70530-30d2-41dc-aff5-8d01aba38041
2015-12-11 15:04:36 [Thread-13] ERROR o.a.spark.util.ShutdownHookManager - Exception while deleting Spark temp dir: C:\Users\MyUser\AppData\Local\Temp\spark-42b70530-30d2-41dc-aff5-8d01aba38041
java.io.IOException: Failed to delete: C:\Users\MyUser\AppData\Local\Temp\spark-42b70530-30d2-41dc-aff5-8d01aba38041
    at org.apache.spark.util.Utils$.deleteRecursively(Utils.scala:884) [spark-core_2.11-1.5.0.jar:1.5.0]
    at org.apache.spark.util.ShutdownHookManager$$anonfun$1$$anonfun$apply$mcV$sp$3.apply(ShutdownHookManager.scala:63) [spark-core_2.11-1.5.0.jar:1.5.0]
    at org.apache.spark.util.ShutdownHookManager$$anonfun$1$$anonfun$apply$mcV$sp$3.apply(ShutdownHookManager.scala:60) [spark-core_2.11-1.5.0.jar:1.5.0]
    at scala.collection.mutable.HashSet.foreach(HashSet.scala:78) [scala-library-2.11.6.jar:na]
    at org.apache.spark.util.ShutdownHookManager$$anonfun$1.apply$mcV$sp(ShutdownHookManager.scala:60) [spark-core_2.11-1.5.0.jar:1.5.0]
    at org.apache.spark.util.SparkShutdownHook.run(ShutdownHookManager.scala:264) [spark-core_2.11-1.5.0.jar:1.5.0]
    at org.apache.spark.util.SparkShutdownHookManager$$anonfun$runAll$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(ShutdownHookManager.scala:234) [spark-core_2.11-1.5.0.jar:1.5.0]
    at org.apache.spark.util.SparkShutdownHookManager$$anonfun$runAll$1$$anonfun$apply$mcV$sp$1.apply(ShutdownHookManager.scala:234) [spark-core_2.11-1.5.0.jar:1.5.0]
    at org.apache.spark.util.SparkShutdownHookManager$$anonfun$runAll$1$$anonfun$apply$mcV$sp$1.apply(ShutdownHookManager.scala:234) [spark-core_2.11-1.5.0.jar:1.5.0]
    at org.apache.spark.util.Utils$.logUncaughtExceptions(Utils.scala:1699) [spark-core_2.11-1.5.0.jar:1.5.0]
    at org.apache.spark.util.SparkShutdownHookManager$$anonfun$runAll$1.apply$mcV$sp(ShutdownHookManager.scala:234) [spark-core_2.11-1.5.0.jar:1.5.0]
    at org.apache.spark.util.SparkShutdownHookManager$$anonfun$runAll$1.apply(ShutdownHookManager.scala:234) [spark-core_2.11-1.5.0.jar:1.5.0]
    at org.apache.spark.util.SparkShutdownHookManager$$anonfun$runAll$1.apply(ShutdownHookManager.scala:234) [spark-core_2.11-1.5.0.jar:1.5.0]
    at scala.util.Try$.apply(Try.scala:191) [scala-library-2.11.6.jar:na]
    at org.apache.spark.util.SparkShutdownHookManager.runAll(ShutdownHookManager.scala:234) [spark-core_2.11-1.5.0.jar:1.5.0]
    at org.apache.spark.util.SparkShutdownHookManager$$anon$2.run(ShutdownHookManager.scala:216) [spark-core_2.11-1.5.0.jar:1.5.0]
    at org.apache.hadoop.util.ShutdownHookManager$1.run(ShutdownHookManager.java:54) [hadoop-common-2.4.1.jar:na]

我尝试在互联网上搜索,但只找到了 in progress Spark 中的问题(一个用户尝试做一些补丁,但它不起作用,如果我正确理解这个拉取请求的评论)和 SO 中的一些 Unresolved 问题。

看起来问题出在 Utils.scala 的 deleteRecursively() 方法中类(class)。我为此方法设置了断点并将其重写为 Java:

public class Test {
    public static void deleteRecursively(File file) {
        if (file != null) {
            try {
                if (file.isDirectory()) {
                    for (File child : listFilesSafely(file)) {
                        deleteRecursively(child);
                    }
                    //ShutdownHookManager.removeShutdownDeleteDir(file)
                }
            } finally {
                if (!file.delete()) {
                    if (file.exists()) {
                        throw new RuntimeException("Failed to delete: " + file.getAbsolutePath());
                    }
                }
            }
        }
    }

    private static List<File> listFilesSafely(File file) {
        if (file.exists()) {
            File[] files = file.listFiles();
            if (files == null) {
                throw new RuntimeException("Failed to list files for dir: " + file);
            }
            return Arrays.asList(files);
        } else {
            return Collections.emptyList();
        }
    }

    public static void main(String [] arg) {
        deleteRecursively(new File("C:\\Users\\MyUser\\AppData\\Local\\Temp\\spark-9ba0bb0c-1e20-455d-bc1f-86c696661ba3")); 
    }

Spark在此方法的断点处停止,我发现 Spark 的一个线程的 JVM锁定“C:\Users\MyUser\AppData\Local\Temp\spark-9ba0bb0c-1e20-455d-bc1f-86c696661ba3\metastore\db.lck”文件和 Windows Process Explorer还显示 Java 锁定了这个文件。 FileChannel 还显示文件在 JVM 中被锁定。

现在,我必须:

  1. 找出哪个线程/类锁定了这个文件

  2. 找出锁定文件的方法Spark正在使用锁定“metastore\db.lck”,它是什么类以及如何在关机前解锁它

  3. Spark 做一些拉取请求或 Hive在调用 deleteRecursively() 方法之前解锁此文件(“metastore\db.lck”)或至少对问题发表评论

如果您需要任何其他信息,请在评论中询问。

最佳答案

参见 How to find out which thread is locking a file in java?

文件被 Windows 进程锁定。线程可以打开文件进行读写,但是持有文件句柄引用的类负责关闭它。因此,您应该寻找一个对象,而不是一个线程。

参见 How can I figure out what is holding on to unfreed objects?了解具体方法。

关于java - 如何找到哪个 Java/Scala 线程锁定了一个文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34228953/

相关文章:

java - 查询 MongoDB 数组并使用最匹配的元素进行排序

java - 模拟restTemplate getForObject

scala - 如何删除密封特征实现中的重复 case 语句

javascript - 一键禁用按钮后是否有机会获得双击按钮?

java - 结合 java spring/thread 和数据库访问时间关键的 web 应用程序

scala - SBT assembly-plugin 的 PathList 中的 "xs @ _*"是什么意思?

连续产品的Scala解决方案

json - Livy服务器: return a dataframe as JSON?

java - Spark : duplicate stages while using join

scala - sbt 在运行 Spark hello world 代码时出错?