0x00 前言
資料倉庫體系裡面的主要内容也寫的差不多了,現在補一點之前遺漏的點。這一篇就來聊一下 ETL。
文章結構
- 先聊一下什麼是 ETL。 聊一下大緻的概念和一般意義上的了解。
- 聊一聊資料流是什麼樣子。因為 ETL 的工作主要會展現在一條條的資料處理流上,是以這裡做一個說明。
- 舉個具體的例子來說明。
0x01 什麼是 ETL
ETL,是英文 Extract-Transform-Load 的縮寫,用來描述将資料從來源端經過抽取(extract)、轉換(transform)、加載(load)至目的端的過程。
嗯,怎麼了解 ETL 這個東西呢?直接上一個網上搜到的招聘資訊看一下:
職位名稱: ETL工程師
職位職責:
- 負責ETL系統研發和對外支援工作;
- 設計科學的資料抽取、轉換、加載的工作流程,保證資料及時、正确地抽取到數倉中;
- 負責安排ETL工程流程的排程和成功執行;
- 協調資料模組化建立風控模型、對資料進行挖掘、優化及統計。
職位要求:
- 熟練掌握數倉方法論,了解次元模組化;
- 熟悉hadoop,hive,hbase,spark,flume等工作原理;熟悉kettle,informatica,sqoop等工作;
- 精通hive文法,熟練SQL優化,熟悉python/shell等一種腳本語言;掌握mysql,oracle,sqlserver等資料庫;
- 有網際網路大資料平台資料開發經驗優先。
看上面的要求,有幾個點可以關注一下:
- 數倉的理論
- 計算引擎:Hadoop、Spark、Hive
- 資料同步:Flume、Sqoop、Kettle
- 存儲引擎:Mysql、Oracle、Hbase等存儲平台
我們大緻分析一下這些内容。首先說數倉的理論,這個在前面的部落格也都有提到,很重要,從理論上指導了怎麼來進行資料處理。存儲引擎也就不提了。這兩者不太算是 ETL 的範疇。
那就聊一下計算引擎和資料同步的工具。我們可以大緻了解 ETL 的主要工作就是利用這些工具來對資料進行處理。下面舉幾個栗子來說明 ETL 的場景:
- Nginx 的日志可以通過 Flume 抽取到 HDFS 上。
- Mysql 的資料可以通過 Sqoop 抽取到 Hive 中,同樣 Hive 的資料也可以通過 Sqoop 抽取到 Mysql 中。
- HDFS 上的一些資料不規整,有很多垃圾資訊,可以用 Hadoop 或者 Spark 進行處理并重新存入 HDFS 中。
- Hive 的表也可以通過 Hive 再做一些計算生成新的 Hive 表。
這些都算是 ETL,其中 1 和 2 都比較典型,它們把資料從一個存儲引擎轉移到另一個存儲引擎,在轉移的過程中做了一定的轉換操作。 3 和 4 也同樣是 ETL 隻是它們更側重的是資料的加工。
到了這一步,我們不再糾結于具體的 ETL 概念是什麼,僅從自己的直覺了解上來定義 ETL,不管嚴謹不嚴謹,反正這些活 ETL 工程師基本都要幹。
ETL 是對資料的加工過程,它包括了資料抽取、資料清洗、資料入庫等一系列操作,大部分和資料處理清洗相關的操作都可以算是 ETL。
0x02 資料流長什麼樣子
舉個栗子
舉個簡單的栗子,下面是一個種資料流的設計,藍色的框框代表的是資料來源,紅色的框框主要是資料計算平台,綠色的 HDFS 是我們一種主要的資料存儲,Hive、Hbase、ES這些就不再列出來了。
資料流的分類
我們常說的資料流主要分兩種:
- 離線資料
- 實時資料
其中離線資料一般都是 T+1 的模式,即每天的淩晨開始處理前一天的資料,有時候可能也是小時級的,技術方案的話可以用 Sqoop、Flume、MR 這些。實時資料一般就是指實時接入的資料,一般是分鐘級别以下的資料,常用的技術方案有 Spark Streaming 和 Flink。
現在的大部分資料流的設計都會有離線和實時相結合的方案,即 Lambda 架構,感興趣的同學可以了解一下。
0x03 舉個栗子
前段時間和一個哥們再聊資料流的設計,正好這裡大概描述一下場景和解決方案。
一、場景
- 資料源主要為 Mysql,希望實時同步 Mysql 資料到大資料叢集中(肯定是越快越好)。
- 目前每日 20 億資料,可遇見的一段時間後的規模是 100 億每日以上。
- 能快速地查到最新的資料,這裡包含兩部分含義:從 Mysql 到大資料叢集的速度快、從大資料叢集中查詢的速度要快。
二、方案選型
遇到這個場景的時候,根據經驗我們主要考慮下面兩個點:資料抽取引擎和存儲引擎。
資料抽取引擎
這裡我們主要考慮兩種方案:
- Sqoop 定時抽取 Mysql 資料到 HDFS 中,可以每天全量抽取一份,也可以隔段時間就抽取一份變更的資料。
- Canal 監聽 Mysql 的 binlog 日志,相當于是 Mysql 有一條資料久變動,我們就抽取一條資料過來。
優缺點的對比也很明顯:
- Sqoop 相對比較通用一些,不管是 Mysql 還是 PostgreSql都可以用,而且很成熟。但是實時性較差,每次相當于是啟動一個 MR 的任務。
- Canal 速度很快,但是隻能監聽 Mysql 的日志。
存儲引擎
存儲引擎主要考慮 HDFS、Hbase 和 ES。
一般情況下,HDFS 我們盡量都會儲存一份。主要糾結的就是 Hbase 和 ES。本來最初是想用 Hbase 來作為實時查詢的,但是由于考慮到會有實時檢索的需求,就暫定為ES
三、方案設計
最終,我們使用了下面的方案。
- 使用 Canal 來實時監聽 Mysql 的資料變動
- 使用 Kafka 作為消息中間件,主要是為了屏蔽資料源的各種變動。比如以後即使用 Flume 了,我們架構也不用大變
- 資料落地,有一份都會落地 HDFS,這裡使用 Spark Streaming,算是準實時落地,而且友善加入處理邏輯。在 落地 ES 的時候可以使用 Spark Streaming,也可以使用 Logstach,這個影響不大
四、一些問題
有兩個小問題列一下。
- 小檔案,分鐘級别的檔案落地,肯定會有小檔案的問題,這裡要考慮的是,小檔案的處理盡量不要和資料接入流程耦合太重,可以考慮每天、每周、甚至每月合并一次小檔案。
- 資料流的邏輯複雜度問題,比如從 Kafka 落地 HDFS 會有一個取舍的考慮,比如說,我可以在一個 SS 程式中就分别落地 HDFS 和 ES,但是這樣的話兩條流就會有大的耦合,如果 ES 叢集卡住,HDFS 的落地也會受到影響。但是如果兩個隔開的話,就會重複消費同一份資料兩次,會有一定網絡和計算資源的浪費。
0xFF 總結
仔細想了一下,資料流應該是我做的最多的一塊了,但是總結的時候感覺又有很多東西說不清楚,先大緻寫一點吧。
前段時間太忙,周末也休息不足,趕快補一篇出來。