P
PipeCraft

Roadmap Progress

ข้อมูลเบื้องต้นเกี่ยวกับวิศวกรรมข้อมูล (Introduction to Data Engineering) Python สำหรับ Data Engineering พื้นฐาน Linux & CLI สำหรับวิศวกรข้อมูล Git สำหรับระบบงานข้อมูลและทีมพัฒนา ระบบเครือข่ายและระบบประมวลผลแบบกระจายศูนย์ (Networking & Distributed Systems) SQL ขั้นสูง (Window Functions & Optimization) ฐานข้อมูลไม่ใช่เชิงสัมพันธ์ (NoSQL Databases & Modern Stores) การออกแบบโครงสร้างข้อมูล (Star/Snowflake & SCD) โครงสร้างพื้นฐานเครือข่ายระบบคลาวด์ (Cloud-based Networking) สถาปัตยกรรม Data Lakehouse (Apache Iceberg & MinIO) Local-first Data Engineering ด้วย DuckDB โครงสร้างพื้นฐานในรูปแบบโค้ด (IaC ด้วย Terraform) การแปลงข้อมูลระดับโปรด้วย dbt-core ข้อตกลงร่วมด้านข้อมูล (Data Contracts) การบริการและการส่งต่อข้อมูลวิเคราะห์ (Data Serving & Reverse ETL) การประมวลผลข้อมูลขนาดใหญ่แบบกระจายด้วย Apache Spark ระบบจัดการเวิร์กโฟลว์ข้อมูล (Airflow, Dagster & Prefect) การประมวลผลข้อมูลแบบเรียลไทม์ด้วย Kafka & Redpanda การจัดการคอนเทนเนอร์และคลัสเตอร์ (Containers & Kubernetes) ระบบ CI/CD และการเฝ้าระวังคุณภาพข้อมูล (CI/CD, Monitoring & Testing) ระบบความปลอดภัยและการควบคุมข้อมูล (Security, Governance & Privacy) ระบบปฏิบัติการและประมวลผลโมเดล (Machine Learning & MLOps)
บทที่ 1: รากฐานวิศวกรรมซอฟต์แวร์และระบบ (Foundations of Software & Systems)

Git สำหรับระบบงานข้อมูลและทีมพัฒนา

1.4 Git และการควบคุมเวอร์ชันโค้ดท่อส่งข้อมูล (Git & Version Control for Data Pipelines)

การพัฒนาโมเดลวิเคราะห์ข้อมูลระดับองค์กรและการสร้างแอปพลิเคชัน Spark จำเป็นต้องพึ่งพาระบบควบคุมเวอร์ชันเพื่อป้องกันข้อขัดแย้งของรหัส (Code Conflicts) และรับประกันเสถียรภาพก่อนนำขึ้นสู่โปรดักชัน โมดูลนี้เจาะลึก 5 หัวข้อหลักในระบบควบคุมเวอร์ชันด้วย Git

1. โครงสร้างฐานข้อมูลของ Git (Directed Acyclic Graph) และกลไกจัดเก็บออบเจกต์

ทฤษฎีและกลไกการทำงาน (How it works): Git ไม่ได้เก็บความเปลี่ยนแปลงแบบประวัติส่วนต่างของไฟล์รายบรรทัด (Delta-based) แต่จัดเก็บข้อมูลในรูปสแนปช็อต (Snapshots) ทั้งระบบผ่านโครงสร้างข้อมูลแบบกราฟทิศทางไม่มีวัฏจักร หรือ Directed Acyclic Graph (DAG) ออบเจกต์ภายในของ Git จะถูกบันทึกไว้ในไดเรกทอรี `.git/objects/` โดยเข้ารหัสแฮชแบบ SHA-1 และแบ่งออกเป็น 4 รูปแบบหลัก: 1. **Blob**: จัดเก็บเนื้อหาไฟล์ดิบหลังจากทำการบีบอัดด้วยอัลกอริทึม zlib โดยจะไม่บันทึกชื่อไฟล์และสิทธิ์การเข้าถึงใดๆ 2. **Tree**: ทำหน้าที่เสมือนโฟลเดอร์ เก็บรายการสิทธิ์ (Permissions), ชนิดของข้อมูล (Blob หรือ Tree ย่อย), แฮช SHA-1 และชื่อไฟล์จริง 3. **Commit**: เก็บข้อมูล Metadata ได้แก่ ชื่อผู้เขียน, ผู้ตรวจสอบ, วันที่บันทึก, พอยน์เตอร์ชี้ไปยัง Tree หลัก และแฮชของคอมมิตต้นตระกูล (Parent Commits) 4. **Tag**: ออบเจกต์ชี้ตำแหน่งคอมมิตอย่างถาวรเพื่อใช้อ้างอิงเวอร์ชันจำลอง

# Inspecting low-level Git object database directly
# 1. Compute SHA-1 hash of a string and write to Git object database
echo "pipeline_id: spark_elt_01" | git hash-object -w --stdin

# 2. Retrieve object type and content using the generated hash (e.g. 8d3d92...)
git cat-file -t 8d3d92
git cat-file -p 8d3d92
                    

Use Case ในชีวิตจริง (Real-world Scenario): เมื่อเกิดปัญหารหัสโมเดลการประมวลผลข้อมูลใน dbt เสียหายหลังการรวมกิ่ง วิศวกรข้อมูลสามารถใช้คำสั่งล่างระบบ (Plumbing Commands) เช่น `git cat-file` เพื่อย้อนดูข้อมูลในออบเจกต์ Tree และ Commit ของพ่อแม่ ทำให้สามารถตรวจสอบความสัมพันธ์เชิงลำดับของ DAG ได้อย่างอิสระโดยไม่ต้องสลับสาขาโค้ด

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): ปัญหา Repository Bloat หรือพื้นที่เก็บมีขนาดบวมโตอย่างรวดเร็ว เกิดจากวิศวกรเผลอคอมมิตไฟล์ข้อมูลดิบ (เช่น `.csv`, `.json` ขนาดเกิน 100MB) ลงในฐานข้อมูล Git แก้ไขโดยติดตั้งโปรแกรมลบประวัติแบบถาวรอย่าง `git-filter-repo` หรือ `BFG Repo-Cleaner` ร่วมกับการเขียนระบุชนิดไฟล์ห้ามติดตามลงในไฟล์ `.gitignore` ก่อนเริ่มโครงการ

2. การเลือกสถาปัตยกรรมสาขาโค้ด: Feature Branching กับ Trunk-Based Development

ทฤษฎีและกลไกการทำงาน (How it works): การแบ่งปันงานและการจัดการรหัสโครงการขนาดใหญ่แบ่งออกเป็น 2 แนวคิดหลัก: - **Feature Branching (Gitflow)**: นักพัฒนาแยกกิ่งพัฒนา (Feature Branches) ยาวนาน รวบรวมงานส่งผ่านการตรวจสอบรหัส (Pull Requests) เหมาะสำหรับโปรเจกต์ที่มีความเสี่ยงสูงและต้องการระบบอนุมัติหลายชั้น - **Trunk-Based Development**: นักพัฒนาทุกคนส่งรหัสการแก้ไขตรงเข้าสู่สาขาหลัก (main หรือ trunk) ตลอดเวลา หรือผ่านสาขาที่มีอายุน้อยกว่า 24 ชั่วโมง โดยพึ่งพาระบบการตรวจสอบคุณภาพด้วย Automated Testing (CI/CD) เป็นเกณฑ์กั้นการทำงาน

# Configuration variable toggling in Python to support Trunk-Based release
import os

# Use Environment Variables / Feature Flags to isolate incomplete features in Main branch
RUN_NEW_INGESTION_MODEL = os.getenv("FEATURE_NEW_INGESTION", "False") == "True"

def run_pipeline():
    if RUN_NEW_INGESTION_MODEL:
        # Code from new trunk commit (experimental)
        print("Running experimental high-performance polars ingestion.")
    else:
        # Stable legacy pipeline
        print("Running legacy pandas ingestion.")
                    

Use Case ในชีวิตจริง (Real-world Scenario): ทีมผู้สร้างคลังข้อมูลระดับร้อยคนนำระบบ Trunk-Based Development มาใช้ร่วมกับระบบตรวจสอบรหัสอัตโนมัติ เพื่อเลี่ยงปัญหาการขัดแย้งของโค้ดขนาดใหญ่ (Merge Conflicts) ที่มักเกิดขึ้นตอนปลายสัปดาห์ ส่งผลให้ลดระยะเวลาจัดส่งฟีเจอร์แปลงข้อมูลขึ้นระบบงานจริงได้รวดเร็วขึ้น

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): ความเสี่ยงสูงสุดของ Trunk-Based Development คือการที่รหัสบั๊กหลุดไปถึงผู้ใช้บริการหากไม่มีการควบคุมอย่างรัดกุม แก้ไขโดยการเปิดระบบปกป้องสาขาหลัก (Branch Protection Rules) ห้ามดันตรงโดยไม่มีการตรวจสอบ และสร้างระบบทดสอบแบบแยกสภาพแวดล้อมชั่วคราว (Ephemeral environments) เพื่อประเมินผลรันข้อมูลก่อนทำการรวมกิ่งเสมอ

3. การควบคุมประวัติการพัฒนาขั้นสูง: Interactive Rebase, Squash, และ Amend

ทฤษฎีและกลไกการทำงาน (How it works): Git มีชุดเครื่องมือสำหรับเขียนประวัติคอมมิตย้อนหลังใหม่เพื่อให้ประวัติโครงการเป็นระเบียบเรียบร้อยก่อนแชร์ให้ผู้อื่น: - **Interactive Rebase (`git rebase -i`)**: เปิดโปรแกรมข้อความเพื่อเข้าไปจัดการคอมมิตย้อนหลังตามระบุ เช่น การเปลี่ยนคำคอมมิต (reword), การลบ (drop), การย้ายลำดับ หรือการควบรวม - **Squash**: การยุบคอมมิตย่อยหลายตัวที่อยู่ติดกัน ให้หลอมรวมเป็นคอมมิตเดียว - **Amend (`git commit --amend`)**: การแทรกสอดการเปลี่ยนรูปไฟล์ล่าสุดลงในคอมมิตปัจจุบัน ช่วยหลีกเลี่ยงการเพิ่มคอมมิตเล็กน้อยที่ไม่จำเป็น

# Interactive rebase process for local cleanup before merge
# 1. Start interactive rebase for last 4 commits
git rebase -i HEAD~4

# 2. Git opens text editor. Modify list like this:
# pick a3c561f feat: add partition config to minio sink
# squash c4d291e tmp: add temp logging
# squash e912a3d fix: resolve snaphshot metadata error
# reword f512cba feat: finalize iceberg table partition script

# 3. Save, resolve conflict if any, then push using lease protection
git push origin feature/iceberg-sync --force-with-lease
                    

Use Case ในชีวิตจริง (Real-world Scenario): ก่อนที่วิศวกรข้อมูลจะผสานรวมกิ่งโปรเจกต์ SQL dbt ไปยังสาขา `main` เขาได้ทำการรัน `git rebase -i` เพื่อรวมคอมมิตขยะอย่าง "try fixing typo" หรือ "re-run check" ทั้งหมดให้หลอมรวมเป็นคอมมิตที่ดูเป็นมืออาชีพเพียงตัวเดียว เพื่อความคลีนในการตรวจสอบย้อนหลัง

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การเขียนประวัติใหม่จะเปลี่ยนค่าแฮชคอมมิตทั้งหมด หากรันคำสั่งแก้ไขบนประวัติที่แชร์กับนักพัฒนาคนอื่นแล้ว จะส่งผลให้ Git กราฟเสียหายและสับสนอย่างรุนแรง แก้ไขโดยห้ามทำ Rebase/Amend บนสาขาแชร์ภายนอกเด็ดขาด และใช้คำสั่ง `git push --force-with-lease` แทน `--force` เสมอ เพื่อป้องกันการเผลอไปเขียนทับรหัสที่สมาชิกดันขึ้นมาใหม่

4. การจัดการความปลอดภัยและควบคุมคุณภาพแบบอัตโนมัติด้วย Git Hooks และ Pre-Commit

ทฤษฎีและกลไกการทำงาน (How it works): Git Hooks คือชุดโปรแกรมต้นแบบที่รันอัตโนมัติเมื่อเกิดเหตุการณ์สำคัญในโปรเซสของ Git (เช่น ก่อนการส่งบันทึก `pre-commit` หรือก่อนดันโค้ดขึ้นระบบ `pre-push`) โดยไฟล์เหล่านี้จะเก็บอยู่ในโฟลเดอร์ซ่อน `.git/hooks/` วิศวกรข้อมูลนิยมประยุกต์ใช้เฟรมเวิร์ก **pre-commit** เพื่อคุมมาตรฐานรหัสผ่านการรันเครื่องมือประเมินคุณภาพ โดยจะสกัดไฟล์เฉพาะบรรทัดที่เปลี่ยนแปลงไปสแกน ทำให้ประหยัดเวลารันโปรแกรมทดสอบ

# Production-ready .pre-commit-config.yaml configuration schema
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0
    hooks:
      - id: check-yaml
      - id: end-of-file-fixer
      - id: check-added-large-files
        args: ['--maxkb=500']
  - repo: https://github.com/sqlfluff/sqlfluff
    rev: 2.1.2
    hooks:
      - id: sqlfluff-lint
        additional_dependencies: ['sqlfluff-templater-dbt']
  - repo: https://github.com/Yelp/detect-secrets
    rev: v1.4.0
    hooks:
      - id: detect-secrets
        args: ['--baseline', '.secrets.baseline']
                    

Use Case ในชีวิตจริง (Real-world Scenario): สถาบันการเงินบังคับให้วิศวกรข้อมูลรัน pre-commit hooks ทุกครั้ง โดยหากโปรแกรมตรวจจับพบรหัสลับ (Database Credentials, Cloud Access Keys) ในโค้ดหรือการเขียนสคริปต์ SQL ที่ไม่มีการจัดรูปแบบตามมาตรฐาน SQLFluff ตัว Git จะป้องกันและขัดขวางไม่ให้มีการบันทึกคอมมิต

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): นักพัฒนาอาจใช้พารามิเตอร์ `git commit --no-verify` เพื่อเลี่ยงการรันตรวจสอบความปลอดภัย ส่งผลให้รหัสที่มีจุดอ่อนรั่วไหลขึ้นระบบ แก้ไขโดยการเซ็ตอัประบบตรวจสอบความปลอดภัยซ้ำอีกเลเยอร์หนึ่งที่ฝั่งผู้ให้บริการคลาวด์ ผ่านโปรแกรมจำลอง CI/CD (เช่น GitHub Actions, GitLab CI) เพื่อทำการปฏิเสธรหัสที่ไม่ผ่านมาตรฐานตั้งแต่ชั้นแรก

5. การกู้ประวัติและฟื้นฟูหลังภัยพิบัติด้วย git reflog และ git reset

ทฤษฎีและกลไกการทำงาน (How it works): Git มีคุณสมบัติในการรักษาความปลอดภัยของไฟล์ประวัติ โดยการเปลี่ยนแปลงตำแหน่งหัวชี้ทั้งหมด (HEAD moves) จากคำสั่ง เช่น commit, merge, checkout, rebase, หรือ reset จะถูกจดบันทึกประวัติพิกัดลงในตารางสถิติตำแหน่งที่ชื่อว่า git reflog (Reference Log) ทำให้วิศวกรสามารถค้นหาแฮชคอมมิตดั้งเดิมที่ลบทิ้งหรือหายไป และกู้คืนกลับมาได้อย่างถูกต้องสมบูรณ์ผ่านคำสั่งการเปลี่ยนพอยน์เตอร์อย่าง `git reset --hard`

# Disastrous mistake: accidentally deleted or hard-reset master branch
# 1. Query Reference Log history to locate target state
git reflog

# Output example:
# a5d1e2f HEAD@{0}: reset: moving to HEAD~3
# f12c4b8 HEAD@{1}: commit: feat: implement dbt incremental layer
# 8c2a41d HEAD@{2}: commit: fix: clean pandas dataframe index

# 2. Hard reset pointer back to the exact commit prior to the disaster
git reset --hard f12c4b8
                    

Use Case ในชีวิตจริง (Real-world Scenario): ระหว่างช่วงแก้ไขโค้ดฉุกเฉินกลางดึก วิศวกรเผลอรันคำสั่ง `git reset --hard HEAD~5` ทำลายประวัติไฟล์โมเดลการประมวลผลข้อมูลไป 5 คอมมิตล่าสุดโดยที่ไม่ได้ทำการดันโค้ดขึ้นเซิร์ฟเวอร์หลัก เขาสามารถเปิดระบบดึงแฮชคอมมิตล่าสุดจาก `git reflog` และรันคำสั่งกู้คืนสถานะโค้ดทั้งหมดได้อย่างสมบูรณ์ภายในเวลาไม่ถึงนาที

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): ประวัติการบันทึกใน `git reflog` มีอายุจัดเก็บจำกัด (ปกติมีอายุ 90 วัน) และจะโดนล้างทิ้งถาวรเมื่อมีการรันโปรแกรมทำความสะอาดขยะ `git gc` แก้ไขโดยหากพบสภาวะรหัสโครงการเสียหาย ต้องรีบรัน reflog เพื่อบันทึกพิกัดและสร้างสาขาใหม่กู้ข้อมูลทันทีเพื่อป้องกันการโดนเขียนทับ

🛠️ Weekend Sandbox Challenge: Simulating and Resolving Merge Conflicts

โจทย์ปฏิบัติการ: จงทดลองจำลองและกู้คืนสภาวะขัดแย้งของโค้ด (Merge Conflict) ใน Git โดยสร้างคลังจำลองขึ้นมาสองสาขา (Branches) และแก้ไขโค้ดที่ไฟล์บรรทัดเดียวกัน จากนั้นทำการสั่งรวมโค้ดและแก้ความขัดแย้งผ่าน CLI

# 1) Set up temporary git sandbox directory
mkdir git-sandbox && cd git-sandbox
git init

# 2) Create master branch commit
echo "print('Base Version')" > script.py
git add script.py && git commit -m "Initial commit"

# 3) Branch out and modify same line
git checkout -b feature-a
echo "print('Feature A Version')" > script.py
git commit -am "Feature A update"

# 4) Go back and conflict on main branch
git checkout main
echo "print('Main Branch Version')" > script.py
git commit -am "Main branch update"

# 5) Merge and encounter conflict
git merge feature-a # Git reports MERGE_MSG conflict
                    

💼 Senior Technical Interview Q&A

Q1: จงอธิบายความแตกต่างของกลไกระหว่าง Git Merge และ Git Rebase รวมถึงผลกระทบต่อประวัติล็อกทีมผู้พัฒนา?

A1: `Git Merge` นำปลายสาขาสองฝั่งมาเชื่อมกันโดยสร้าง Commit ตัวใหม่ขึ้นมารวมกัน (Merge Commit) รักษาลำดับเวลาและประวัติเดิมไว้ทั้งหมดอย่างปลอดภัย แต่อาจเกิดประวัติสายกราฟที่รกรุงรัง ในขณะที่ `Git Rebase` จะย้ายฐานประวัติการทำของสาขาเราไปตั้งต้นใหม่ที่ยอดปลายสุดของเป้าหมาย ทำให้เกิดประวัติเส้นทางตรงเรียงเป็นเส้นตรงเส้นเดียวที่สวยงาม แต่อาจเปลี่ยนแปลงหมายเลข Hash ของ Commit เดิม

Q2: การสั่งใช้คำสั่ง `git cherry-pick` มีหลักการทำงานอย่างไร และควรมีข้อพึงระวังอย่างไรในการวางท่อ CI/CD?

A2: `git cherry-pick` เป็นการดึงเฉพาะประวัติแก้ไขของหนึ่ง Commit จากสาขาอื่นมารวมยังสาขาปัจจุบันโดยสร้างเป็น Commit แฝดตัวใหม่ ข้อพึงระวังในระบบ CI/CD คือหากดึงมาทับซ้อนบ่อยครั้งโดยไม่ระบุโครงสร้างความสัมพันธ์อาจเกิดปัญหา Commit ซ้ำซ้อนและปัญหากดรวมสาขาหลักล้มเหลวภายหลัง

🌳 Interactive Git Branch Visualizer

Interactive Graph

เป้าหมาย: สร้างกิ่งใหม่ชื่อ dev (ใช้ git checkout -b dev), ทำการบันทึกโค้ด (ใช้ git commit -m "add feature"), สลับกลับไปที่กิ่งหลัก main (ใช้ git checkout main) และรวมงานด้วยคำสั่ง git merge dev

Visual Git Commit History Tree C0 (Initial)
git bash console Active Branch: main
Git repository initialized. Type 'git help' for commands.
$ git

ข้อดี / จุดเด่น & ข้อเสีย / ข้อควรระวัง

ข้อดี / จุดเด่น

  • สามารถย้อนกลับเวอร์ชันการทำงานของท่อข้อมูลได้ตลอดเวลาเมื่อเกิดความเสียหาย
  • ช่วยให้คนในทีมหลายสิบคนสามารถเขียนโค้ดท่อข้อมูลและแก้ไขส่วนต่างๆ ได้พร้อมกัน

ข้อเสีย / ข้อควรระวัง

  • เกิดปัญหา Merge Conflict เมื่อมีคนแก้ไขไฟล์เดียวกันบนบรรทัดเดียวกันพร้อมกัน
  • การใช้ Git สำหรับเก็บไฟล์ข้อมูลดิบขนาดใหญ่ (เช่น CSV, Parquet ขนาด GB) จะทำให้ Repository หน่วงและช้ามาก

ปฏิบัติการจริง (Lab Practice)

Bilingual Guide

แล็บ: การรวมกิ่งและแก้ไข Merge Conflict

💡 คำแนะนำ & ทริกเด็ด

ก่อนรันโค้ดขึ้นระบบคลาวด์ ตรวจสอบให้แน่ใจว่าได้ระบุไฟล์เก็บความลับ เช่น `.env` หรือโฟลเดอร์เก็บแคชข้อมูลดิบลงใน `.gitignore` เสมอ เพื่อความปลอดภัยจากการทำ API Key รั่วไหลออกสู่สารธารณะ