【大數據】hive 刪除臨時文件 .hive-staging_hive


一、.hive-staging_hive 產生的原因:

通過spark-sql、hive-sql、hue等提交select或者insert overwrite等sql到hive時,會產生該目錄,用於臨時存放執行結果,比如insert overwrite會將結果暫存到該目錄下,待任務結束,將結果復制到hive表中。hql任務執行失敗時,這些臨時文件和目錄不會被自動刪除掉,直到有相關的hql執行成功時,才會自動刪掉。

 

二、.hive-staging_hive 會導致的一些問題:

1、如果目標路徑存在臨時文件的話,datax 讀取hdfs數據的時候會報錯,因為 .hive-staging_hive 臨時文件的數據也會被 datax 讀到;

2、有的 .hive-staging_hive 可能會包含很多的臨時文件,占用空間,同時也會造成 namenode 的壓力;

 

三、解決辦法(CDH):

進入hive配置頁面,搜索 hive-site.xml ,找到服務高級配置代碼段(安全閥)和 客戶端高級配置代碼段(安全閥),增加配置:

<property>
    <name>hive.insert.into.multilevel.dirs</name>
    <value>true</value>
    <description>允許生成多級目錄</description>
</property>
<property>
    <name>hive.exec.stagingdir</name>
    <value>/tmp/hive/staging/.hive-staging</value>
    <description>臨時文件暫放目錄</description>
</property>

 

1、hive-site.xml 的 Hive 服務高級配置代碼段(安全閥)

 

 

2、hive-site.xml 的 Hive 客戶端高級配置代碼段(安全閥)

 

 

 

 

四、歷史遺留的 hive-staging 文件處理和定期維護

這邊提供一個 python3.6 腳本,需要注意的是刪除的時候,一般不要刪除今天的臨時文件,因為可能有作業正在使用。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2020/5/7 09:59
# @Author : way
# @Site : 
# @Describe: 清除hive昨日殘留的staging垃圾文件

import time
import datetime
from hdfs import Client

class staging:

    def __init__(self, HDFS_ClIENT):
        """
        :param HDFS_ClIENT: hdfs客戶端連接
        """
        self.client = Client(HDFS_ClIENT)
        self.today_timestamp = int(time.mktime(time.strptime(str(datetime.date.today()), '%Y-%m-%d')))*1000


    # 移動 hive 垃圾文件 foo >> staging_tmp_path
    def move(self, foo, staging_tmp_path):
        filemsg = self.client.status(foo, strict=False)
        if filemsg.get('type') == 'DIRECTORY':
            dirs = self.client.list(foo, status=False)
            for son in dirs:
                if '.hive-staging_hive' in son:
                    src = f'{foo}/{son}'
                    dst = f'{staging_tmp_path}/{son}'
                    # print(src, dst)
                    self.client.rename(src, dst)
                    print(f"{son} has moved to {dst} success")
                else:
                    self.move(foo + '/' + son, staging_tmp_path)


    # 移除 昨天的垃圾文件
    def delete(self, staging_tmp_path):
        dirs = self.client.list(staging_tmp_path, status=False)
        for dir in dirs:
            target = staging_tmp_path + '/' + dir
            modificationTime = self.client.status(target, strict=False).get('modificationTime')
            if '.hive-staging_hive' in dir and modificationTime < self.today_timestamp:
                # print(target)
                self.client.delete(target, recursive=True)
                print(f"{target} has been deleted success")


if __name__ == "__main__":
    HDFS_ClIENT = "http://172.16.122.21:50070;http://172.16.122.24:50070"
    staging_tmp_path = '/tmp/hive/staging'
    stag = staging(HDFS_ClIENT)
    # 移動 hive 垃圾文件 foo >> staging_tmp_path
    # foo = '/user/hive/warehouse'
    # stag.move(foo, staging_tmp_path)
    # 移除 昨天的垃圾文件
    stag.delete(staging_tmp_path)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM