一個典型的企業資料倉庫通常包含資料采集、資料加工和存儲、資料展現等幾個過程,本篇文章将按照這個順序記錄部門目前建設資料倉庫的過程。
采集資料之前,先要定義資料如何存放在 hadoop 以及一些相關限制。限制如下:
所有的日志資料都存放在 hdfs 上的 <code>/logroot</code> 路徑下面
hive 中資料庫命名方式為 <code>dw_xxxx</code>,例如:dw_srclog 存放外部來源的原始資料,dw_stat 存放統計結果的資料
原始資料都加工成為結構化的文本檔案,字段分隔符統一使用制表符,并在 lzo 壓縮之後上傳到 hdfs 中。
hive 中使用外部表儲存資料,資料存放在 <code>/logroot</code> 下,如果不是分區表,則檔案名為表名;如果是分區表,則按月和天分區,每天分區下的檔案名為<code>表名_日期</code>,例如:<code>test_20141023</code>
資料采集的來源可能是關系資料庫或者一些系統日志,采集工具可以是日志采集系統,例如:flume、sqoop 、storm以及一些 etl 工具等等。
目前,主要是從 mysql 中導出資料然後在導入到 hdfs 中,對于存儲不需要按天分區的表,這部分過程代碼如下:
上面 bash 代碼邏輯如下:
1、判斷是否輸入參數,如果沒有參數,則取昨天,意思是每天讀取 mysql 資料庫中昨天的資料。
2、定義 mysql 中 select 查詢語句
3、定義 hive 中建表語句
4、讀取 mysql 資料庫連接配接資訊,上例中為從 db_name.sql 中讀取 <code>db_host</code>、<code>db_user</code>、<code>db_pass</code>、<code>db_port</code>、<code>db_name</code> 五個變量
5、運作 mysql 指令導出指定 sql 查詢的結果,并将結果中的 null 字段轉換為 <code>\\n</code>,因為 <code>\</code> 在 bash 中是轉義字元,故需要使用兩個 <code>\</code>
6、lzo 壓縮檔案并上傳到 hdfs,并且建立 lzo 索引
7、最後删除本地檔案
對于分區表來說,建表語句如下:
從 mysql 導出檔案并上傳到 hdfs 指令如下:
通過上面的兩個指令就可以實作将 mysql 中的資料導入到 hdfs 中。
這裡需要注意以下幾點:
1、 hive 中原始日志使用預設的 textfile 方式存儲,是為了保證日志的可讀性,友善以後從 hdfs 下載下傳來之後能夠很友善的轉換為結構化的文本檔案并能浏覽檔案内容。
2、使用 lzo 壓縮是為了節省存儲空間
3、使用外包表建表,在删除表結構之後資料不會删,友善修改表結構和分區。
使用 sqoop 主要是用于從 oracle 中通過 jdbc 方式導出資料到 hdfs,sqoop 指令如下:
對于資料量比較小任務可以使用 impala 處理,對于資料量大的任務使用 hive hql 來處理。
impala 處理資料:
有時候需要使用 impala 導出資料:
使用 hive 處理資料生成結果表:
這裡主要是先判斷是否建立外包表(外包表存儲為 rcfile 格式),然後設定 map 的輸出結果使用 snappy 壓縮,并設定每個 map 的大小,最後運作 insert 語句。結果表存儲為 rcfile 的原因是,在 cdh 5.2 之前,該格式的表可以被 impala 讀取。
當任務多了之後,每個任務之間會有一些依賴,為了保證任務的先後執行順序,這裡使用的是 azkaban 任務排程架構。
該架構的使用方式很簡單:
首先建立一個 bi_etl 目錄,用于存放執行腳本。
在 bi_etl 目錄下建立一個 properties 檔案,檔案名稱任意,檔案内容為:<code>day=yesterday</code>,這是一個系統預設參數,即預設 day 變量的值為 yesterday,該變量在運作時可以被覆寫:在 azkaban 的 web 管理界面,運作一個 flow 時,添加一個 <code>flow parameters</code> 參數,name 為 day,value 為你想要指定的值,例如:20141023。
建立一個 bash 腳本 test.sh,檔案内容如第一章節内容,需要注意的是該腳本中會判斷是否有輸出參數。
針對 bash 腳本,建立 azkaban 需要的 job 檔案,檔案内容如下(azkaban 運作該 job 時候,會替換 <code>${day}</code> 變量為實際的值 ):
最後,将 bi_etl 目錄打包成 zip 檔案,然後上傳到 azkaban 管理界面上去,就可以運作或者是設定排程任務了。
使用上面的方式編寫 bash 腳本和 azkaban 的 job 的好處是:
azkaban 的 job 可以指定參數來控制運作哪一天的任務
job 中實際上運作的是 bash 腳本,這些腳本脫離了 azkaban 也能正常運作,同樣也支援傳參數。
目前是将 hive 或者 impala 的處理結果推送到關系資料庫中,由傳統的 bi 報表工具展示資料或者直接通過 impala 查詢資料生成報表并發送郵件。
為了保證報表的正常發送,需要監控任務的正常運作,當任務失敗的時候能夠發送郵件,這部分通過 azkaban 可以做到。另外,還需要監控每天運作的任務同步的記錄數,下面腳本是統計記錄數為0的任務:
上面介紹了資料采集、加工和任務排程的過程,有些地方還可以改進:
引入 etl 工具實作關系資料庫導入到 hadoop,例如:kettle 工具
目前是每天一次從 mysql 同步資料到 hadoop,以後需要修改同步頻率,做到更實時
hive 和 impala 在字段類型、存儲方式、函數的相容性上存在一些問題