本次項目是基於企業大數據的電商經典案例項目(大數據日誌以及網站數據分析),業務分析、技術選型、架構設計、集羣規劃、安裝部署、整合繼承與開發和web可視化交互設計。
1.系統數據流程設計
我這裏主要分享下系統數據大致流通的過程。
電商數據來源爲兩部分:
第一部分是java以及前端等程序員在網站做的埋點,用戶點擊產生的日誌數據,通過springboot以及nginx等將數據分發到日誌服務器。這裏我們直接寫了一個java程序,模擬產生了大量數據,結果直接保存在服務器上。
第二部分是網站業務的數據,一般保存在mysql數據庫上面。
數據傳輸流程:
日誌數據通過flume收集,然後保存在kafka中。再通過flume傳輸到hdfs上。
業務數據直接通過sqoop導入到hdfs上。
數據處理流程:
編寫hql以及腳本程序,並放在azakban上作爲每日定時任務,將最後結果導入mysql數據庫上面。
數據展示流程:
java及前端程序員編寫,在頁面上展示處理完成後放在mysql上的數據。
後期擴展:
kafka中保存的內容可以讓spark streaming來消費,進行實時處理。hdfs上的數據也可以利用presto,druid進行近實時查詢。
2.軟件使用的版本如下:
注:大數據的軟件爲apache下的。
hadoop : 2.7.2
flume: 1.7.0
kafka:0.11.0.2
kafka manager:1.3.3.22
hive:1.2.1
sqoop:1.4.6
mysql:5.6.24
azkaban:2.5.0
java:1.8
zookeeper:3.4.10
presto:0.189
3.集羣服務器部署:
服務名稱 |
子服務 |
服務器 hadoop102 |
服務器 hadoop103 |
服務器 hadoop104 |
HDFS |
NameNode |
√ |
|
|
DataNode |
√ |
√ |
√ |
|
SecondaryNameNode |
|
|
√ |
|
Yarn |
NodeManager |
√ |
√ |
√ |
Resourcemanager |
|
√ |
|
|
Zookeeper |
Zookeeper Server |
√ |
√ |
√ |
Flume(採集日誌) |
Flume |
√ |
√ |
|
Kafka |
Kafka |
√ |
√ |
√ |
Flume(消費Kafka) |
Flume |
|
|
√ |
Hive |
Hive |
√ |
|
|
MySQL |
MySQL |
√ |
|
|
Sqoop |
Sqoop |
√ |
|
|
Presto |
Coordinator |
√ |
|
|
Worker |
|
√ |
√ |
|
Azkaban |
AzkabanWebServer |
√ |
|
|
AzkabanExecutorServer |
√ |
|
|
|
Druid |
Druid |
√ |
√ |
√ |
服務數總計 |
|
13 |
8 |
9 |
4.技術點大致解析:
flume採集日誌:
1.flume採用的1.7.0版本,此版本的source更新了一個Taildir Source。這個source相比exec source和spooling directory source的優點在於:
Taildir Source支持斷點續傳,多目錄。因爲會有一個文件專門記錄讀取的文件內容到哪裏了。
2.自定義了ETL攔截器和分類型攔截器。
ETL攔截器實現了簡單的數據過濾和清洗。注意複雜的清洗還是在hive中清洗,flume只適合做一些最簡單的清洗,因爲它在複雜的數據清洗上性能並不是很好。
分類型攔截器主要是對數據進行分發到kafka不同的topic中去,所以需要配置不同通道的selector。
3.flume採集日誌的channel並不是file channel或者memory channel而是kafka channel,配置了kafka channel之後並不需要配置sink。
flume消費kafka中數據:
這裏了爲什麼會增加一層kafka和一層flume而不是直接由flume採集日誌直接到hdfs上了?因爲考慮到後期採集的日期數據可能會重複利用,比如做實時計算。難道需要又重新搭建flume來採集嗎?顯然既耗時又浪費集羣資源。所以統一保存在kafka中,其他業務有需求直接從kafka中取數據就行了。現在就是用flume從kafka中取得數據保存在hdfs上。
數據倉庫的理論:
數據倉庫一般分爲4層。
ods:原始數據層。數據收集後直接保存在hdfs上,未做任何處理。
dwd:數據明細層。數據經過了etl清洗。
dws:服務數據層。數據經過一些分類聚合,輕度彙總。
ads:數據應用層。提供各種分析的報表結果進行展示。
數倉建模:事實表,維度表,事務型事實表,週期型事務表,星型模型。
hadoop安裝配置:
支持lzo,snappy壓縮,一般hive表配置爲外部表,snappy壓縮,orc格式。
hive的搭建:
hive這裏主要想說明的是hql其實就是mapreduce,如果hql複雜,啓動幾個mapreduce的時候,中間結果會保存在磁盤,然後再從磁盤上讀取結果進行下一個mapreduce計算,這樣太浪費時間了。所以將hive的計算引擎從mapreduce換成了tez,tez是基於內存來計算的,所以中間結果直接保存在內存中,計算效率大大增加。
hive自定義函數:
hive自定義函數有三種。
udf:一對一。輸入一個值輸出一個值。
udtf:一對多或者多對多。輸入一個值或多個值輸出多個值,配合later view炸裂數據。
udaf:多對一。輸入多個值輸出一個值。
自定義函數主要是針對有些複雜的字符串,比如json更方便解析。
拉鍊表:
這個重點講解一下。
拉鍊表記錄每天信息的生命週期,一旦一條信息的生命週期結束,就重新開始一條新的紀錄,並把當前日期放入生效開始日期。
舉個例子,比如某一條訂單,可能客戶2019.01.01下單了,但是他當天沒支付,訂單就是未支付狀態。這條數據同步到數據倉庫後就保存下來了,這條數據(訂單狀態:未支付)的生效開始日期是2019.01.01,結束日期也是9999.99.99,因爲不知道什麼時候它的狀態改變,所以給與一個最大值。第二天,用戶支付了,同步到數據倉庫後,第一天未支付的訂單的狀態是未支付就過期了,這條數據也就失效了,所以這條數據(訂單狀態:未支付)的生效開始日期是2019.01.01,結束日期也是2019.01.01。同時新增一條數據(訂單狀態:已支付)的生效開始日期是2019.01.02,結束日期也是9999.99.99。第三天,商家收到訂單後準備發貨但是還沒有發貨,同步到數據倉庫後,第二天未支付的訂單的狀態是已支付就過期了,這條數據也就失效了,所以這條數據(訂單狀態:已支付)的生效開始日期是2019.01.02,結束日期也是2019.01.02。同時新增一條數據(訂單狀態:未發貨)的生效開始日期是2019.01.03,結束日期也是9999.99.99。接下來一直到2019年12月12日,商家才發貨,此時和前面邏輯一樣修改狀態爲未支付的訂單數據,同時新增狀態爲已完成的數據。
爲什麼要這麼做了?每條數據都給與一個生效開始時間,生效結束時間?原因一,保存在數倉中的數據是不能更改的,也就是說訂單狀態是不能修改的,所以必須記錄這條數據在什麼時間段內有效。原因二,像剛纔所說的,如果商家拖了12個月才發貨,難道每天都記錄一條未發貨的訂單數據了,沒有必要,造成以後的數據分析會有大量冗餘垃圾數據,還要去清洗。所以只需要記錄一下未支付從哪天開始有效,哪天無效就行了。至於拉鍊表如何實現了,這裏我就不多說了,但是肯定需要一張臨時表來配合。
spark streaming:這部分可以看我另一篇博文https://blog.csdn.net/a790439710/article/details/103173099
sqoop:沒什麼好說的。
azkaban:沒什麼好說的。