大數據 - DWM層 業務實現

来源:https://www.cnblogs.com/vipsoft/archive/2022/12/29/17000949.html
-Advertisement-
Play Games

DWM 建表,需要看 DWS 需求。 DWS 來自維度(訪客、商品、地區、關鍵詞),為了出最終的指標 ADS 需求指標 DWT 為什麼實時數倉沒有DWT,因為它是歷史的聚集,累積結果,實時數倉中不需要 DWD 不需要加工 DWM 需要加工的數據 統計主題 需求指標【ADS】輸出方式計算來源來源層級 ...


DWM 建表,需要看 DWS 需求。

DWS 來自維度(訪客、商品、地區、關鍵詞),為了出最終的指標
ADS 需求指標
DWT 為什麼實時數倉沒有DWT,因為它是歷史的聚集,累積結果,實時數倉中不需要
DWD 不需要加工
DWM 需要加工的數據

統計主題 需求指標【ADS】輸出方式計算來源來源層級
訪客【DWS】pv可視化大屏page_log 直接可求dwd
UV(DAU)可視化大屏需要用 page_log 過濾去重dwm
跳出率可視化大屏需要通過 page_log 行為判斷dwm
進入頁面數可視化大屏需要識別開始訪問標識dwd
連續訪問時長可視化大屏page_log 直接可求dwd
商品點擊多維分析page_log 直接可求dwd
收藏多維分析收藏表dwd
加入購物車多維分析購物車表dwd
下單可視化大屏訂單寬表dwm
支付多維分析支付寬表dwm
退款多維分析退款表dwd
評論多維分析評論表dwd
地區PV多維分析page_log 直接可求dwd
UV多維分析需要用 page_log 過濾去重dwm
下單可視化大屏訂單寬表dwm
關鍵詞搜索關鍵詞可視化大屏頁面訪問日誌 直接可求dwd
點擊商品關鍵詞可視化大屏商品主題下單再次聚合dws
下單商品關鍵詞可視化大屏商品主題下單再次聚合dws

獨立訪客UV

UV,全稱是 Unique Visitor,即獨立訪客,對於實時計算中,也可以稱為 DAU(Daily Active User),即每日活躍用戶,因為實時計算中的 UV 通常是指當日的訪客數。
那麼如何從用戶行為日誌中識別出當日的訪客,那麼有兩點:

  • 是識別出該訪客打開的第一個頁面,表示這個訪客開始進入我們的應用
  • 由於訪客可以在一天中多次進入應用,所以我們要在一天的範圍內進行去重(狀態去重)

KeyState min -> state (存日期)

  • 獲取執行環境
  • 讀取Kafka dwd_page_log 主題的數據
  • 將每行數據轉換為JSON對象
  • 過濾數據,狀態編程 只保留每個 mid 每天第一次登錄的數據
  • 將數據寫入kafka
  • 啟動任務

過濾思路

  • 首先用 keyby 按照 mid 進行分組,每組表示當前設備的訪問情況
  • 分組後使用 keystate 狀態,記錄用戶進入時間,實現 RichFilterFunction 完成過濾
  • 重寫 open 方法用來初始化狀態
  • 重寫 filter 方法進行過濾
    ◼ 可以直接篩掉 last_page_id 不為空的欄位,因為只要有上一頁,說明這條不是這個用戶進入的首個頁面。
    ◼ 狀態用來記錄用戶的進入時間,只要這個 lastVisitDate 是今天,就說明用戶今天已經訪問過了所以篩除掉。如果為空或者不是今天,說明今天還沒訪問過,則保留。
    ◼ 因為狀態值主要用於篩選是否今天來過,所以這個記錄過了今天基本上沒有用了,這裡 enableTimeToLive 設定了 1 天的過期時間,避免狀態過大。

跳出明細

跳出就是用戶成功訪問了網站的一個頁面後就退出,不在繼續訪問網站的其它頁面。
跳出率就是用跳出次數除以訪問次數。
關註跳出率,可以看出引流過來的訪客是否能很快的被吸引,渠道引流過來的用戶之間的質量對比,對於應用優化前後跳出率的對比也能看出優化改進的成果。
跳出率高不是好事、留存率高是好事

計算跳出行為的思路

首先要識別哪些是跳出行為,要把這些跳出的訪客最後一個訪問的頁面識別出來。那麼要抓住幾個特征:

  • 該頁面是用戶近期訪問的第一個頁面
    這個可以通過該頁面是否有上一個頁面(last_page_id)來判斷,如果這個表示為空,就說明這是這個訪客這次訪問的第一個頁面。
  • 首次訪問之後很長一段時間(自己設定),用戶沒繼續再有其他頁面的訪問。
    這第一個特征的識別很簡單,保留 last_page_id 為空的就可以了。但是第二個訪問的判斷,其實有點麻煩,首先這不是用一條數據就能得出結論的,需要組合判斷,要用一條存在的數據和不存在的數據進行組合判斷。而且要通過一個不存在的數據求得一條存在的數據。更麻煩的他並不是永遠不存在,而是在一定時間範圍內不存在。那麼如何識別有一定失效的組合行為呢?

最簡單的辦法就是 Flink 自帶的 CEP 技術。這個 CEP 非常適合通過多條數據組合來識別某個事件。
用戶跳出事件,本質上就是一個條件事件加一個超時事件的組合。

  • 獲取執行環境
  • 讀取 Kafka dwd_page_log 主題的數據
  • 將每行數據轉換為JSON對象,並提取時間戳生成 Watermark
  • 定義模式序列
  • 將模式序列作用到流上 CEP
  • 提取匹配上的和超時事件
  • UNION 兩種事件
  • 將數據寫入kafka
  • 啟動任務

訂單寬表

需求分析與思路

訂單是統計分析的重要的對象,圍繞訂單有很多的維度統計需求,比如用戶、地區、商品、品類、品牌等等。
為了之後統計計算更加方便,減少大表之間的關聯,所以在實時計算過程中將圍繞訂單的相關數據整合成為一張訂單的寬表。
那究竟哪些數據需要和訂單整合在一起?
image

如上圖,由於在之前的操作我們已經把數據分拆成了事實數據和維度數據,事實數據(綠色)進入 kafka 數據流(DWD 層)中,維度數據(藍色)進入 hbase 中長期保存。那麼我們在 DWM 層中要把實時和維度數據進行整合關聯在一起,形成寬表。那麼這裡就要處理有兩種關聯,事實數據和事實數據關聯、事實數據和維度數據關聯。

  • 事實數據和事實數據關聯,其實就是流與流之間的關聯。
  • 事實數據與維度數據關聯,其實就是流計算中查詢外部數據源。

訂單和訂單明細關聯(雙流 join)

https://ci.apache.org/projects/flink/flink-docs-release-1.12/dev/stream/operators/joining.html

在 flink 中的流 join 大體分為兩種,一種是基於時間視窗的 join(Time Windowed Join),比如 join、coGroup 等。另一種是基於狀態緩存的 join(Temporal Table Join),比如 Interval Join。

這裡選用 Interval Join,因為相比較視窗 join,Interval Join 使用更簡單,而且避免了應匹配的數據處於不同視窗的問題。Interval Join 目前只有一個問題,就是還不支持 left join。

但是我們這裡是訂單主表與訂單從表之間的關聯不需要 left join,所以 intervalJoin 是較好的選擇。

  1. 設定事件時間水位線
  2. 創建合併後的寬表實體類
  3. 訂單和訂單明細關聯 intervalJoin
  • 獲取執行環境
  • 讀取兩個埠數據創建流,並提取時間戳生成 Watermark
  • 雙流join
  • 列印
  • 啟動任務

維表關聯代碼實現

維度關聯實際上就是在流中查詢存儲在 HBase 中的數據表。但是即使通過主鍵的方式查詢,HBase 速度的查詢也是不及流之間的 join。外部數據源的查詢常常是流式計算的性能瓶頸,所以咱們再這個基礎上還有進行一定的優化。

  • 獲取執行環境
  • 讀取 Kafka dwd_page_log 主題的數據
  • 將每行數據轉換為JavaBean對象,並提取時間戳生成 Watermark
  • 雙流join
  • 關聯維度信息
  • 將數據寫入kafka
  • 啟動任務
優化-加入旁路緩存模式 (cache-aside-pattern)

我們在上面實現的功能中,直接查詢的 HBase。外部數據源的查詢常常是流式計算的性能瓶頸,所以我們需要在上面實現的基礎上進行一定的優化。我們這裡使用旁路緩存。
旁路緩存模式是一種非常常見的按需分配緩存的模式。如下圖,任何請求優先訪問緩存,緩存命中,直接獲得數據返回請求。如果未命中則,查詢資料庫,同時把結果寫入緩存以備後續請求使用。
image
image

這種緩存策略有幾個註意點

緩存要設過期時間,不然冷數據會常駐緩存浪費資源。
要考慮維度數據是否會發生變化,如果發生變化要主動清除緩存。

緩存的選型

一般兩種:堆緩存或者獨立緩存服務(redis,memcache),
堆緩存,從性能角度看更好,畢竟訪問數據路徑更短,減少過程消耗。但是管理性差,其他進程無法維護緩存中的數據。
獨立緩存服務(redis,memcache)本事性能也不錯,不過會有創建連接、網路 IO 等消耗。但是考慮到數據如果會發生變化,那還是獨立緩存服務管理性更強,而且如果數據量特別大,獨立緩存更容易擴展。
因為咱們的維度數據都是可變數據,所以這裡還是採用 Redis 管理緩存。

優化-非同步查詢

在 Flink 流處理過程中,經常需要和外部系統進行交互,用維度表補全事實表中的欄位。例如:在電商場景中,需要一個商品的 skuid 去關聯商品的一些屬性,例如商品所屬行業、商品的生產廠家、生產廠家的一些情況;在物流場景中,知道包裹 id,需要去關聯包裹的行業屬性、發貨信息、收貨信息等等。
預設情況下,在 Flink 的 MapFunction 中,單個並行只能用同步方式去交互: 將請求發送到外部存儲,IO 阻塞,等待請求返回,然後繼續發送下一個請求。這種同步交互的方式往往在網路等待上就耗費了大量時間。為了提高處理效率,可以增加 MapFunction 的並行度,但增加並行度就意味著更多的資源,並不是一種非常好的解決方式。
Flink 在 1.2 中引入了 Async I/O,在非同步模式下,將 IO 操作非同步化,單個並行可以連續發送多個請求,哪個請求先返回就先處理,從而在連續的請求間不需要阻塞式等待,大大提高了流處理效率。
Async I/O 是阿裡巴巴貢獻給社區的一個呼聲非常高的特性,解決與外部系統交互時網路延遲成為了系統瓶頸的問題。

image

非同步查詢實際上是把維表的查詢操作托管給單獨的線程池完成,這樣不會因為某一個查詢造成阻塞,單個並行可以連續發送多個請求,提高併發效率。
這種方式特別針對涉及網路 IO 的操作,減少因為請求等待帶來的消耗。

支付寬表

支付寬表的目的,最主要的原因是支付表沒有到訂單明細,支付金額沒有細分到商品上,沒有辦法統計商品級的支付狀況。
所以本次寬表的核心就是要把支付表的信息與訂單寬表關聯上。

解決方案有兩個

  • 一個是把訂單寬表輸出到 HBase 上,在支付寬表計算時查詢 HBase,這相當於把訂單寬表作為一種維度進行管理。
  • 一個是用流的方式接收訂單寬表,然後用雙流 join 方式進行合併。因為訂單與支付產生有一定的時差。所以必須用 Interval Join 來管理流的狀態時間,保證當支付到達時訂單寬表還保存在狀態中。

訂單寬表不需要永久保存,數據本身要寫Kafka所以沒必要再寫一份到 HBase,還要從裡面查,綜合考慮,採用第2種方案。

image

https://www.bilibili.com/video/BV1Ju411o7f8/?p=73

尚矽谷 源代碼

大數據 - 數據倉庫-實時數倉架構分析
大數據 - 業務數據採集-FlinkCDC
大數據 - DWD&DIM 行為數據
大數據 - DWD&DIM 業務數據
大數據 - DWM層 業務實現
大數據 - DWS層 業務實現
大數據 - ADS 數據可視化實現


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • HashMap是Java中用於實現映射關係的一種數據結構。它允許將一個對象(稱為鍵)映射到另一個對象(稱為值)。當需要訪問值時,可以使用鍵來查找值。 HashMap的實現原理是使用散列函數將鍵映射到表中的桶(也稱為桶位置)。每個桶都包含了一些鍵值對,這些鍵值對按照鍵的散列值存儲在桶中。 當向Hash ...
  • 作者:小目標青年 來源:https://blog.csdn.net/qq_35387940/article/details/125921218 前言 不建議使用 select * 這幾個字眼,做開發的都不陌生吧。 阿裡的開發手冊上面也是有提到: 這個完整版可以關註公眾號Java核心技術,然後在公眾號 ...
  • 前言 今天給大家介紹的是Python爬取小說數據並保存txt文檔,在這裡給需要的小伙伴們代碼,並且給出一點小心得。 首先是爬取之前應該儘可能偽裝成瀏覽器而不被識別出來是爬蟲,基本的是加請求頭,但是這樣的純文本數據爬取的人會很多,所以我們需要考慮更換代理IP和隨機更換請求頭的方式來對小說數據進行爬取。 ...
  • 一、前言 在數據量大的企業級實踐中,Elasticsearch顯得非常常見,特別是數據表超過千萬級後,無論怎麼優化,還是有點力不從心!使用中,最首先的問題就是怎麼把千萬級數據同步到Elasticsearch中,在一些開源框架中知道了,有專門進行同步的!那就是Logstash 。在思考,同步完怎麼查看 ...
  • 介面組成更新 介面的組成:常量,抽象方法 Java8之前 常量:public static final 抽象方法:public abstract 預設方法(Java8) 靜態方法(Java8) 私有方法(Java9) 介面中預設方法(Java8) 介面中預設方法的格式: 格式:public defa ...
  • 普遍意義上講,生成器是一種特殊的迭代器,它可以在執行過程中暫停併在恢復執行時保留它的狀態。而協程,則可以讓一個函數在執行過程中暫停併在恢復執行時保留它的狀態,在Python3.10中,原生協程的實現手段,就是生成器,或者說的更具體一些:協程就是一種特殊的生成器,而生成器,就是協程的入門心法。 協程底 ...
  • 原文地址 https://www.cnblogs.com/younShieh/p/17010572.html ❤如果本文對你有所幫助,不妨點個關註和推薦呀,這是對筆者最大的支持~❤ 我們先考慮一般會從什麼地方複製文本、圖片到我們的軟體中。 首先說文本。我們可能會從文本文件,網頁,word,ppt,q ...
  • 修訂功能可以跟蹤文檔所有的修改,瞭解修改的過程,這對於團隊協同文檔編輯、審閱是非常有用的一個功能。將工作簿發送給他人審閱時,我們可以開啟修訂功能,共用工作簿被修改後,用戶查看文檔時可以選擇接受或者拒絕他人修改的數據信息。本文將詳細為您介紹如何接受或拒絕 Excel 中的修訂。 接受工作簿中的修訂 拒 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...