1. 程式人生 > >【資料倉庫】6. ETL 的設計

【資料倉庫】6. ETL 的設計

0x00 前言

資料倉庫體系裡面的主要內容也寫的差不多了,現在補一點之前遺漏的點。這一篇就來聊一下 ETL。

文章結構

  1. 先聊一下什麼是 ETL。 聊一下大致的概念和一般意義上的理解。
  2. 聊一聊資料流是什麼樣子。因為 ETL 的工作主要會體現在一條條的資料處理流上,因此這裡做一個說明。
  3. 舉個具體的例子來說明。

0x01 什麼是 ETL

ETL,是英文 Extract-Transform-Load 的縮寫,用來描述將資料從來源端經過抽取(extract)、轉換(transform)、載入(load)至目的端的過程。

嗯,怎麼理解 ETL 這個東西呢?直接上一個網上搜到的招聘資訊看一下:

職位名稱: ETL工程師

職位職責:

  1. 負責ETL系統研發和對外支援工作;
  2. 設計科學的資料抽取、轉換、載入的工作流程,保證資料及時、正確地抽取到數倉中;
  3. 負責安排ETL工程流程的排程和成功執行;
  4. 協調資料建模建立風控模型、對資料進行挖掘、優化及統計。

職位要求:

  1. 熟練掌握數倉方法論,理解維度建模;
  2. 熟悉hadoop,hive,hbase,spark,flume等工作原理;熟悉kettle,informatica,sqoop等工作;
  3. 精通hive語法,熟練SQL優化,熟悉python/shell等一種指令碼語言;掌握mysql,oracle,sqlserver等資料庫;
  4. 有網際網路大資料平臺數據開發經驗優先。

看上面的要求,有幾個點可以關注一下:

  • 數倉的理論
  • 計算引擎:Hadoop、Spark、Hive
  • 資料同步:Flume、Sqoop、Kettle
  • 儲存引擎:Mysql、Oracle、Hbase等儲存平臺

我們大致分析一下這些內容。首先說數倉的理論,這個在前面的部落格也都有提到,很重要,從理論上指導了怎麼來進行資料處理。儲存引擎也就不提了。這兩者不太算是 ETL 的範疇。

那就聊一下計算引擎和資料同步的工具。我們可以大致理解 ETL 的主要工作就是利用這些工具來對資料進行處理。下面舉幾個栗子來說明 ETL 的場景:

  1. Nginx 的日誌可以通過 Flume 抽取到 HDFS 上。
  2. Mysql 的資料可以通過 Sqoop 抽取到 Hive 中,同樣 Hive 的資料也可以通過 Sqoop 抽取到 Mysql 中。
  3. HDFS 上的一些資料不規整,有很多垃圾資訊,可以用  Hadoop 或者 Spark 進行處理並重新存入 HDFS 中。
  4. Hive 的表也可以通過 Hive 再做一些計算生成新的 Hive 表。

這些都算是 ETL,其中 1 和 2 都比較典型,它們把資料從一個儲存引擎轉移到另一個儲存引擎,在轉移的過程中做了一定的轉換操作。 3 和 4 也同樣是 ETL 只是它們更側重的是資料的加工。

到了這一步,我們不再糾結於具體的 ETL 概念是什麼,僅從自己的直觀理解上來定義 ETL,不管嚴謹不嚴謹,反正這些活 ETL 工程師基本都要幹。

ETL 是對資料的加工過程,它包括了資料抽取、資料清洗、資料入庫等一系列操作,大部分和資料處理清洗相關的操作都可以算是 ETL。

0x02 資料流長什麼樣子

舉個栗子

舉個簡單的栗子,下面是一個種資料流的設計,藍色的框框代表的是資料來源,紅色的框框主要是資料計算平臺,綠色的 HDFS 是我們一種主要的資料儲存,Hive、Hbase、ES這些就不再列出來了。

 

資料流的分類

我們常說的資料流主要分兩種:

  1. 離線資料
  2. 實時資料

其中離線資料一般都是 T+1 的模式,即每天的凌晨開始處理前一天的資料,有時候可能也是小時級的,技術方案的話可以用 Sqoop、Flume、MR 這些。實時資料一般就是指實時接入的資料,一般是分鐘級別以下的資料,常用的技術方案有 Spark Streaming 和 Flink。

現在的大部分資料流的設計都會有離線和實時相結合的方案,即 Lambda 架構,感興趣的同學可以瞭解一下。

0x03 舉個栗子

前段時間和一個哥們再聊資料流的設計,正好這裡大概描述一下場景和解決方案。

一、場景

  1. 資料來源主要為 Mysql,希望實時同步 Mysql 資料到大資料叢集中(肯定是越快越好)。
  2. 目前每日 20 億資料,可遇見的一段時間後的規模是 100 億每日以上。
  3. 能快速地查到最新的資料,這裡包含兩部分含義:從 Mysql 到大資料叢集的速度快、從大資料叢集中查詢的速度要快。

二、方案選型

遇到這個場景的時候,根據經驗我們主要考慮下面兩個點:資料抽取引擎和儲存引擎。

資料抽取引擎

這裡我們主要考慮兩種方案:

  1. Sqoop 定時抽取 Mysql 資料到 HDFS 中,可以每天全量抽取一份,也可以隔段時間就抽取一份變更的資料。
  2. Canal 監聽 Mysql 的 binlog 日誌,相當於是 Mysql 有一條資料久變動,我們就抽取一條資料過來。

優缺點的對比也很明顯:

  • Sqoop 相對比較通用一些,不管是 Mysql 還是 PostgreSql都可以用,而且很成熟。但是實時性較差,每次相當於是啟動一個 MR 的任務。
  • Canal 速度很快,但是隻能監聽 Mysql 的日誌。

儲存引擎

儲存引擎主要考慮 HDFS、Hbase 和 ES。

一般情況下,HDFS 我們儘量都會儲存一份。主要糾結的就是 Hbase 和 ES。本來最初是想用 Hbase 來作為實時查詢的,但是由於考慮到會有實時檢索的需求,就暫定為ES

三、方案設計

最終,我們使用了下面的方案。

 

  1. 使用 Canal 來實時監聽 Mysql 的資料變動
  2. 使用 Kafka 作為訊息中介軟體,主要是為了遮蔽資料來源的各種變動。比如以後即使用 Flume 了,我們架構也不用大變
  3. 資料落地,有一份都會落地 HDFS,這裡使用 Spark Streaming,算是準實時落地,而且方便加入處理邏輯。在 落地 ES 的時候可以使用 Spark Streaming,也可以使用 Logstach,這個影響不大

四、一些問題

有兩個小問題列一下。

  1. 小檔案,分鐘級別的檔案落地,肯定會有小檔案的問題,這裡要考慮的是,小檔案的處理儘量不要和資料接入流程耦合太重,可以考慮每天、每週、甚至每月合併一次小檔案。
  2. 資料流的邏輯複雜度問題,比如從 Kafka 落地 HDFS 會有一個取捨的考慮,比如說,我可以在一個 SS 程式中就分別落地 HDFS 和 ES,但是這樣的話兩條流就會有大的耦合,如果 ES 叢集卡住,HDFS 的落地也會受到影響。但是如果兩個隔開的話,就會重複消費同一份資料兩次,會有一定網路和計算資源的浪費。

轉載