優化 R Docker image 的建立與部署:套件安裝速度提升與節省空間技巧

  1. 前言
  2. 建立 Docker image 時遇到的瓶頸
  3. Step 1:優化安裝套件的速度
    1. 改用 Precompiled 版本的套件 -> 安裝速度提升 8.6 倍
  4. Step 2:優化 Docker image size
    1. 用 r-ver 取代 tidyverse -> 節省 image size 約 2.8 倍
    2. 使用 Multi-stage Builds:兩階段相同 image -> 沒有太大改變
    3. 使用 Multi-stage builds:第二階段改 ubuntu -> 成功縮減 2 倍 image size
  5. 總結
  6. 後記

前言

近期遇到有部分 R Script 執行時佔用太多 VM 記憶體,所以打算把 R 打包成一個 Docker image,讓他可以在 GCP Cloud Run 上面跑,解放 VM 的資源。

首先我建立了一個基於 tidyverse 的 Dockerfile,安裝常用的兩個套件,並讓這個 image 可以由外部提供一個 JOB_NAME 參數,來動態指定要執行的檔案。
(選擇 tidyverse 的原因是使用 r-base 時會遇到無法安裝 bigrquery 的問題)

FROM rocker/tidyverse:4.4.1

RUN R -e "install.packages(c('dplyr', 'bigrquery'), repos='<http://cran.rstudio.com/>')"

COPY r_jobs /r_jobs

CMD ["sh", "-c", "Rscript /r_jobs/$JOB_NAME"]

建立 Docker image 時遇到的瓶頸

雖然這個 image 是可以正常執行,但 docker build 後發現兩個大問題:

  • Docker image 太胖!
    • image 竟然有 2.5 GB 這麼大,這將會造成部署與存放上的問題。
  • R 套件安裝太慢!
    • 光是安裝兩個套件的步驟,就要花 5 分鐘,安裝 12 個套件需要 20 分鐘(如下圖 1,203 秒),時間成本太高。

基於這兩個問題我開始研究 Docker image 的優化方法。

閱讀更多»

Python 與 R 效能大對決!實測比較 Python 和 R 處理數據時的記憶體使用&執行速度

  1. 前言
  2. 實測環境&版本
  3. 實測程式碼
    1. Python
    2. R
    3. 檢查 Test Data 是否相同
  4. 實測數據
  5. 實測結論
  6. 總結

前言

近期因為遇到在 GCP Compute Engine 跑 R 程式碼發生 OOM (Out of Memory)的記憶體問題,所以研究了很多關於 Python 和 R 之間的比較,看到不少文章都說 R 在效能、記憶體分配和垃圾處理(Garbage collect)上都是輸給 Python 的,也看到很多人不推薦使用 R 做大型數據處理。

秉持著研究精神,還是自己測一次最有感,所以這篇文章就是我自己實測的 Python VS. R 的記憶體 + 執行時間的大對決!

實測環境&版本

  • Macbook Pro
    • 晶片: Apple M3
    • 記憶體: 16 GB
    • MacOS: Sonoma 14.2
  • R
    • IDE: 採用最主流的 R Studio 來執行
    • Version:
      • R version: 4.3.3
      • pryr: 0.1.6
  • Python
    • IDE: 採用市占率最高的 VS Code 來執行
    • Version:
      • Python version 3.11.9
      • psutil: 6.0.0
      • numpy: 1.26.4

實測程式碼

這次直接由 ChatGPT-4o 幫我生成兩種不同程式語言的程式碼,我只有附上自己的註解,以及手動更改建立的數據大小而已(下面圖片中的程式碼範例皆為產出一個 70000 x 70000 的表)

閱讀更多»

資料傳輸效能提升 70%!實測 GCP 的 gcloud storage 與 gsutil 指令的差異

  1. 前言
  2. 什麼是 gsutil 指令?
  3. 什麼是 gcloud 指令?
  4. 官方建議使用 gcloud storage 取代 gsutil
  5. 自行實測結果
    1. 實測環境
    2. 實測結果表
    3. 實測 1:複製一個 249.1 MiB 小型檔案
      1. gsutil cp: 5.4 sec
      2. gcloud storage cp: 3.2 sec ( Speed Up 40% )
    4. 實測 2:複製一個 1.0 GiB 大型檔案
      1. gsutil cp: 24 sec
      2. gcloud storage cp: 6.3 sec ( Speed Up 74% )
  6. 總結
  7. 補充資料

前言

在資料工程師的工作中,常會使用雲端 Google Cloud Platform (GCP) 的 Google Cloud Storage (GCS) 作為 Data Lake 儲存一些非結構化資料,而操作 GCS 的指令我都是用 gsutil 來進行,但近期發現有另一個指令是 gcloud storage ,所以這篇文章記錄我針對這兩種指令實測後發現的差異,以及官方文件的建議。

什麼是 gsutil 指令?

  • gsutil 是一個 Python application,主要用來讓使用者可以透過 Command Line 操作 Cloud Storage,操作包含:
    • Creating and deleting buckets.
    • Uploading, downloading, and deleting objects.
    • Listing buckets and objects.
    • Moving, copying, and renaming objects.
    • Editing object and bucket ACLs.

什麼是 gcloud 指令?

  • gcloud 是 GCP 主要的 CLI 工具,用途更廣不限於 GCS,操作包含:
    • Manages authentication, local configuration and developer workflow.
    • Interactions with the Google Cloud APIs.
閱讀更多»

【轉職】非本科從零開始轉職工程師的心路歷程(包含給轉職者的建議)

先自我介紹一下,作者 Jumping 我本人 2019 年以前從來沒碰過程式,透過自學資料科學相關課程,目前是有三年資料領域工作經驗的資料工程師 Data engineer,這篇文章記錄了我從自學到轉職過程的心路歷程,以及給同樣想要轉職的朋友的建議。

先聊聊我的背景

或許我跟大多數人一樣,在上大學前也完全不知道自己要念什麼科系,當時只想說「總之就是三類組,然後分數到哪就去哪」, 後來大學念了食品科學系,雖然後來也是有找到一點熱情,但畢業後仍然不知道自己要什麼,看到身邊不少朋友選擇繼續念碩士,我也憑著那一點熱情考了食品科學相關的研究所,所以在我的六年學生時期是完全沒有碰過程式,大部分都是生物和化學相關的課程和實驗。

當完兵出了社會,第一份工作理所當然的選擇進了食品業做研發,當時還常常被面試官問「為什麼你要做食品研發?」,老實講,我還真的回答不出來。

這種茫然困惑、不知道自己想要做什麼的狀態,一直持續到我出社會幾個月後,接觸程式語言時才開始產生變化。

接觸程式的過程

拿到工作的薪水後,我開始想該如何做投資上的運用,這時候我開始研究公司的財報、技術分析線圖等散戶會做的一些事,在查資料時發現很多人會使用 Python 自己寫爬蟲和畫線圖,於是我開始一點一點地學習怎麼樣寫 Python 語法,後來遇到有些股票網站資訊和圖表是需要付費訂閱才能觀看時,也試著自己按照那些付費圖表的邏輯去編寫程式,並嘗試視覺化出我心中所想的圖表。

(至於我自學的方式和課程,後續的文章會再做說明)

為何轉職?以及轉職時遇到的困難?

在這樣反覆學習和實作的過程中,漸漸發現自己對於寫程式收集及處理資料很感興趣,也很享受把想法和創意透過程式作品實踐出來的過程和成就感,於是就開始思考自己是否有機會轉職做一位工程師,而當時會想轉職很大的原因是:

  • 覺得大數據是未來趨勢,所有公司將來都會需要數據來輔助決策,因此打算往數據方面的工程師發展
  • 當然薪資待遇也很重要,我待的食品業算是傳產,薪資天花板比較低,如果轉職的話比較有發展空間

但同時也要思考許多實際上的困難

  • 因為領域跨很多,所以要補的技術和知識實在太多
  • 自己當時因為研究所 + 當兵 + 工作兩年已經滿 28 歲,要怎麼跟更年輕的肝競爭,還來得及轉嗎?
  • 要離職專心自學嗎?我自己經濟狀況是否允許?

調適心態、面對挑戰

面對這些困難,我自己仍然做了轉職的決定,是因為有了心態上的調適,像是技術不足的部分我可以靠上課學習來補足,也選擇了在繼續工作的狀態下持續自學,讓我不用擔心經濟上的問題。

另外一個我覺得很重要的心態突破,就是評估了利弊之後,好好想一下「對自己來說,最糟的狀況是什麼?」,我自己的答案是「大不了我就是轉職失敗,然後回食品業工作」,所以其實現在轉職並不會有多糟的後果,也是因為這樣想,我才毅然決然繼續往轉職資料工作者的路前進。

你也想要轉職嗎?

當我過了兩三年,回顧我的轉職過程時,我覺得有幾點人生體悟,可以給想要轉職的朋友一些參考:

– 確立目標

凡事都需要一個清楚明確的目標,才能讓我們走在正確的路上!

– 動手實作

不論是在什麼領域,學習都不能只有輸入,最重要的還是輸出,學了之後一定要自己動手做,像是當時我自己的 Side Project 就幫助我找到工作。

– 放下「沉沒成本」

其實不會有所謂「真正準備好」的時候,何時開始都不嫌晚,最適合開始進行的時機就是「現在」,不要因為「沉沒成本」而委屈求全。我到現在還是很感謝當時的我所做的選擇,因為沒有當初的「捨」,就沒有現在的「得」

– 列出恐懼與困難

把自己目前想得到的恐懼和困難都寫下來,如果自己還在為了轉職而卻步,想想這些困難是「知識技術」上的挑戰?還是其實是「勇氣」的挑戰呢?列出了所有的恐懼並面對它們,說不定會發現其實自己離目標沒有想像中的遠喔!

如果你正在為了要不要轉職而猶豫不決,希望我的這些經驗能幫助到你! 也歡迎把文章分享給正在轉職的朋友們!

[SQL] 為何應該要使用 “IS NULL" 而不是 “= NULL"?

當我們想要找出某些欄位是 NULL 的資料…

做為資料工作者,在處理資料的時候經常會遇到所謂的空值「NULL」,也常看到這樣的值被存在資料庫的欄位中,當我們使用 SQL 想要找出某些欄位中是空值的資料,就會使用像下方這樣的 WHERE 去做篩選,但這樣其實無法得到我們想要的結果。

SELECT 
    column_1,
    column_2
FROM `my_table`
WHERE column_1 = NULL
閱讀更多»