日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

arcengine遍历属性表_记录一次Hive表清理过程

發布時間:2025/3/20 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 arcengine遍历属性表_记录一次Hive表清理过程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

記錄一次Hive表清理過程

背景

時間:2020-07-17

在用spark+hive做數倉的過程中往往會產生很多表,過多歷史表會很快消耗掉有限的hdfs資源,并且時間過于久遠的表一般不會具有利用價值了,如果不及時清理這部分hive表會造成hdfs資源的嚴重浪費,因此需要有一個類似于HiveClean的定時任務,執行定期清理舊數據的邏輯。

動機

在接手這個功能需求的時候,已經有了一個HiveClean的版本,基本的清理邏輯如下:

  • 遍歷所有需要清理的hive表
  • 執行ALTER TABLE $cluster%s.$table%s SET TBLPROPERTIES('external'='false')來把hive外部表轉換成hive內部表

ps:如果直接刪除外部表,只會從hive metastore中刪除外部表的元數據,而對應的物理文件依然存放在hdfs中,沒有達成我們的目的

  • 篩選出需要刪除的表分區,執行ALTER TABLE $cluster%s.$table%s DROP PARTITION (time_hour='xxx')來刪除對應的分區

現在的需求是改進這個邏輯:注意上面的最后一步,刪除分區的方式是一個一個刪除,想看看能不能用范圍刪除的方式來清理舊分區

問題

  • 一開始了解到hive是原生支持分區范圍刪除的:ALTER TABLE $cluster%s.$table%s DROP PARTITION (time_hour<'xxx'),但是事情并沒有那么簡單:在hive執行沒有問題,但是Spark SQL引擎并不支持
  • spark-sql> ALTER TABLE xxx DROP PARTITION (time_hour<2020060110); Error in query: mismatched input '<' expecting {')', ','}(line 1, pos 54) == SQL == ALTER TABLE xxx DROP PARTITION (time_hour<2020060110) ------------------------------------------------------^^^ spark-sql>

    這是Spark SQL自身的局限性

  • 雖然這個想法不可行,但是在研究的過程中發現了HiveClean邏輯的錯誤,問題復現如下:
  • 按照參數的設置,HiveClean定時任務會在每天的下午某個時間點執行,并且清理的是45天以前的舊分區
  • 但是遍歷HDFS文件目錄可以發現,有一些Hive表45天前的分區中的物理文件雖然不存在了,但是分區目錄還在;還有另一些Hive表干脆連45天前的物理文件還完好無損(后來分析猜測是有些表手工設置為了內部表,而后來新增的表沒有設置)
  • 在hive中執行SHOW PARTITIONS xxx時顯示的分區確實只有45天以內的(從后面的分析可以知道這是刪除外部表的結果,元數據刪除了但是物理文件還在)
  • 從上面的問題現象中可以很自然地想到可能是Hive內部表和外部表的原因
  • 執行DESC FORMATTED xxx可以查看Hive表的屬性,例如:shell ... ... Type MANAGED Provider hive ... ... Location hdfs://hadoop-hdfs-nn/topics/cluster/xxx ... ...
    上面顯示的Type MANAGED表明Hive表示內部表,如果顯示的是Type EXTERNAL則說明是外部表
  • 在執行上述的命令查看Hive表屬性的時候發現是外部表,但是奇怪的地方就在于每次HiveClean執行的時候,都會先通過ALTER TABLE $cluster%s.$table%s SET TBLPROPERTIES('external'='false')將外部表轉換成內部表,然后再執行分區刪除邏輯,理論上執行一次之后,Hive表就應該是內部表了,而現在來看卻不是這樣,問題出在了哪?
  • 在Stack Overflow上面找到了這樣的回答:
  • How can we convert an external table to managed table in SPARK 2.2.0??stackoverflow.com

    ,有兩個值得關注的回答:

  • 關于上面外部表轉換語句無效的解釋
  • 重點在于下面的評論,先看回答中給出的方案,顯然跟我們現有的HiveClean中的一樣,說是大小寫敏感的問題,但是這是網上流傳甚廣的誤導方案,正確的設置語句應該是大寫的:ALTER TABLE $cluster%s.$table%s SET TBLPROPERTIES('EXTERNAL'='FALSE'),但是如果在spark中執行的話會報錯(hive中當然一點問題都沒有):Error in query: Cannot set or change the preserved property key: 'EXTERNAL';
    現在來看答案下面的解釋,簡單來說就是EXTERNAL是保留字并且大小寫敏感,如果設置的是external那么只會給Hive表新增一條自定義屬性'external',EXTERNAL依然沒有改變(即內外部表的屬性沒變)
    既然改變EXTERNAL的值才行,但Spark中又沒法執行,那怎么辦呢?總不能手工把所有的表全部設置為內部表吧,萬一將來新增了新的表忘記了設置為內部表,又或者希望將內部表轉成外部表,每次都手工設置顯得很不優雅,有什么好方法嗎?別急,也在這個SO的回答中,看下面

  • Spark中外部表轉換內部表的正確姿勢

  • 這個無需多說,無腦照抄就行,親測有效

  • 現在還有點小問題,就是一些表被當做外部表刪除了,metastore中已經沒了45天以前的元數據,因此在后面的分區刪除任務中這些分區依然沒法被刪除,這時候就需要把這些表的分區修復回來,然后在下一次HiveClean定時任務執行時統一把遠古分區給刪掉
  • Hive分區修復命令MSCK用法:MSCK REPAIR TABLE xxx,可以參考這篇文章了解一下MSCK命令:

    一二三沖鴨:一起學Hive——使用MSCK命令修復Hive分區?zhuanlan.zhihu.com

    后續

    但是現在在Spark中按范圍刪除Hive表分區的問題依然沒有解決,反倒歪打正著修復了存在已久的bug。。。

    總結

    以上是生活随笔為你收集整理的arcengine遍历属性表_记录一次Hive表清理过程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。