iT邦幫忙

2024 iThome 鐵人賽

DAY 23
1
AI/ ML & Data

這跟文件說的不一樣!從 0 到 1 導入 dbt 的實戰甘苦談系列 第 23

DAY 23 CI/CD 跟文件說的不一樣!每次都 full refresh 太貴怎麼辦?

  • 分享至 

  • xImage
  •  

接著我想來討論一下,在 CI/CD 流程中,我們在 CI 跟 CD 分別做了什麼不同的操作。

這邊主要可以用環境來區分,在 CI 時,也就是 PR 建立時,我們會在開發(測試)環境中運行,檢查模型本身、以及其下游的表格是否能正常運行。

而在 CD 時,也就是 PR 被合併時,我們會在生產(正式)環境中運行,確保他正常更新我們正在使用的資料。

而在這兩個環節中,我們所做的、最主要的差異就在於 —— full refresh。

這個 full refresh 是針對 dbt 中的 incremental model(先前有介紹到),這個模型在第一次將資料表建立起來之後,每次更新時,就只會更新原始 log 表中尚未更新的資料,藉此操作來節省運算量(跟錢)。

在測試環境中,由於我們的資料是抽樣出來的,量體很小,可以放心的做 full refresh,也就是每一次測試時,我們都把 incremental model 重新建立一遍,確保不會因為欄位的邏輯、名稱變動、或是欄位的增減而導致部署失敗。

但是在正式環境中,原本也應該要 full refresh 才能確保資料狀態是最新最完整的,但無奈每次更新時都要進行 full refresh 有點燒錢,我們大部分的事實表(fact table)都是以 incremental model 來處理的。有時候只是改個不影響結果的小地方,甚至只是排版有調整,就要把整張表又重新刷新一遍,還連帶所有的上下游都一起更新,這個運算並無必要。

我們目前想到一個 workaround,我們看了 GitHub Actions 中各種事件被觸發的條件(如文件),覺得在 GitHub 上要達到可以透過特定行為來決定要不要 full refresh,只有標籤比較適合。當開發者確認該 PR 應該要重新刷新調整後的模型時,就透過新增 GitHub PR 上的標籤,在 GitHub Actions 中我們判斷是否有加上此標籤,來決定是否要將資料表重新刷新。

不過只要有人工就會讓風險增加,這部分還需要再想想其他的優化辦法。這部分因為是 dbt 相關的功能,比起在 GitHub 上想方法,應該可以再去看看 dbt 的社群中有沒有人推出更合適的工具或作法,研究看看是否可以結合 GitHub 跟上一篇提到 dbt 的 state 判斷來做更精確的更新。(其實還有一個解決方法就是每次都全部刷新啦,有錢就能解決的問題 XD)

認真的,如果資料更值錢一些,確保資料完整度的優先級就會擺在最前面,相比起來 cost down 什麼的,就是有時間再去做就好了。


另一個差異是,在正式環境部署時,若遇到問題,我們需要即刻接收到資訊,並迅速判斷應該先退回舊版,還是可以馬上修正。因此在 CD 流程中,我們加上一個流程,判斷部署是否成功,如果失敗的話馬上透過 API 傳送提醒至 slack。應該有蠻多不同寫法的,不過都大同小異。

- name: Send GitHub Action trigger data to Slack workflow
  id: slack
  if: failure()
  uses: slackapi/slack-github-action@v1.27.0
  with:
    channel-id: {{ channel-id }}
    slack-message: {{ message }}
  env:
    SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}

接下來會談談上一篇賣的關子:除了沒看到 dbt 有提供 state:modified 來判斷有變動的模型這個理由之外,用 git diff 附加的好處為何?


上一篇
DAY 22 CI/CD 跟文件說的不一樣!用 state 去辨別異動的模型
下一篇
DAY 24 CI/CD 跟文件說的不一樣!如何保持 dbt 與下游服務的連貫性?
系列文
這跟文件說的不一樣!從 0 到 1 導入 dbt 的實戰甘苦談30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言