#concept

同一條路,三個名字——差別只在自動化走到哪裡 ① 提交程式碼push / open PR ② 建置 + 測試自動、每次都跑 ③ 打包產物一顆可部署的東西 ④ 測試環境驗收隨時可上線的狀態 ⑤ 上 Production誰按下這一步? CI(持續整合) 合回主幹 + 每次都自動驗證 Continuous Delivery(持續交付) 隨時可上線,但人按 Continuous Deployment(持續部署)——過關就自動上,沒有那顆按鈕 兩個 CD 的差別不是技術,是你敢不敢把那顆按鈕拿掉 敢不敢,取決於前面幾關擋得住多少——這也是為什麼品質關卡與回滾是後面幾篇的重點

Jenkins 是什麼:CI 不是「有跑測試」,是「頻繁合回主幹」

· tech · 約 13 分鐘 · 📚 Jenkins 學習筆記 #1

大部分人第一次碰 Jenkins,情境都差不多:公司有一台跑很久的 Jenkins,你要在上面「加一個 job」。點進去、複製隔壁專案的設定、改幾個欄位、按存檔——會動了,收工。這樣用了兩年,你會很熟…

#jenkins#ci-cd#concept

同一個映像檔,跑遍所有環境 映像檔my-app:1.0(不可變) DevelopmentConfigMap + Secret StagingConfigMap + Secret ProductionConfigMap + Secret Pod(dev) Pod(staging) Pod(production) 12-factor:設定放環境/外部,不烤進映像檔——同一映像檔才能跨環境重用

ConfigMap 與 Secret:把設定和機密從映像檔裡拆出來

· tech · 約 5 分鐘 · 📚 Kubernetes 學習筆記 #5

前面幾篇,你已經能把一個 app 部署、對外服務了。但真實的 app 還缺一塊:設定——資料庫位址、feature flag,還有密碼、API key、憑證。這些東西有一條鐵律:不該寫死在映像檔或程式…

#kubernetes#concept

Infra 體檢表:看任何工具都問這 8 題 ① 部署拓撲由哪些角色組成?幾台?誰是大腦誰是工人? ② 狀態與儲存 ★樞紐有狀態嗎?資料放哪?掉了能重建嗎? ③ 擴展水平(加機器)還是垂直(加規格)? ④ HA / 故障轉移掛一台誰接手?有沒有單點? ⑤ 容量規劃瓶頸是 CPU / 記憶體 / 磁碟 / 網路? ⑥ 監控該盯哪些指標?怎麼知道它快不行了? ⑦ 調校旋鈕哪些設定會決定生死? ⑧ 故障模式它最常怎麼壞?壞了長什麼樣?

從 Infra 角度看一個工具,要問哪些問題

· tech · 約 3 分鐘 · 📚 從 Infra 角度看資料工具 #1

學一個工具、和把它放進 Production,是兩種完全不同的問題。學的時候你問「這個 API 怎麼用、這個概念是什麼」;上 Production 時你問的是另一組問題——它會怎麼掛?怎麼長大?半夜壞…

#infrastructure#concept

傳統 KV 快取(memcached) key → 「一坨字串」(不透明 blob) 改一個欄位 = GET 整包 → 應用端改 → SET 整包 Redis(資料結構伺服器) key → List / Hash / Set / ZSet 伺服器端直接操作(原子)= HSET · LPUSH · ZADD · ZRANGE 例:排行榜 = 一個 Sorted Set,ZADD 記分 + ZRANGE 取前 N 不必把整個榜撈回應用端自己排序——運算搬到資料旁邊做,又快又原子

Redis 是什麼:不只是快取,是記憶體資料結構伺服器

· tech · 約 5 分鐘 · 📚 Redis 學習筆記 #1

大多數人第一次認識 Redis,都是把它當「快取」——把資料庫查詢的結果丟進去、下次直接拿。這沒錯,但也把它看小了。Redis 的本質是一台記憶體資料結構伺服器(in-memory data stru…

#redis#concept

① Dirty Read 髒讀 T1 T2 餘額改 200(未提交) 讀到餘額 200 ❌ ROLLBACK ② Non-repeatable Read 不可重複讀 T1 T2 讀餘額 100 餘額改 200 並提交 又讀餘額 200 ❌ ③ Phantom Read 幻讀 T1 T2 查到 3 筆訂單 插入 1 筆符合訂單並提交 又查到 4 筆 ❌ 時間 →

交易與隔離層級:併發不打架的分級

· tech · 約 6 分鐘 · 📚 SQL 我以為我懂 #11

前面講的都是「一個查詢怎麼跑得快」(索引、EXPLAIN),這篇換個維度:很多交易同時跑,怎麼不互相打架? 這就是交易與隔離層級。(這裡講單機 PostgreSQL 的實務;分散式交易與一致性,交給姊…

#sql#concept

輸入(orders):4 列 A · 100 A · 250 B · 80 B · 120 GROUP BY(收合) A · SUM 350 B · SUM 200 4 列 → 2 列(每組收成一列) SUM() OVER(不收合) A · 100組計 350 A · 250組計 350 B · 80組計 200 B · 120組計 200 4 列 → 4 列(每列多一欄看整組的值)

Window Function:不收合的聚合

· tech · 約 4 分鐘 · 📚 SQL 我以為我懂 #5

上一篇的 GROUP BY 把每組收合成一列。但你一定遇過這種需求:「我想要整組的計算,又想保留每一列。」 例如——在每一筆訂單旁邊,標上它佔該客戶總額的比例;或在每個月的營收旁,標上跟上個月的差。收…

#sql#concept#window-function

原始列(orders) A · amount 100 A · amount 250 B · amount 80 B · amount 120 B · amount 50 GROUP BY customer 收合後:每組一列 customer = ACOUNT=2 · SUM=350 customer = BCOUNT=3 · SUM=250 amount 一組有多個值(100/250)→ 不能裸選,要用聚合(SUM/AVG…)壓成一個數

GROUP BY:把多列收合成一列

· tech · 約 5 分鐘 · 📚 SQL 我以為我懂 #4

GROUP BY 每個人都會寫,但幾乎每個人也都被那句 column "..." must appear in the GROUP BY clause 擋過,而且常常搞不懂「我就選個欄位,為什麼不行?…

#sql#concept

SQL 的邏輯有三個值(不是兩個) TRUE 條件成立 FALSE 條件不成立 UNKNOWN 不知道 ↑ 任何跟 NULL 的比較都落這裡 age = NULL、age <> NULL 都是 WHERE / ON / HAVING 只放行 TRUE TRUE → ✓ 保留 FALSE → ✗ 丟 UNKNOWN → ✗ 丟

NULL 不是值,是「不知道」

· tech · 約 6 分鐘 · 📚 SQL 我以為我懂 #3

上一篇的 LEFT JOIN,會幫沒配到的列補上 NULL。那個 NULL 就是這篇的主角——它是無數 SQL bug 的源頭,而根本原因只有一句:NULL 不是一個值,是「不知道」。 一旦你把它讀成…

#sql#concept

右表 R:訂單(user 欄) A A B 左表 L:使用者 使用者 A 使用者 B 使用者 C A 配到 2 筆 → 結果 A 出現兩次 B 配到 1 筆 C 配不到 → INNER 丟掉 LEFT 補 (C, NULL) ON 符合(留下) 不符合(丟棄)

JOIN 的真相:先算笛卡爾積,再過濾

· tech · 約 6 分鐘 · 📚 SQL 我以為我懂 #2

上一篇把「你寫的順序不是它跑的順序」講清楚了。這篇用同一把鑰匙拆穿 JOIN。很多人把 JOIN 想成「把兩張表黏在一起」,然後死背 INNER/LEFT/RIGHT/FULL 各自的行為。但其實它們…

#sql#concept

呼叫方 只認 web 這名字 Service:web 固定 IP 10.96.0.10 · DNS web.*.svc selector: app=web 自動負載均衡到健康 Pod Pod · 10.1.2.7 ✓ 健康 Pod · IP 會變 掛了換新:.8 → .31 Pod · 10.1.4.2 ✓ 健康

Service:擋在短命 Pod 前面的固定門牌

· tech · 約 5 分鐘 · 📚 Kubernetes 學習筆記 #4

第二篇留了一個問題:既然 Pod 是短命的、被換掉就有新的 IP,那別的服務要怎麼穩定找到它?你總不能把某顆 Pod 的 IP 寫死在設定裡——它下一秒可能就不在了。這篇的主角 Service,就是 …

#kubernetes#concept#networking

你這樣寫 DB 這樣跑(邏輯順序) SELECT FROM / JOIN WHERE GROUP BY HAVING ORDER BY LIMIT ① FROM / JOIN ② WHERE ③ GROUP BY ④ HAVING ⑤ SELECT ⑥ ORDER BY ⑦ LIMIT

你寫的 SQL 不是照你寫的順序跑

· tech · 約 4 分鐘 · 📚 SQL 我以為我懂 #1

你寫 SQL,幾乎都是 SELECT 開頭。寫久了很自然會以為:它就是從 SELECT 開始跑的。但不是——SQL 是宣告式的,你寫的是「要什麼」,引擎自己決定「怎麼跑、照什麼順序跑」,而它跑的順序跟…

#sql#concept

Deployment 期望:replicas = 3 · image v1 ReplicaSet 確保永遠有 3 個 Pod Pod ✓ 健康 Pod ✗ 掛了 Pod ✓ 健康 少一個 → ReplicaSet 觀察到落差 → 立刻補一個新的回到 3 個

Deployment 與自我修復:reconcile loop 的實戰

· tech · 約 6 分鐘 · 📚 Kubernetes 學習筆記 #3

第一篇給了靈魂(reconcile loop),第二篇給了原子(Pod)。但實務上你幾乎不會手動去建一個 Pod —— 你宣告的是 Deployment,而它正是 reconcile loop 最實用…

#kubernetes#concept

Pod 最小部署單位・排程與伸縮的單位 容器:app 你的服務 容器:sidecar 選配(log / proxy) 共享:一個 IP(彼此用 localhost 通)· 共享 Volume

Pod、Node、Scheduler:Kubernetes 叢集的三個原子

· tech · 約 5 分鐘 · 📚 Kubernetes 學習筆記 #2

上一篇講了 K8s 的靈魂:你宣告期望,reconcile loop 不斷把現實拉過去。但那句「我要 3 個」——3 個什麼?落在哪台機器上?誰決定放哪? 這篇把叢集最基本的三個原子講清楚:Pod、N…

#kubernetes#concept

期望狀態 你宣告:replicas = 3 Controller 控制迴圈 比較 & 修正 實際狀態 現在只有 2 個 ① 讀期望 ② 動作 ③ 觀察 2 → 建 1 個 → 3 ✓ reconcile loop:不斷比較期望與實際,有落差就修正 —— 這就是 K8s 的靈魂

Kubernetes 是什麼:從「跑容器」到「宣告你要的狀態」

· tech · 約 5 分鐘 · 📚 Kubernetes 學習筆記 #1

很多人學 Kubernetes(K8s)覺得難,是因為一上來就被 kubectl、一堆 YAML 欄位、幾十種資源名詞淹沒。但其實 K8s 只有一個核心觀念,抓住它,後面全部都是同一句話的變形。這個系…

#kubernetes#concept

痛點還沒到 → 輕量解 本機 PySpark · dbt + 倉儲 直接打 API · 兩層架構 成本低、好維護 痛點到了 → 才上重武器 Spark 叢集 · Kafka Airflow · 多層 Medallion 威力強,但每天要餵養 痛點臨界點 痛點量級(資料量 · 來源數 · 編排複雜度)→

先確認痛點,再上重武器

· tech · 約 2 分鐘

這是一篇概念筆記 —— 一個我反覆在用的判斷,獨立成篇,讓其他文章可以連回來。 一句話:在引入任何重型工具或架構之前,先確認你的痛點真的到了需要它的量級。 沒到,就別上 —— 因為重武器的成本不在「裝…

#concept#data-engineering