

Parquet Format Cloud Native Design — คู่มือฉบับสมบูรณ์ 2026
ในยุคที่ข้อมูลคือน้ำมันเชื้อเพลิงดิจิทัล การเลือกรูปแบบการจัดเก็บข้อมูล (Data Format) ที่มีประสิทธิภาพถือเป็นรากฐานที่สำคัญที่สุดอย่างหนึ่งของสถาปัตยกรรมข้อมูลสมัยใหม่ หนึ่งในรูปแบบที่ได้รับความนิยมสูงสุดและกลายเป็นมาตรฐานโดยพฤตินัยในระบบ Data Lake, Data Warehouse และระบบประมวลผลขนาดใหญ่ก็คือ Apache Parquet แต่การจะดึงศักยภาพของ Parquet ออกมาได้อย่างเต็มที่ในสภาพแวดล้อม Cloud Native นั้น จำเป็นต้องเข้าใจการออกแบบที่ลึกไปกว่าแค่การเซฟไฟล์ ในบทความฉบับสมบูรณ์นี้ เราจะเจาะลึกถึงหลักการออกแบบ Parquet แบบ Cloud Native, Best Practices ระดับ Production, และกรณีศึกษาในโลกจริงเพื่อให้คุณพร้อมรับมือกับความท้าทายด้านข้อมูลในปี 2026 และต่อไป
ทำความรู้จักกับ Apache Parquet: มันดีกว่าอย่างไร?
Apache Parquet คือรูปแบบไฟล์คอลัมน์นาร์ (Columnar Storage Format) แบบโอเพนซอร์สที่ออกแบบมาสำหรับระบบประมวลผลข้อมูลแบบกระจาย (เช่น Hadoop, Spark, Presto) โดยเฉพาะ ความแตกต่างหลักจากรูปแบบแถวนาร์ (Row-based) อย่าง CSV หรือ Avro (ในบางโหมด) คือการจัดเก็บข้อมูลเป็นคอลัมน์แทนที่จะเป็นแถว
สถาปัตยกรรมคอลัมน์นาร์: ใจความสำคัญของประสิทธิภาพ
ลองนึกภาพตารางข้อมูลที่มี 1 ล้านแถวและ 100 คอลัมน์ หากคุณต้องการคำนวณค่าเฉลี่ยของเพียงแค่ 2 คอลัมน์เท่านั้น:
- รูปแบบแถวนาร์ (Row-based): ระบบต้องโหลดข้อมูลทั้งแถว (ทั้งหมด 100 คอลัมน์) เข้ามาในหน่วยความจำก่อน จากนั้นจึงค่อยกรองเอาคอลัมน์ที่ต้องการออกมาเพื่อคำนวณ ส่งผลให้การอ่านข้อมูลส่วนใหญ่ (98 คอลัมน์) เป็นการอ่านที่สูญเปล่า (I/O Inefficiency)
- รูปแบบคอลัมน์นาร์ (Columnar – Parquet): ระบบจะอ่านเฉพาะคอลัมน์ที่ 23 และคอลัมน์ที่ 87 เท่านั้นจากไฟล์ ทำให้ปริมาณข้อมูลที่ต้องอ่านจากดิสก์หรือเครือข่ายลดลงอย่างมหาศาล ประหยัดทั้ง I/O, หน่วยความจำ และแบนด์วิธ
นอกจากนี้ การที่ข้อมูลประเภทเดียวกันถูกจัดเก็บอยู่ติดกัน (เช่น ค่า Integer ทั้งหมดของคอลัมน์หนึ่ง) ยังเปิดโอกาสให้ใช้เทคนิคการบีบอัดข้อมูล (Compression) ที่มีประสิทธิภาพสูง เช่น Dictionary Encoding, Run-Length Encoding (RLE) ได้อย่างดีเยี่ยม
โครงสร้างทางกายภาพของไฟล์ Parquet
ไฟล์ Parquet หนึ่งไฟล์ประกอบด้วยส่วนสำคัญดังนี้:
- Row Groups: การแบ่งข้อมูลภายในไฟล์ออกเป็นกลุ่มแถว (คล้ายกับ Pages) แต่ละ Row Group ประกอบด้วยข้อมูลของทุกคอลัมน์สำหรับแถวชุดนั้นๆ และสามารถประมวลผลแบบอิสระต่อกันได้ (Parallel Processing)
- Column Chunks: ข้อมูลของแต่ละคอลัมน์ภายใน Row Group หนึ่งๆ
- Pages: หน่วยย่อยภายใน Column Chunks ที่ใช้สำหรับการบีบอัดและเข้ารหัส
- Footer (Metadata): ส่วนท้ายไฟล์ที่สำคัญที่สุด ซึ่งเก็บ Schema, Metadata ของ Row Groups/Column Chunks, และ Statistics (เช่น min, max, count, null count) ของแต่ละคอลัมน์ในแต่ละ Row Group
File Structure:
+------------------------+
| Magic Number (4 bytes) |
+------------------------+
| Row Group 1 |
| - Column A Chunk |
| - Column B Chunk |
+------------------------+
| Row Group 2 |
| - Column A Chunk |
| - Column B Chunk |
+------------------------+
| ... |
+------------------------+
| FOOTER (Metadata) |
+------------------------+
| Footer Length (4 bytes)|
+------------------------+
| Magic Number (4 bytes) |
+------------------------+
การออกแบบ Cloud Native สำหรับ Parquet: หลักการสำคัญ
การออกแบบ Cloud Native ไม่ได้หมายถึงแค่การย้ายไฟล์ Parquet ขึ้น Cloud Object Storage (เช่น AWS S3, Google Cloud Storage, Azure Blob Storage) เท่านั้น แต่เป็นการออกแบบระบบที่สอดคล้องกับคุณสมบัติของคลาวด์: แบบจ่ายตามการใช้งาน (Pay-as-you-go), ความยืดหยุ่นสูง (Elasticity), และการทำงานแบบไร้เซิร์ฟเวอร์ (Serverless)
1. การจัดการกับ Object Storage ที่มี Latency สูง
Cloud Object Storage มี Latency สูงกว่า Local HDFS อย่างมีนัยสำคัญ การออกแบบต้องลดจำนวนการเรียกอ่าน (List/Read Operations) ให้น้อยที่สุด
- หลีกเลี่ยงไฟล์เล็กจำนวนมาก (Small Files Problem): การมีไฟล์ Parquet ขนาดเล็กหลายหมื่นไฟล์จะทำให้การอ่าน Metadata ช้าและมีค่าใช้จ่ายสูง (เนื่องจากมี Request จำนวนมาก) ควรรวมไฟล์ให้มีขนาดเหมาะสม (แนะนำระหว่าง 256 MB ถึง 1 GB ต่อไฟล์)
- ใช้การอ่านแบบ Predicate Pushdown อย่างมีประสิทธิภาพ: ต้องออกแบบ Schema และเลือก Partition Key ให้สอดคล้องกับรูปแบบการ query เพื่อให้ระบบสามารถตัดทิ้ง (Prune) Row Groups และไฟล์ที่ไม่เกี่ยวข้องได้ตั้งแต่ต้น
2. การออกแบบ Schema ให้เหมาะกับคลาวด์
Schema ของ Parquet มีผลกระทบโดยตรงต่อประสิทธิภาพและค่าใช้จ่าย
// ตัวอย่าง Schema ที่ออกแบบไม่ดี (Nested Structure ซับซ้อนเกินไป)
message bad_schema {
required string user_id;
optional group events (LIST) {
repeated group event {
required int64 timestamp;
optional string action;
optional group details (MAP) {
repeated group key_value {
required string key;
optional string value;
}
}
}
}
}
// ตัวอย่าง Schema ที่ออกแบบดีแล้ว (แยก Column, ใช้ประเภทข้อมูลเหมาะสม)
message good_schema {
required string user_id;
required int64 event_timestamp;
required string event_action;
optional string detail_key_1; // Flattened จาก MAP
optional string detail_key_2;
}
หลักการออกแบบ Schema:
- เลือกประเภทข้อมูลที่เหมาะสม: ใช้ INT32 แทน INT64 หากค่าอยู่ในช่วงที่เล็กกว่า ใช้ DATE/TYPE ประเภทเฉพาะของ Parquet แทนการเก็บเป็น String
- ลดความซับซ้อนของ Nested Structure: โครงสร้างที่ซับซ้อนมากอาจทำให้การอ่านช้าลงในบางเอ็นจิ้น พิจารณา Flatten บางส่วนหากจำเป็น
- เรียงลำดับคอลัมน์: วางคอลัมน์ที่ใช้ใน WHERE clause บ่อยๆ หรือคอลัมน์ที่ใช้สำหรับการเรียงลำดับไว้ด้านหน้า เพื่อประโยชน์ในการบีบอัด
3. การแบ่งพาร์ติชัน (Partitioning) และการจัดระเบียบข้อมูล
การแบ่งพาร์ติชันคือหัวใจของประสิทธิภาพในคลาวด์ โดยทั่วไปใช้ Hive-style partitioning
s3://my-data-lake/events/
year=2026/
month=01/
day=01/
event-00001.parquet
event-00002.parquet
day=02/
month=02/
year=2025/
คำแนะนำในการเลือก Partition Key:
- เลือกคอลัมน์ที่มักใช้ใน WHERE clause (เช่น date, region, tenant_id)
- ต้องไม่ทำให้เกิด Partition จำนวนมากเกินไป (Partition Explosion) เช่น การพาร์ติชันด้วย user_id โดยตรงจะสร้าง partition เป็นล้านอันซึ่งจัดการยาก ควรใช้ระดับพาร์ติชันที่ให้ขนาดข้อมูลต่อ partition ประมาณ 1GB ขึ้นไป
- พิจารณาใช้ Partitioning ร่วมกับ Clustering/Z-Ordering ในระบบเช่น Delta Lake หรือ Iceberg เพื่อประสิทธิภาพที่สูงขึ้น
การเปรียบเทียบ: Parquet vs อื่นๆ ในสภาพแวดล้อมคลาวด์
เพื่อให้เห็นภาพชัดเจน เรามาเปรียบเทียบ Parquet กับรูปแบบไฟล์ยอดนิยมอื่นๆ ในมุมมอง Cloud Native
| รูปแบบ | Parquet | CSV/JSON | Avro (Row) | ORC |
|---|---|---|---|---|
| รูปแบบการจัดเก็บ | คอลัมน์นาร์ | แถวนาร์ | แถวนาร์ | คอลัมน์นาร์ |
| การบีบอัด | ยอดเยี่ยม | พอใช้ | ดี | ยอดเยี่ยม |
| Schema Evolution | รองรับดี (Add/Drop) | ไม่มี Schema | รองรับดีมาก | รองรับดี |
| เหมาะสำหรับ | Analytical Query, Aggregation | Data Exchange, Logging | Event Streaming, Serialization | Analytical Query (Hive) |
| Cloud Native Cost (I/O) | ต่ำมาก (อ่านเฉพาะคอลัมน์) | สูงมาก (อ่านทั้งหมด) | สูง (อ่านทั้งหมด) | ต่ำมาก |
| Ecosystem Support | กว้างมาก (ทุกเครื่องมือ) | กว้างมาก | กว้าง | กว้าง (แต่เน้น Hadoop) |
Parquet vs. Format ล้ำสมัยอย่าง Delta Lake และ Apache Iceberg
Delta Lake และ Iceberg ไม่ใช่รูปแบบไฟล์ แต่เป็น “Table Format” ชั้นสูงที่ใช้ Parquet (หรือ ORC) เป็นฐานเก็บข้อมูล และเพิ่มคุณสมบัติด้าน Transaction (ACID), Time Travel, และ Metadata Management ที่ทรงพลัง
| Feature | Raw Parquet Files | Delta Lake / Iceberg |
|---|---|---|
| ACID Transactions | ไม่มี (ต้องจัดการเอง) | มี (พร้อม Concurrent Reads/Writes) |
| Time Travel | ทำได้ยาก (ต้องมี Versioning เอง) | มีในตัว (Query data as of time) |
| Schema Enforcement/Evolution | พื้นฐาน | แข็งแกร่ง (ป้องกัน Data Corruption) |
| Metadata Performance | ช้าเมื่อมีไฟล์มาก (ต้อง List ทั้งหมด) | เร็ว (มี Metadata Layer ที่ optimize) |
| ความซับซ้อน | ต่ำ | สูง (ต้องมีระบบจัดการ) |
| Use Case หลัก | Data Lake ขั้นพื้นฐาน, Batch Archive | Lakehouse, Continuous Data Ingestion, ML Pipelines |
Best Practices ระดับ Production สำหรับปี 2026
จากประสบการณ์การใช้งานจริงในสเกลใหญ่ เราขอสรุป Best Practices ที่ควรปฏิบัติตาม
1. การปรับแต่งขนาดไฟล์และ Row Group
- ขนาดไฟล์ที่เหมาะสม: ตั้งเป้าไว้ที่ 256 MB ถึง 1 GB ต่อไฟล์บนคลาวด์ ขนาดนี้ลดปัญหา Small Files ในขณะที่ยังไม่ใหญ่เกินไปจนปรับ Scalability ได้ยาก
- Row Group Size: ตั้งค่า Row Group ให้มีขนาดประมาณ 128 MB ถึง 256 MB เพื่อให้การ Predicate Pushdown ทำงานได้ละเอียด และเหมาะกับการประมวลผลแบบขนาน
- Page Size: มักตั้งไว้ที่ 1 MB ซึ่งเป็นค่าที่เหมาะสมสำหรับการบีบอัดและการอ่าน
# ตัวอย่างการเขียน Parquet ใน Apache Spark ด้วยการตั้งค่าเฉพาะ
df.write \
.option("parquet.block.size", 256 * 1024 * 1024) # Row Group Size = 256MB
.option("parquet.page.size", 1024 * 1024) # Page Size = 1MB
.option("parquet.dictionary.page.size", 32 * 1024 * 1024) # Dictionary Size
.option("parquet.enable.dictionary", "true")
.mode("overwrite") \
.parquet("s3a://my-bucket/data/output/")
2. การบีบอัดข้อมูล: เลือก Codec อย่างไร?
การเลือก Compression Codec เป็นการ trade-off ระหว่างอัตราการบีบอัด ความเร็ว และการใช้ทรัพยากร CPU
- Snappy (แนะนำเริ่มต้น): ความเร็วสูง อัตราการบีบอัดพอใช้ เหมาะกับข้อมูลที่ต้องอ่านบ่อย
- Gzip/Zstd: อัตราการบีบอัดดีเยี่ยม (Zstd ดีกว่า Gzip) แต่ใช้ CPU สูงกว่า เหมาะกับข้อมูลที่เก็บถาวรหรือข้อมูลที่อ่านไม่บ่อย (Cold Storage)
- LZO: ความเร็วสูง แต่ไม่รองรับโดยค่าเริ่มต้นในบางระบบ
คำแนะนำ: ใช้ Snappy สำหรับข้อมูลที่ใช้งานบ่อยใน Data Lake และใช้ Zstd สำหรับการ Archive ข้อมูลเก่าเพื่อประหยัดพื้นที่เก็บซึ่งส่งผลต่อค่าใช้จ่ายคลาวด์โดยตรง
3. การจัดการ Metadata และการค้นพบไฟล์
ในคลาวด์ การ List ไฟล์จำนวนมากมีค่าใช้จ่ายและเวลา ควรใช้เครื่องมือช่วย:
- ใช้ AWS Glue Data Catalog, Google Dataplex, หรือ Azure Purview: เป็น Metadata Catalog ศูนย์กลาง เพื่อให้ระบบ Query Engine (Athena, BigQuery, Synapse) ค้นพบข้อมูลได้เร็ว
- หลีกเลี่ยงการทำ MSCK REPAIR TABLE บ่อยครั้ง: ใน Spark/Athena หากเพิ่มพาร์ติชันใหม่ ให้ใช้ `ALTER TABLE ADD PARTITION` แทนที่จะสั่ง Repair ทั้งตาราง
- พิจารณาใช้ Table Format (Delta/Iceberg): หากระบบของคุณมีปัญหากับ Metadata Management ของ Raw Parquet โดยตรง
กรณีศึกษาในโลกจริง (Real-World Use Cases)
Case 1: บริษัท E-Commerce — Data Lakehouse สำหรับการวิเคราะห์ผู้ใช้
ความท้าทาย: มีข้อมูลเหตุการณ์ (คลิก, ดูสินค้า, ซื้อ) จำนวน 10TB ต่อวันจากหลายแหล่ง ต้องการ query วิเคราะห์แบบ interactive และ batch processing
โซลูชัน Cloud Native ด้วย Parquet:
- Data Ingestion: ใช้ Kafka + Spark Streaming เพื่อ consume ข้อมูลมาเขียนเป็น Parquet ลง S3 ทุก 15 นาที (Micro-batch) โดยจัดพาร์ติชันเป็น `project=ecome/event_type=view/year=2026/month=01/day=01/hour=00/`
- File Sizing: ตั้งค่าให้แต่ละไฟล์มีขนาดประมาณ 300MB หลังเขียน
- Query Layer: ใช้ Amazon Athena (Presto) และ Redshift Spectrum เพื่อ query ข้อมูลจาก S3 โดยตรง โดย Athena ใช้ Statistics ใน Parquet Footer เพื่อเร่งความเร็ว query ได้อย่างมีนัยสำคัญ
- ผลลัพธ์: ลดเวลา query ที่เคยใช้จากหลายนาทีเหลือไม่กี่วินาที ค่าใช้จ่ายด้าน Storage ลดลง 70% เนื่องจากบีบอัดได้ดี และลดปริมาณข้อมูลที่ Scan ลงได้มาก
Case 2: Startup FinTech — Feature Store สำหรับ Machine Learning
ความท้าทาย: ทีม Data Science ต้องการเข้าถึงฟีเจอร์ (Features) ที่คำนวณแล้วจากหลาย pipelines อย่างรวดเร็วและมี versioning ที่ชัดเจนสำหรับการ training และ serving models
โซลูชัน:
- ใช้ Delta Lake (ซึ่งใช้ Parquet เป็นฐาน) สร้าง Feature Store บน S3
- แต่ละ Feature Table ถูกจัดเก็บเป็น Delta Table โดยมี Schema ที่เข้มงวด
- การเขียนฟีเจอร์ใหม่จะเป็นการ Transaction ที่ปลอดภัย ไม่ทำให้ข้อมูลเก่าชำรุด
- ทีม ML สามารถใช้ Time Travel เพื่อ query ฟีเจอร์ย้อนหลังตาม timestamp ของโมเดลได้ (`SELECT * FROM feature_table TIMESTAMP AS OF ‘2026-01-15’`)
- การใช้ Parquet เป็นฐานทำให้การอ่านฟีเจอร์เฉพาะคอลัมน์ (บาง Features) สำหรับการทำ Batch Inference มีประสิทธิภาพสูง
Summary
Apache Parquet ได้พิสูจน์ตัวเองแล้วว่าเป็นเสาหลักของระบบข้อมูลยุคคลาวด์ ด้วยสถาปัตยกรรมคอลัมน์นาร์ที่ลดการใช้งาน I/O และทรัพยากรได้อย่างน่าทึ่ง การจะก้าวไปสู่การออกแบบที่แท้จริงแบบ Cloud Native นั้น ต้องให้ความสำคัญกับการจัดการไฟล์ให้มีขนาดเหมาะสม การออกแบบพาร์ติชันและ Schema ให้สอดคล้องกับรูปแบบการ query การเลือก Compression Codec อย่างชาญฉลาด และการจัดการ Metadata ที่มีประสิทธิภาพ ในปี 2026 แนวโน้มชัดเจนที่ Table Format อย่าง Delta Lake และ Apache Iceberg จะถูกนำมาใช้ร่วมกับ Parquet บ่อยขึ้น เพื่อเพิ่มขีดความสามารถด้าน Transaction และ Data Management ในระดับที่ซับซ้อนกว่าเดิม การเข้าใจหลักการพื้นฐานของ Parquet อย่างลึกซึ้งจึงเป็นกุญแจสำคัญที่จะทำให้คุณเลือกใช้หรือประยุกต์ใช้เครื่องมือชั้นสูงเหล่านี้ได้อย่างถูกต้องและมีประสิทธิภาพสูงสุด สุดท้ายนี้ ไม่มีสูตรสำเร็จเดียว ให้ทดลองวัดผล (Benchmark) ด้วยข้อมูลและรูปแบบการใช้งานจริงของคุณเสมอ เพราะการออกแบบที่ดีที่สุดคือการออกแบบที่ตอบโจทย์ workload ของคุณได้อย่างมีประสิทธิภาพและคุ้มค่าที่สุดบนคลาวด์