大數據SRE的總結(4)--基於FsImage的HDFS數據深度分析

謝 @汪涉洋 的邀請,這裡給大家介紹一下之前提到的基於FsImage的HDFS數據分析系統。

雖然稱之為基於fsimage分析系統,其實就是利用hdfs fsimage對裡面文件和目錄的基本數據進行收集,然後將其插入到資料庫,以供進一步分析使用。 這個項目可以讓運維人員通過簡單的SQL對文件數據進行系統分析,從而做出更好的優化和決策。

為了讓大家更進一步了解項目的細節,本文主要從下面幾個方向做介紹:

1. 項目背景

2. 基本架構

3. 實現優化

4. 總結及一些思考

1.項目背景

由於公司數據越來越多,hdfs的存儲空間越來越大,但是效率也越來越低。出現了諸如小文件,冷文件等多種問題。一方面這些問題拖累了hdfs的運行效率,另一方面也使得在優化hdfs時出現了各種技術或者非技術難題,常見的有:

  • 如何說服用戶刪除它的冷數據(尤其是數據量比較大,難以用肉眼觀測時)
  • 如何預測數據的增長和減少,這一點對於普通公司尤其重要,因為一旦集群增長過快,而又沒法在短時間部署新的節點,這將是毀滅性的災難。
  • 如何自動找出需要優化的目錄,減少人工優化的工作(例如 @汪涉洋 之前提到的小文件合併,其中一部分分析的數據就是從這個項目收集得到的)
  • 如何找出突然減少的數據(誤操作或者惡意刪除),尤其是對於用作warehouse 的hdfs集群尤其重要。一旦一個比較大的數據表(例如10T的hive表)被刪除,如果沒有輔助工具,我們很難第一時間找到消失的數據,錯過恢複數據的最佳時間。

諸如這類問題一直困擾著大數據程序員,在我工作的公司也不例外。 因此去年還沒有畢業的我就提前來到公司以實習生的身份開始著手開發這個項目。希望通過這個新的作業,能夠解決或者基本解決上面的問題。

下面我們將詳細介紹這個項目

2. 基本架構

項目在公司內部當時被命名為 hdfs ETL,意思是hdfs fsimage Extract-Transform-Load. 其主要由3個大的模塊組成 :

  1. 解析fsimage,生成基本的文件或者目錄數據(例如大小,修改時間等)
  2. 將1的數據進一步整理,拆成一個star schema的結構,生成幾個不同類型的文件
  3. 將2的文件分別插入到對應的資料庫(impala)表中,用於實際的分析使用。

由上面的模塊可以看出,主要是1和2是我們項目的核心,當然3中impala表的設計也很重要,因為它關係到我們的查詢效率。下面我們依次介紹著三個流程

分析fsimage

我們分析fsimage除了工程上的實現外,主要解決的問題是meta屬性定義的問題。實際上,由於每個集群的需求不同,為了簡化後面的分析,我們對屬性的定義和hdfs meta不完全一樣,這樣就使得我們從fsimage拿到raw data後,需要對其進行聚集。最典型的就是目錄中文件的總文件的大小,顯然這是一個對目錄樹做DFS聚集的過程,儘管我們也可以用諸如

hdfs dfs -du hdfs://<path of director>

之類的命令拿到,但是這樣做有兩個缺點:

  • 查詢時間較慢,需要實時計算
  • 計算運行於namenode,會增大namenode壓力

因此我們在分析fsimage時應該提前對這些數據做好聚集,方便進一步查詢。

這樣由於我們需要dfs整個hdfs 的目錄樹,因此我們需要在內存中構建出一個包含全部

meta的tree,實際上相當於我們構建了一個新的namenode,因此內存開銷是非常大的,一般都是幾十g的級別。

儘管這一步看似簡單,但是實際上由於後來分析的數據全部基於此,因此在考慮聚集計算數據的信息時,一定要根據自己的需求定義相關的欄位和計算方法。

拆分成star schema files

雖然拆分成start

Schema Files是第二個流程,但本質上它是為了插入到資料庫做準備的,因此我們先介紹impala資料庫的設計,然後再介紹第二個流程。具體來說,下圖是我們資料庫的結構

由圖中可以看出,我們將file和directory分開存儲,即 hdfs_file_fact_p和hdfs_dir_fact_p,對於這兩個表中的任意一個表,它都和其他的「dim」表組成一個OLAP的star schema結構,這也是我們第二步名稱的由來。

我們將要查詢的數據(例如 文件大小,文件個數等)放入fact表,並將其按照年月日分區; 而將其他一些屬性(例如文件名等)則放入dim表。 這樣做是為了加速查詢,經過這種拆分,我們的fact表中只會存儲每天變化的數據,最大程度減少冗餘。

除了將數據拆分成star schema file以外,這一步中我們還對新產生的dim數據和歷史dim數據進行了合併,比如,我們對name_dim表中的last_accessed_time進行了更新。此外還有一些 hdfs path name,半年內都沒有存在於hdfs中(例如一年前mapreduce產生的諸如 hdfs://application_cache/01.tmp這種中間文件),我們也會將其從name_dim中刪除,用於降低name_dim的大小,減少查詢時間。

導入到impala

因為我們是一個data-warehouse,因此需要一個資料庫引擎,但是我們又想達到olap的效果。因此我們採用了cloudera公司自己開發的impala資料庫,這個資料庫是於2013年由cloudera公司開始立項開發的,用C++編寫,現在已經是apache頂級項目。之所以選用它,是由於它在hadoop集群中能夠以幾十秒級甚至秒級返回一些大規模的查詢結果。

這裡以我們的data warehouse為例,在約25個impala daemon計算下,對於一個10PB數據規模的hadoop集群,查詢某個文件或者目錄的半個月數據變化,約需要不到10s; 查詢某個目錄內一周來增長最快的10個子目錄,約需要20s。總體上來看查詢速度還是很快的,遠遠快於現場用hdfs指令查詢。

講解完基本架構後,我們來談談其中的一些優化,希望能幫助大家開發類似的工具時少走一些彎路。

3. 實現優化

這部分我們用Q&A的方式來簡單談一下整個項目中一些細節問題,當然如果讀者有一些問題我沒有在下面提到,也歡迎大家來找我交流。

Q: 解析fsimage的作業過多消耗資源怎麼優化?

A: 由於解析fsimage相當於構建了一遍namenode內存,因此資源開銷是比較大的,除了上面提到的大內存外,在實際運行時,我們還發現了這個作業對硬碟的損耗很大,一開始我們是放在一個獨立的機器上運行,發現磁碟每幾個月就會壞一次。所以後來我們將其包裝成一個map-reduce程序,這樣讓yarn幫忙動態申請container,這樣作業會在不同的機器運行,分攤了每個機器的壓力。當然也可以將其打成一個docker file,然後每天定時運行,這樣更方便維護,不過缺少了一些靈活性。

Q: 在資料庫name_dim表設計中,如何設計name_key?

A: 由於hdfs path特別多,因此對於它們的name設計一個好的key是非常重要的,它應當滿足:

  1. 沒有衝突,即不能有兩個不同的path name,它倆是同一個key
  2. 易於計算,由於我們分析fsimage用的java程序,而查詢頁面則是Flask(python)程序,因此這意味著這個key的計算應當支持多個框架且易於計算

這裡我採用的方式先計算hdfs path name 的MD5,得到一個128位的二進位串,然後再將其相鄰兩位異或得到一個64位的long整數,這個就是我們的key。

經過我測試在6PB的集群規模下,並沒有key衝突。而且計算也足夠簡單有效。

Q: 整個job的運行時長是多少?能否有間隔更短(例如小時級別,而不是目前的天級別)的查詢?

A: 整個job運行時間約為2個小時。這樣來看,其實我們可以做到2小時的間隔查詢,但實際使用時發現這個並不是剛需,大多數時候我們還是願意按照天來查詢數據變化,畢竟沒有一個SDE真的會每個小時都看一次數據變化。此外, 我們團隊後來還開發了一個hdfs audit system,通過hdfs audit log來記錄和統計每個小時的變化,可以作為我們這個項目的一個補充。

最後我們展示一下我們前端的最終效果:

按照文件冷熱(即最後訪問時間)分類hdfs 數據

按照文件大小分類hdfs 數據

某個目錄2周內總文件大小的變化趨勢

某個目錄下過去一周增長最快的10個子目錄

由最終的展示效果可以看出,這樣的統計對於hadoop 運維人員是非常有用的,可以十分直觀地看出集群數據規模的變化。

除了上面這些以外,我們團隊後來還基於這個HDFS DATA-WAREHOUSE做了進一步的分析,尤其是針對普通用戶的分析,這些內容將由 @汪涉洋 在後面介紹。

4. 總結及一些思考

項目的價值在於運維人員深度挖掘文件系統內在數據規律,極大地減少運維人員的運維成本,達到了大數據SRE的總結(0)--開篇中提到的「讓一切人的決策基於數據「的運維目標。


推薦閱讀:

在第四範式工作/實習是一種怎樣的體驗?
大數據集怎麼求彼此相似度?
如何成為一名技術型營銷人(Technical Marketer)?
2015年註冊消防工程師掛靠費用一年多少錢,哪些大數據證書掛靠平台上有詳細的分析?

TAG:大数据 | Hadoop | 程序员 |