PipeCraft

Roadmap Progress

ข้อมูลเบื้องต้นเกี่ยวกับวิศวกรรมข้อมูล (Introduction to Data Engineering) Python สำหรับ Data Engineering พื้นฐาน Linux & CLI สำหรับวิศวกรข้อมูล Git สำหรับระบบงานข้อมูลและทีมพัฒนา พื้นฐานเครือข่าย เว็บเทคโนโลยี และระบบกระจายศูนย์ (Web Fundamentals, 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) รากฐานของ AWS VPC การจัดการเส้นทางขั้นสูงและ NAT Gateway การเชื่อมต่อหลาย VPC และ Hybrid Cloud VPC Endpoints (PrivateLink) ระบบรักษาความปลอดภัยขอบเขตเครือข่าย สถาปัตยกรรมเครือข่ายสำหรับ EKS IPv6 และการจัดการ IP Address สถาปัตยกรรมเครือข่ายระดับโลก แก่นแท้ของสถาปัตยกรรม Kubernetes สถาปัตยกรรมเครื่องและคอมโพเนนต์ เลเยอร์ที่เชื่อมต่อได้ (Pluggable Layers) การรันบนโปรดักชันระดับองค์กร Apache Flink Stateful Stream Processing Real-Time CDC & Event Sourcing at Scale Low-Latency Stream-Table Joins & Windowing Data Lineage & Metadata Graph Engineering Statistical Anomaly Detection & Data Drift Data Incident Management & Automated DLQ Remediation Cloud Data FinOps & Cost Optimization Mechanics Data Mesh & Multi-Tenant Platform Architecture Vector Databases & AI-Ready Data Infrastructure API Fundamentals, Architectures & Core Components API Versioning, Docs, Real-Time & Microservices Production Reliability, Security & Resiliency World-Class Master Architecture & Traffic Management
บทที่ 5: ระบบประมวลผลขนาดใหญ่และการจัดลำดับงาน (Orchestration, Scale & Streaming)

การประมวลผลข้อมูลแบบเรียลไทม์ด้วย Kafka & Redpanda

5.3 การส่งสัญญาณประมวลผลข้อมูลเรียลไทม์ (Kafka & Flink)

สถาปัตยกรรมสตรีมมิ่งข้อมูล (Data Streaming) ประมวลผลข้อมูลทันทีเมื่อเกิดเหตุการณ์ขึ้น โดยเก็บข้อมูลใน Message Broker เพื่อส่งต่อไปยังผู้บริโภคข้อมูลเรียลไทม์และตัวประมวลผลสตรีม (Stream Processing Engine)

Technical Architecture Diagram
Click to Zoom
3D Isometric Architecture Breakdown:
  • Step 1: Data Ingestion & Event Processing
  • Step 2: Distributed Computation & State Management
  • Step 3: Orchestration & Resource Allocation

1. โครงสร้างภายในตารางกระทู้แยกส่วนและการจดจำ Offset (Topic Partitioning Internals)

Learning Progression

  • [BASIC] ปูพื้นฐานภาษาเข้าใจง่าย - เข้าใจคอนเซปต์ภาพรวมและการแก้ปัญหาเบื้องต้น
  • [INTERMEDIATE] โค้ด/คอนฟิกไวยากรณ์จริง - การเขียนโค้ดเพื่อใช้งานจริงในระบบ
  • [PROFESSIONAL] Under-the-hood & Performance/FinOps - กลไกเบื้องลึกและการรีดประสิทธิภาพ

Real-World Enterprise Scenario

เคสระบบการเงิน/Big Tech: การรองรับ Transaction จำนวนมหาศาลต่อวินาทีพร้อมประกัน Data Integrity สูงสุด โดยใช้สถาปัตยกรรมที่ยืดหยุ่นและการมอนิเตอร์ระดับสูง

ทฤษฎีและกลไกการทำงาน (How it works): Apache Kafka จัดเก็บข้อมูลแต่ละหัวข้อ (Topic) แบบกระจายศูนย์โดยแบ่งออกเป็น **Partitions** ซึ่งมีโครงสร้างจัดเก็บแบบเขียนต่อท้ายไฟล์อย่างเดียว (Append-only Commit Log) ข้อมูลแต่ละตัวที่แทรกจะได้รับรหัสตำแหน่ง **Offset** ประจำตัว กลไกนี้ช่วยให้ระบบสตรีมมิ่งสามารถอ่านข้อมูลขนานกันได้โดยไม่มีสะดุด และยินยอมให้ผู้รับ (Consumer) ย้อนไปดึงข้อมูลใหม่ ณ ตำแหน่งใดก็ได้ย้อนหลังตาม Offset ที่บันทึกไว้

# Concept of Kafka Topic partitioning and offsets layout
Topic: sales-clicks
   ├── Partition 0: [Msg 0 (Offset 0)] -> [Msg 1 (Offset 1)] -> [Msg 2 (Offset 2)]
   └── Partition 1: [Msg 0 (Offset 0)] -> [Msg 1 (Offset 1)]
                    

Use Case ในชีวิตจริง (Real-world Scenario): ยอดดาวน์โหลดกดไลก์เพจจากลูกค้าทั่วประเทศวิ่งเข้ามาพร้อมกัน 50,000 ครั้งต่อวินาที ทราฟฟิกจะโดนหั่นแยกเป็น 8 พาร์ทิชันกระจายแบ่งเบาภาระงานให้ Worker 8 ตัวคำนวณสรุปผลยอดได้เรียลไทม์

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การเลือกใช้คีย์พาร์ทิชันที่ไม่มีการกระจาย (Bad partitioning key) ทำให้ข้อมูลเกือบทั้งหมดตกไปที่พาร์ทิชันเดียวเกิด Data Skew แก้ไขโดยเลือกใช้คีย์ที่กระจายตัวสูง เช่น ID ลูกค้า (Customer UUID)

2. Kafka Rebalance Protocols (Eager vs Cooperative Sticky)

ทฤษฎีและกลไกการทำงาน (How it works): เมื่อมีการเพิ่ม/ลด Consumer ในกลุ่ม Kafka ต้องทำ **Rebalance** แจกจ่าย Partition ใหม่: - **Eager Rebalance (เก่า)**: หยุดการทำงานของ Consumer ทุกตัว (Stop-the-world) เพิกถอนสิทธิ์ Partition ทั้งหมด แล้วค่อยแจกใหม่ ทำให้ระบบหยุดชะงักชั่วคราว - **Cooperative Sticky Rebalance (ใหม่)**: ทยอยคืนสิทธิ์เฉพาะ Partition ที่จำเป็นต้องย้ายไปยัง Consumer ตัวใหม่ ส่วน Consumer ตัวอื่นยังคงประมวลผล Partition เดิมของตนต่อไปได้โดยไม่หยุดชะงัก

# Enabling Cooperative Sticky Rebalance in Kafka Consumer
from kafka import KafkaConsumer

consumer = KafkaConsumer(
    "production-clickstream",
    bootstrap_servers=["kafka-1:9092"],
    group_id="click-metrics-aggregator",
    partition_assignment_strategy=["org.apache.kafka.clients.consumer.CooperativeStickyAssignor"]
)
                    

Use Case ในชีวิตจริง (Real-world Scenario): คลัสเตอร์ที่มี 500 Consumers กำลังประมวลผลหลักแสนข้อความต่อวินาที หากใช้ Eager Rebalance การเพิ่ม Pod 1 ตัวจะทำให้ทั้งระบบหยุดชะงักไปหลายวินาทีเกิดคิวสะสม การเปลี่ยนมาใช้ Cooperative Sticky ทำให้การอัปสเกลราบรื่นระดับมิลลิวินาที

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): ข้อผิดพลาด **Rebalance Storm** จากการที่ Consumer ค้าง/คำนวณช้าเกิน `max.poll.interval.ms` แก้ไขโดยการแยกงานคำนวณหนักๆ ออกไปประมวลผลแบบอะซิงโครนัส หรือปรับจูนรอบ Polling และใช้ Cooperative Sticky

3. ความเสถียรข้อมูลและการกำหนดการสำเนากลุ่ม (ISR & Replication Configs)

ทฤษฎีและกลไกการทำงาน (How it works): เพื่อค้ำประกันไม่ให้ข้อความสูญหาย Kafka นำระบบการคัดลอกสำเนามาใช้งานโดยใช้ **In-Sync Replicas (ISR)** หากกำหนดพารามิเตอร์ส่งข้อมูล `acks=all` ตัว Producer จะสแตนด์บายรอจนกว่าเครื่อง Leader และ Follower ภายในกลุ่ม ISR ทั้งหมดจะเขียนลงดิสก์สำเร็จ จึงจะยืนยัน (Ack) กลับไป

# Producer configuration demonstrating zero data loss settings
from kafka import KafkaProducer

producer = KafkaProducer(
    bootstrap_servers=["kafka-1:9092", "kafka-2:9092"],
    acks="all",            # Wait for replica handshakes before confirming write
    retries=5,             # Retry sending on transient failures
)
                    

Use Case ในชีวิตจริง (Real-world Scenario): ระบบโอนเงินธนาคาร การสูญหายของข้อความเพียงรายการเดียวหมายถึงหายนะ การเปิดใช้ `acks=all` คู่กับ `min.insync.replicas=2` (ต้องบันทึกติดอย่างน้อย 2 เครื่อง) ช่วยค้ำประกันให้ธุรกรรมคงอยู่ถาวรแม้เครื่องหนึ่งพัง

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การกำหนด `acks=all` ทำให้เกิด Latency ในการตอบสนองที่สูงขึ้น (Throughput drop) แก้ไขโดยเพิ่ม Batch Size และใช้การบีบอัดข้อความ (Compression type: snappy/lz4) หรือยอมลดระดับเป็น `acks=1` สำหรับข้อมูลที่ไม่สำคัญ (เช่น Log)

4. Exactly-Once Semantics (EOS) & Transactional Producer

ทฤษฎีและกลไกการทำงาน (How it works): ในการประมวลผลข้อความ: - **At-Least-Once**: ระเบียบข้อมูลอาจส่งซ้ำเมื่อเกิดข้อผิดพลาด - **Exactly-Once Semantics (EOS)**: ค้ำประกันว่าข้อมูลจะถูกประมวลผลและส่งต่อเพียง "ครั้งเดียวถ้วน" โดยใช้ **Idempotent Producer** (ป้องกันการเขียนซ้ำ) ร่วมกับ **Kafka Transactions** (Atomic Commit ระหว่างการรับ Offset ขาเข้า และการเขียนข้อความขาออก)

# Conceptual settings to achieve exactly-once processing in Kafka
# 1. Enable idempotence and transactions in Producer
producer_config = {'enable.idempotence': True, 'transactional.id': 'prod-tx-01'}
# 2. Configure Consumer to read only completed transactions
consumer_config = {'isolation.level': 'read_committed'}
                    

Use Case ในชีวิตจริง (Real-world Scenario): ท่อส่งเงินเดือนพนักงานปลายทางที่ห้ามเกิดยอดประมวลผลซ้ำซ้อน (Double payments) การใช้ Kafka Transactional API ครอบรอบการประมวลผล จะรับประกันว่าถ้าจ๊อบพังกลางคัน ระบบจะทำการ Rollback ข้อมูลกลับทั้งหมด

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): ระบบ EOS มี Overhead การทำงานที่สูงและต้องการทรัพยากรเพิ่มขึ้นอย่างมีนัยสำคัญ อีกทั้งยังใช้ได้ผลสมบูรณ์เฉพาะสถาปัตยกรรมแบบ Kafka-to-Kafka เท่านั้น หากเขียนลงฐานข้อมูลนอก ต้องออกแบบปลายทางให้รองรับ Idempotent Update แทน

5. Apache Flink State Backends (RocksDB) & Checkpointing

ทฤษฎีและกลไกการทำงาน (How it works): เครื่องมือประมวลผลสตรีมมิ่งขั้นสูงอย่าง Apache Flink ต้องจำ "สถานะ" (State) ของข้อมูลที่ไหลเข้ามา (เช่น ผลรวมยอดขายในกรอบเวลา 1 ชม.) - **State Backends**: หน้าที่จัดเก็บสถานะ หากข้อมูลใหญ่กว่า RAM Flink จะใช้ **RocksDB State Backend** บันทึกสถานะชั่วคราวลง Local Disk อย่างมีประสิทธิภาพ - **Checkpointing**: Flink จะกระจายสัญญาณ (Barriers) เข้าไปในสายน้ำข้อมูล เพื่อสั่งให้ทุก Node ทำ Snapshot สถานะของตัวเองส่งไปเก็บไว้ใน Distributed Storage (เช่น S3) เมื่อเกิดระบบล่ม Flink สามารถย้อนเวลา (Rewind) ค่ากลับมาที่จุด Checkpoint ล่าสุดได้เป๊ะๆ

# Flink Python API enabling RocksDB and Checkpointing
from pyflink.datastream import StreamExecutionEnvironment
from pyflink.datastream.checkpointing_mode import CheckpointingMode

env = StreamExecutionEnvironment.get_execution_environment()
# Snapshot state every 60 seconds
env.enable_checkpointing(60000, CheckpointingMode.EXACTLY_ONCE)
# Use RocksDB to handle state larger than available memory
env.get_config().set_string("state.backend", "rocksdb")
env.get_config().set_string("state.checkpoints.dir", "s3://flink-checkpoints/prod/")
                    

Use Case ในชีวิตจริง (Real-world Scenario): ระบบตรวจสอบเครดิตการ์ดทุจริตเรียลไทม์ (Fraud Detection) ต้องจดจำพฤติกรรมลูกค้าข้ามเวลา (Windowed State) เมื่อใช้ RocksDB คู่กับ S3 Checkpoint หาก Pod ของ Flink ล่ม ระบบจะถูกสปินขึ้นใหม่ โหลดสถานะเดิมกลับมาภายในไม่กี่วินาที ไม่เสียข้อมูล

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): หากเปิด Checkpoint ถี่เกินไป (เช่น ทุก 1 วินาที) จะทำให้ระบบเผชิญ I/O Bottleneck หนักในการเขียนลง S3 แก้ไขโดยปรับรอบให้อยู่ระหว่าง 1-5 นาทีตามความเหมาะสมของธุรกิจ หรือใช้ฟีเจอร์ Incremental Checkpoints ของ RocksDB

Weekend Sandbox Challenge: Build a Transactional Kafka Pipeline

โจทย์ปฏิบัติการ: จงเขียนโปรแกรม Python (หรือพิจารณา PyFlink) ที่กำหนดคอนฟิกจำลองการทำงานแบบ Exactly-Once โดยจำลองตั้งค่า Consumer เป็นแบบ `read_committed`

# eos_consumer.py
from kafka import KafkaConsumer

consumer = KafkaConsumer(
    'production-sales',
    bootstrap_servers=['localhost:9092'],
    enable_auto_commit=False, # Disable auto-commit
    group_id='sales-verifier',
    isolation_level='read_committed' # Reads only committed transactional messages
)

for message in consumer:
    # 1. Process records (Simulate database insert)
    print(f"Processing committed record: {message.value.decode('utf-8')}")
    # 2. Commit offsets manually only after writing is successful
    consumer.commit()
                    

Senior Technical Interview Q&A

Q1: Cooperative Sticky Rebalance แตกต่างจาก Eager Rebalance อย่างไร และทำไมคลัสเตอร์ขนาดใหญ่ถึงควรใช้?

A1: Eager Rebalance ใช้ยุทธวิธี Stop-the-world โดย Consumer ทั้งหมดจะต้องหยุดประมวลผล เพิกถอนสิทธิ์ Partition ทั้งหมด แล้วรอสิทธิ์ใหม่ ทำให้เกิดดาวน์ไทม์ชั่วคราวสะสมคิวยาวในคลัสเตอร์ใหญ่ แต่ Cooperative Sticky จะค่อยๆ ทยอยโยกย้ายสิทธิ์เฉพาะ Partition ที่จำเป็นต้องย้ายไปยัง Consumer เครื่องใหม่ ทำให้เครื่องที่เหลือยังทำงานต่อได้โดยไม่เกิดจังหวะชะงัก (No downtime)

Q2: ทำไม Apache Flink จึงต้องใช้ RocksDB เป็น State Backend คู่กับ Checkpointing mechanism แทนที่จะใช้ RAM เปล่าๆ?

A2: ในการประมวลผล State ที่มีความซับซ้อน เช่น Windowing ย้อนหลังหลายวัน ขนาดของ State อาจพุ่งทะลุขนาด RAM ปกติ (OOM) การใช้ RocksDB ช่วยให้ Flink เทยาลง Local Disk ได้อย่างมีประสิทธิภาพ และกลไก Checkpointing ทำหน้าที่เซฟ Snapshot รหัสสถานะและ Offset ทั้งหมดขึ้น Object Storage ถาวร (เช่น S3) เมื่อเครื่องพัง Flink จะสามารถ Rewind ระบบคืนค่าเดิมกลับมาทำงานต่อแบบ Exactly-Once ได้สมบูรณ์

Real-time Event Streaming & Lag Monitor

Interactive Streaming

เป้าหมาย: แก้ไขวิกฤตคอขวดข้อมูล (High Consumer Lag) เนื่องจากความเร็วในการดึงข้อมูลของระบบตามหลังการส่งสัญญาณคีย์คลิก (Producer) โดยคลิก **Scale Consumer** เพื่อจัดสรร Consumer Group ให้ครบ 3 โหนด ทำงานแบบขนานกับ 3 พาร์ทิชัน

Event Producer
P
user_clicks_stream ● 60 events/sec
Topic: user-clicks
Partition 0 Lag: 0
Partition 1 Lag: 2450
Partition 2 Lag: 3120
Consumer Group
Consumer-1
Offline
Offline
Consumer Group scaling controls
ขยาย Consumer เพื่อดึงข้อมูลขนาน ป้องกันเหตุการณ์ข้อมูลล่าช้าและสูญหาย

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

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

  • ประมวลผลข้อมูลสดใหม่ได้ความเร็วระดับมิลลิวินาที ตอบรับเหตุการณ์ธุรกิจรวดเร็ว
  • เป็นแหล่งจัดเก็บข้อมูลชั่วคราวที่มีเสถียรภาพและขยายระบบได้แนวนอนยอดเยี่ยม

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

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

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

Bilingual Guide

แล็บ: สร้างและสตรีมข้อมูลผ่าน Redpanda Playground

วิธีรันแล็บปฏิบัติการบนเครื่องจริง (Local Terminal Execution Blueprint)

เนื่องจากปฏิบัติการ Data Engineering / DevOps ระดับสูงต้องรันบน Environment จริง ขั้นตอนด้านล่างนี้คือคำสั่งสำหรับนำไปรันบน Terminal / Docker ในเครื่องของคุณ:

1. สร้างโฟลเดอร์ปฏิบัติการและเตรียมไฟล์ Environment
mkdir -p pipecraft-lab && cd pipecraft-lab
python3 -m venv venv && source venv/bin/activate
pip install --upgrade pip pandas polars pytest requests
2. จำลองการสร้างและรันระบบประมวลผล (Run Pipeline Command)
# Run execution pipeline test
python3 -c "
import polars as pl
print(' [PipeCraft Lab] Running local pipeline engine...')
df = pl.DataFrame({'id': [1, 2, 3], 'status': ['SUCCESS', 'SUCCESS', 'AUDITED']})
print(df)
" 
3. ตรวจสอบการผ่านเกณฑ์และการทำงาน (Data Quality Assertions)
# Verify clean execution exit status
echo " PipeCraft Local Lab Execution Completed Successfully!"

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

ควรตรวจสอบค่า Lag ของ Consumer อยู่เสมอ หากค่าเริ่มสูงขึ้น แสดงว่าโค้ดดึงประมวลผลช้าเกินไป ให้ทำการเพิ่มจำนวน Partition และขยาย Consumers ขึ้นมาทำงานขนานช่วย