假设我们有一个 Hive 表作为这样的目录存储在 HDFS 上:
data/
|-- file1
|-- file2
|-- file3
如果我对该目录开始长时间查询然后删除其中一个文件会怎样?
我可以想到 3 种情况:
- 文件描述符在开始时打开,数据一直保留到查询结束,即使文件路径不再可用于新查询。
- Hive 会记住文件路径,如果找不到已删除的文件,查询就会失败。
- Hive 不记住文件路径,只接受当前目录中的文件。
如果 Hive 的行为类似于 (2),并且在查询期间删除文件是不安全的,从被查询目录中删除旧数据的正确方法是什么?
最佳答案
如@Shankarsh 所述,Hive 尝试使用其 Metastore DB 中的“锁定”表来协调其查询。尝试运行 show locks ;
命令,而另一个 session 正在运行一个长的 SELECT 或 INSERT 查询,而另一个 session 试图更改表(必须等到它可以获得独占锁)以查看自己。
不幸的是,这不会阻止 HDFS 直接访问文件和目录。据我所知,HDFS 中只有一种类型的锁,它是一种用于创建/追加/截断文件(或现有文件中的最后一个 block )的独占锁。
典型场景:您提交查询; Hive 在查询编译时检索文件和文件 block 的列表,然后启动一些映射器以从这些 block 中读取;与此同时,另一个作业请求删除其中一个文件 ==> 其中一个映射器将崩溃并出现 FileNotFoundException
(我遇到过这种情况!)
另一个典型场景:......同时另一个作业创建了一个新文件,或者将一个新 block 附加到现有文件 ==> 数据将永远不会被访问——顺便说一下,这并不是一件坏事。
底线:避免删除 Hive 表(无论是托管表还是外部表)使用的 HDFS 目录中的文件除非您可以确保当前没有任何查询正在运行,或者可能即将运行。如果您想一次删除所有 文件,对于托管表,请在表/分区级别使用TRUNCATE
,并让 Hive 执行肮脏的协调工作。
在某些情况下,您可能会尝试一个复杂的技巧,使用具有单个分区的临时表、EXCHANGE PARTITION
Hive 命令(...协调...),然后删除 HDFS 在临时目录中,然后另一个EXCHANGE PARTITION
将所有剩余的文件返回原位——当然,任何在两者之间开始的查询都会看到一个空表,这可能是一个问题。
关于hadoop - Hive:如果我删除当前正在查询的文件会怎样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37322109/