Big Data Analytics · บทที่ 3 จาก 13

Datacenter และการขยายขนาด

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

📚
เรียบเรียงจากเนื้อหาของ Jimmy Lin, Emanuele Della Valle และเอกสาร “แนวคิดของการมองศูนย์ข้อมูลทั้งหมดเป็นคอมพิวเตอร์หนึ่งเครื่อง” ของผู้สอน โดยปรับคำอธิบายให้แยกหลักการที่ยังใช้ได้ออกจากตัวเลขฮาร์ดแวร์ซึ่งเปลี่ยนตามเวลา

1The Datacenter is the Computer

ในคอมพิวเตอร์เครื่องเดียว โปรแกรมไม่จำเป็นต้องสั่งมอเตอร์ของดิสก์หรือเลือก transistor ที่ใช้คำนวณ Operating System, compiler และ hardware ช่วยสร้าง abstraction ให้เราใช้งานทรัพยากรซับซ้อนได้โดยไม่ควบคุมทุกชิ้นเอง

เมื่อขยายเป็นศูนย์ข้อมูล เราต้องการ abstraction แบบเดียวกันในระดับที่ใหญ่ขึ้น ผู้ใช้ส่ง job หรือ service เข้าไป แล้วระบบเลือกเครื่อง จัด CPU และ memory วางข้อมูล ตรวจสุขภาพ ย้ายงานเมื่อเครื่องเสีย และรวบรวมผลกลับมา

แนวคิดหลัก
มองศูนย์ข้อมูลเป็นคอมพิวเตอร์หนึ่งเครื่องที่ประกอบจากทรัพยากรจำนวนมากและล้มเหลวแยกกันได้ Framework สร้างภาพรวมให้ผู้พัฒนา แต่ไม่ได้ทำให้ network, race condition, lock หรือ failure หายไป มันเพียงรับผิดชอบบางส่วนและกำหนดแบบจำลองที่ผู้พัฒนาใช้ได้ง่ายขึ้น
เหมือนเมืองหนึ่งเมือง
เมืองไม่ได้เป็นเพียงบ้านจำนวนมาก อาคาร ถนน ไฟฟ้า น้ำประปา และระบบขนส่งต้องทำงานร่วมกัน คนในเมืองไม่ต้องสั่งการสถานีไฟฟ้าทุกครั้งที่เปิดไฟ แต่ข้อจำกัดของโครงสร้างพื้นฐานยังมีอยู่ ศูนย์ข้อมูลก็เช่นกัน Framework ช่วยซ่อนรายละเอียดจำนวนมาก แต่ถ้า network ส่วนกลางเต็ม งานทั้งเมืองก็ยังติดขัดได้
หลักการรายละเอียด
Resource Poolingรวม CPU, memory, storage และ accelerator จากหลายเครื่องให้ scheduler จัดสรรตามงาน
Scale Up และ Scale Outเลือกเพิ่มความสามารถเครื่องเดิมหรือเพิ่มจำนวนเครื่องตาม workload, cost และข้อจำกัด ไม่มีกฎว่าต้องใช้ทางเดียว
Failure-aware Designยอมรับว่า process, disk, switch หรือเครื่องบางส่วนล้มได้ แล้วออกแบบ retry, replication และ recovery ไว้ล่วงหน้า
Data Localityพยายามเริ่ม computation ใกล้ข้อมูล หรือทำให้ข้อมูลเล็กลงก่อนส่งผ่านเครือข่าย
Batch and Sequential Accessรวมงานและอ่านข้อมูลเป็นก้อน เพื่อใช้ bandwidth คุ้มและลด latency ซ้ำ ๆ
Observabilityวัด queue, utilization, tail latency, failure และ cost เพราะระบบใหญ่ไม่สามารถวิเคราะห์จากเครื่องเดียวได้

Instruction Set ของศูนย์ข้อมูลเป็นภาพเปรียบเทียบ

MapReduce ให้ผู้ใช้เขียน Map กับ Reduce แล้ว framework จัดการ partition, scheduling, Shuffle และ retry จึงเปรียบได้กับ instruction set ระดับศูนย์ข้อมูล แต่ MapReduce ไม่ใช่ตัวอย่างแรกของ distributed abstraction และไม่ใช่คำตอบสุดท้าย สิ่งสำคัญคือมันทำให้แนวคิดนี้แพร่หลายและแสดงให้เห็นว่าการจำกัดรูปแบบโปรแกรมช่วยให้ framework จัดการระบบแทนผู้ใช้ได้มากขึ้น

Spark เพิ่ม DAG และการเก็บผลใน memory Kubernetes จัด placement และ lifecycle ของ container ส่วน serverless ซ่อนการจัดสรร server มากขึ้น แต่ abstraction แต่ละแบบเลือกสิ่งที่จะรับประกันต่างกัน ผู้ใช้ยังต้องรู้ข้อจำกัด เช่น state อยู่ที่ไหน งานทำซ้ำได้หรือไม่ และค่าใช้จ่ายเกิดจากอะไร

ศูนย์ข้อมูลหนึ่งแห่งมีลำดับชั้นภายใน

เครื่องไม่ได้เชื่อมกันด้วยระยะทางเท่ากันทั้งหมด โดยทั่วไปมีระดับตั้งแต่ core และ socket ภายในเครื่อง ไปยังเครื่องใน rack เดียวกัน ข้าม rack และข้ามศูนย์ข้อมูล ต้นทุน latency, bandwidth และ failure domain เพิ่มตามขอบเขต

ขอบเขตทรัพยากรที่แชร์ตัวอย่างปัญหา
Core / SocketCache, memory channel และ interconnect ภายในเครื่องNUMA, cache contention, memory bandwidth
MachineRAM, local storage, NIC และ OSProcess crash, out-of-memory, disk failure
RackTop-of-rack switch และพลังงานบางส่วนOversubscription, switch failure, rack power loss
Datacenterเครือข่ายและบริการส่วนกลางNetwork partition, cooling หรือ facility incident
Regionระยะทางไกลและข้อกำกับข้อมูลHigh latency, egress cost, disaster recovery

การทำสำเนาสามชุดบนเครื่องสามตัวแต่ทั้งหมดอยู่ rack เดียว ช่วยทนเครื่องเสียแต่ไม่ทน rack เสีย Placement policy จึงต้องรู้ topology และ failure domain ไม่ใช่นับจำนวนสำเนาอย่างเดียว

Abstraction ที่ดีซ่อนรายละเอียด แต่ไม่ซ่อนต้นทุน

ผู้ใช้ Spark สามารถเรียก groupByKey ได้ในบรรทัดเดียว แต่คำสั่งนั้นอาจทำให้ข้อมูลจำนวนมหาศาล Shuffle ข้ามเครื่อง ความง่ายของ API ไม่ได้แปลว่าการทำงานข้างใต้ราคาถูก ผู้เรียนจึงต้องอ่านทั้ง abstraction และ physical behavior

สิ่งที่ Framework ทำแทนไม่ได้ทั้งหมด
Framework retry task ได้ แต่ไม่รู้ว่า operation ของเราทำซ้ำแล้วปลอดภัยหรือไม่ จัด partition ได้ แต่ไม่รู้ว่า key ใดร้อนผิดปกติ และ cache ได้ แต่ไม่รู้ว่าผลใดมีคุณค่าพอจะใช้ memory นักพัฒนายังต้องเข้าใจ semantics กับ workload ของตนเอง

2Seek vs. Scan: ทำไม Random Access ถึงเป็นศัตรูของ Big Data

คำว่า “ศัตรู” ในหัวข้อนี้ตั้งใจให้จำง่าย แต่ไม่ควรตีความว่า random access เป็นสิ่งผิด ฐานข้อมูล OLTP ต้องใช้ point lookup และ random update อยู่เสมอ ประเด็นคือเมื่อเราต้องแตะข้อมูลจำนวนมาก การจ่าย latency สำหรับแต่ละ record แยกกันแพงกว่าการอ่านเป็นก้อนอย่างต่อเนื่องมาก

ตัวอย่างตัวเลขจากเอกสารต้นฉบับ (Ted Dunning)
ฐานข้อมูลขนาด 1 TB ที่มี record ขนาด 100 ไบต์ ต้องอัปเดต 1% ของ record ทั้งหมด (~108 record)
วิธีการเวลาที่ใช้
Mutate ทีละ record (seek+read+write ~30ms/ครั้ง)~35 วัน
อ่าน 1 TB และเขียนผลใหม่ 1 TB แบบต่อเนื่องที่ 100 MB/s~5.6 ชั่วโมง
ตัวเลขนี้เป็นแบบจำลองเพื่อให้เห็นลำดับความต่าง ไม่ใช่ benchmark ของ storage ปัจจุบัน วิธีที่สองใช้เวลาประมาณ 2.8 ชั่วโมงต่อหนึ่งรอบ I/O และราว 5.6 ชั่วโมงเมื่อคิดทั้งอ่านกับเขียน ความต่างจาก random update ยังมากพอเปลี่ยนสถาปัตยกรรมได้โดยไม่เพิ่มเครื่องเลย

ทำไมการรวมงานชิ้นเล็กจึงช่วย

ทุก request มีต้นทุนตั้งต้น เช่น system call, network round trip, seek, metadata lookup และการตั้งค่าการส่งข้อมูล ถ้าทำงานทีละ record เราจ่ายต้นทุนเหล่านี้ซ้ำ การ batch ช่วยหารต้นทุนตั้งต้นด้วยข้อมูลหลายรายการ

รถรับส่งนักศึกษา
การส่งรถหนึ่งคันไปรับนักศึกษาทีละคนให้บริการได้ทันที แต่สิ้นเปลืองการเดินทาง หากรวมหลายคนขึ้นรถคันเดียว throughput สูงขึ้น แต่คนแรกต้องรอนานขึ้นเล็กน้อย Batch size จึงแลก latency กับ throughput ไม่ใช่ยิ่งใหญ่ยิ่งดีเสมอไป

Block Size เป็นการตัดสินใจหลายด้าน

Distributed file system ใช้ block ขนาดใหญ่กว่าระบบไฟล์ทั่วไป เพื่อลด metadata และให้ task หนึ่งทำงานต่อเนื่องนานพอคุ้มค่า scheduling แต่ block ใหญ่เกินไปลดจำนวน task ที่แบ่งได้และทำให้ worker บางตัวรับงานหนักกว่า ส่วน block เล็กเกินไปสร้าง metadata กับ scheduling overhead และไฟล์เล็กจำนวนมาก

ขนาด partition ใน Spark มี trade-off คล้ายกัน Partition เล็กมากทำให้ task overhead สูง Partition ใหญ่มากเสี่ยง memory pressure, spill และ straggler เป้าหมายคือให้แต่ละ task มีงานพอคุ้ม overhead แต่ยังเล็กพอกระจายสมดุลและ retry ได้ไม่แพง

Sequential Access กับ Columnar Access ทำงานร่วมกันได้

การอ่านต่อเนื่องทั้งแถวทุกคอลัมน์ยังสิ้นเปลือง หาก Query ใช้เพียงสองคอลัมน์จากหนึ่งร้อย Columnar format วางค่าชนิดเดียวกันไว้ด้วยกัน จึงอ่านเฉพาะคอลัมน์ที่ใช้ บีบอัดได้ดี และประมวลผลแบบ vectorized ได้

Predicate pushdown ช่วยข้าม row group ที่สถิติบอกว่าไม่มีค่าตรงเงื่อนไข Projection pruning ช่วยตัดคอลัมน์ที่ไม่ใช้ ทั้งสองแนวคิดทำให้ “scan” ไม่จำเป็นต้องแปลว่าอ่านทุก byte

Compression อาจทำให้เร็วขึ้น แม้ต้องใช้ CPU เพิ่ม

ถ้างานติด storage หรือ network bandwidth การบีบอัดลด byte ที่ต้องอ่านและส่ง แม้ต้องใช้ CPU ถอดรหัสเพิ่ม เวลารวมอาจลดลง Columnar data มักบีบอัดได้ดีเพราะค่าชนิดเดียวกันและค่าซ้ำอยู่ใกล้กัน

แต่ compression ที่หนักเกินไปอาจกลายเป็นคอขวด CPU จึงต้องวัดตาม workload และ codec ไม่ใช่ตั้งสมมุติฐานว่าบีบอัดเร็วหรือช้าเสมอ

Small Files Problem

ไฟล์ขนาดเล็กจำนวนมากทำให้ metadata โต เปิดไฟล์ซ้ำ และสร้าง task สั้นจำนวนมาก ต่อให้ขนาดข้อมูลรวมไม่ใหญ่ ระบบอาจช้าจาก overhead การ compact ไฟล์เป็นก้อนและจัด partition ตามรูปแบบ Query จึงช่วยได้มากกว่าการเพิ่ม worker

เมื่อใด Random Access ยังเหมาะสม

ถ้าต้องอ่านหนึ่ง record จากข้อมูลหลายพันล้าน record การสแกนทั้งหมดไม่สมเหตุสมผล Index, key-value store และ cache ช่วยให้ point lookup เร็ว งานบริการมักยอมจ่ายต้นทุนดูแล index เพื่อแลก latency ต่ำ ขณะที่ analytical workload ซึ่งแตะข้อมูลสัดส่วนมากมักเลือก scan

คำถามแนวทางที่มักเหมาะ
อ่านหนึ่ง keyHash index, B-tree, key-value lookup หรือ cache
อ่านช่วง keyOrdered index, range partition และ sequential scan ภายในช่วง
รวมทั้งคอลัมน์Columnar scan, vectorization และ partial aggregation
แก้ข้อมูลจำนวนมากBatch update, append version ใหม่ หรือ rewrite partition ตามระบบ

Storage Hierarchy: ใช้ตัวเลขเก่าเพื่อจำลำดับ ไม่ใช่จำสเปก

ตารางต่อไปเป็นตัวเลขเชิงประวัติศาสตร์ที่นิยมใช้อธิบาย “Latency Numbers Every Programmer Should Know” ฮาร์ดแวร์ปัจจุบันเปลี่ยนไปมาก แต่ลำดับความต่างยังให้บทเรียนสำคัญ: cache เร็วกว่าหน่วยความจำ หน่วยความจำเร็วกว่างาน I/O หลายชนิด และการสื่อสารไกลมี latency สูงกว่าการทำงานภายในเครื่อง

การดำเนินการเวลาโดยประมาณในตารางอ้างอิงดั้งเดิม
L1 cache reference0.5 ns
L2 cache reference7 ns
Main memory reference100 ns
Compress 1KB ด้วย Zippy10,000 ns
ส่งข้อมูล 2KB ผ่านเครือข่าย 1 Gbps20,000 ns
Round trip ภายใน datacenter เดียวกัน500,000 ns
Disk seek10,000,000 ns
อ่าน 1MB จากดิสก์แบบ sequential30,000,000 ns
ส่ง packet ข้ามทวีป (CA→เนเธอร์แลนด์→CA)150,000,000 ns
สิ่งที่ควรจำ
อย่าท่องว่า operation หนึ่งต้องใช้กี่ nanosecond เพราะ CPU, NVMe และเครือข่ายเปลี่ยนรุ่นตลอด ให้จำว่าการข้ามขอบเขตจาก cache ไป RAM ไป storage ไป network เพิ่มทั้ง latency และความแปรปรวน และควรวัดบนระบบจริงก่อนออกแบบจากตัวเลขในสไลด์เก่า
ลองคิดจาก Workload
Query หนึ่งอ่านข้อมูล 5% ของตารางทุกห้านาที ควรใช้ index เพื่อสุ่มอ่าน หรือจัด partition แล้ว scan เฉพาะส่วน? คำตอบขึ้นกับการกระจายของข้อมูล ขนาด row จำนวนคอลัมน์ ความถี่ Query และต้นทุนดูแล index ไม่ใช่เปอร์เซ็นต์เพียงตัวเดียว

3Compute-Intensive กับ Data-Intensive: คอขวดอยู่คนละตำแหน่ง

การแบ่งงานเป็น compute-intensive กับ data-intensive ไม่ได้แบ่งว่าระบบใด “ใช้ supercomputer ได้” หรือไม่ได้ แต่ช่วยถามว่าทรัพยากรใดกำหนดเวลารวม งานวิทยาศาสตร์บางชนิดใช้ arithmetic จำนวนมากต่อข้อมูลหนึ่ง byte จึงติด compute ส่วนงานสแกน log อาจคำนวณเพียงไม่กี่ operation ต่อ record แต่ต้องอ่านและส่งข้อมูลมหาศาล จึงติด I/O หรือ memory bandwidth

Operational Intensity
มองอย่างง่ายว่าเป็นจำนวนงานคำนวณต่อ byte ที่ต้องเคลื่อนย้าย ถ้าค่านี้สูง การเพิ่ม FLOPS อาจช่วยมาก ถ้าค่านี้ต่ำ ระบบอาจรอข้อมูลจนหน่วยคำนวณว่าง การเพิ่ม core โดยไม่เพิ่ม bandwidth จึงไม่ทำให้งานเร็วขึ้นตามสัดส่วน
ลักษณะงานตัวอย่างคอขวดที่เป็นไปได้
Compute-intensiveSimulation, matrix computation, model training บางชนิดCPU/GPU throughput, vectorization, accelerator utilization
Memory-intensiveHash aggregation, graph traversal, in-memory analyticsMemory bandwidth, cache miss, NUMA
Storage-intensiveFull-table scan, ETL, sort ข้อมูลใหญ่Read/write throughput, small files, spill
Network-intensiveShuffle, distributed Join, replicationNIC, switch oversubscription, serialization
Coordination-intensiveงานหลายรอบที่มี barrier หรือ metadata ส่วนกลางTail latency, straggler, coordinator

HPC กับ Big Data มีประวัติการออกแบบต่างกัน แต่กำลังเข้าใกล้กัน

ระบบ HPC เน้น interconnect ประสิทธิภาพสูง งานคำนวณขนาน และ parallel file system ส่วน Hadoop ยุคแรกเน้น commodity server, local disk, fault tolerance และ data locality การอธิบายว่า supercomputer ใช้กับ data-intensive workload ไม่ได้จึงไม่ถูกต้อง ระบบ HPC รองรับ I/O ขนาดใหญ่ได้ แต่รูปแบบ software และสมมุติฐานเรื่องงานต่างจาก Hadoop

ปัจจุบัน workload ผสมกันมากขึ้น AI training ต้องใช้ทั้ง compute และ network bandwidth งานวิทยาศาสตร์สร้างข้อมูลมหาศาล ส่วน data platform ใช้ accelerator มากขึ้น เส้นแบ่งจึงไม่ชัดเหมือนเดิม สิ่งที่ยังใช้ได้คือการระบุ bottleneck จากอัตราส่วน computation ต่อ data movement

นำ Computation ไปหา Data

ย้ายซองคำสั่ง ไม่ย้ายโกดัง
ถ้า data block มีขนาด 256 MB แต่ code กับ configuration มีขนาดไม่กี่ KB การส่ง task ไปยังเครื่องที่มี block ย่อมคุ้มกว่าขน block กลับมา เปรียบเหมือนส่งใบงานไปยังโกดัง แทนการขนสินค้าทั้งโกดังมาที่โต๊ะทำงาน

ใน HDFS scheduler พยายามวาง Map task แบบ node-local หากทำไม่ได้จึงเลือก rack-local หลักนี้ลด network traffic และกระจายการอ่านไปยัง local storage หลายเครื่องพร้อมกัน บทที่ 4 จะอธิบายว่า NameNode ช่วยบอกตำแหน่ง block และ execution framework เลือก task placement อย่างไร

แต่ Data Locality ไม่ได้มีรูปเดียวตลอดไป

เมื่อ storage แยกจาก compute เช่น object storage บน cloud เราไม่สามารถเริ่ม task บน “เครื่องที่มีดิสก์ก้อนนั้น” แบบ HDFS ได้เสมอไป ระบบจึงใช้วิธีอื่น เช่น cache ข้อมูลใกล้ compute, อ่านเฉพาะ column/row group, push filter ไปยัง storage, เพิ่ม bandwidth ระหว่างชั้น และจัดรูปไฟล์เพื่อลด byte ที่ต้องอ่าน

ดังนั้นหลักที่ลึกกว่า co-location คือ ลด data movement ที่ไม่สร้างคุณค่า บางยุควาง disk กับ compute ไว้เครื่องเดียว บางยุคแยกเพื่อให้ขยายอิสระ แต่พยายามลดการเดินทางด้วย caching และ pushdown

Arithmetic เร็วขึ้นไม่ได้ช่วยเมื่อรอข้อมูล

ถ้า worker ใช้ CPU เพียง 20% และเวลาส่วนใหญ่รอ Shuffle การเพิ่ม CPU เป็นสองเท่าแทบไม่ช่วย หาก worker ใช้ GPU ไม่เต็มเพราะ batch เล็ก การเพิ่ม GPU อาจลด utilization มากกว่าเดิม การวัดต้องดู resource utilization, queue และ throughput ของแต่ละชั้นร่วมกัน

คำถามก่อนเพิ่มเครื่อง
งานกำลังติดจำนวน operation, memory bandwidth, storage throughput, network หรือ barrier? ถ้ายังตอบไม่ได้ การเพิ่มทรัพยากรอาจเพียงย้ายคอขวดไปอีกจุด โดยจ่ายแพงขึ้นระหว่างทาง

4Horizontal vs. Vertical Scalability

การขยายระบบมีมากกว่าสองปุ่ม แต่ Scale Up กับ Scale Out เป็นจุดเริ่มต้นที่ดี Scale Up เพิ่มทรัพยากรให้หน่วยเดียว Scale Out เพิ่มหน่วยและแบ่งงานระหว่างกัน ระบบจริงมักใช้ทั้งคู่ เช่น เลือกเครื่องที่มี RAM พอเหมาะก่อน แล้วเพิ่มจำนวน worker เมื่อ workload โตต่อ

รูปแบบวิธีการข้อจำกัด
Vertical Scaling (Scale Up)เพิ่ม core, RAM, storage หรือ accelerator ในเครื่องเดิมมีเพดานฮาร์ดแวร์ ราคาอาจเพิ่มเร็วเมื่อเข้าเครื่องระดับสูง และยังมี failure domain ใหญ่จุดเดียว
Horizontal Scaling (Scale Out)เพิ่มเครื่องแล้ว partition หรือ replicate งานออกไปต้องจ่าย communication, coordination, skew, partial failure และ operational complexity
พื้นที่สีเทาที่เปลี่ยนตามเวลา
จุดที่ Scale Out เริ่มคุ้มกว่า Scale Up ไม่ใช่ค่าคงที่ เครื่องเดี่ยวเร็วและจุขึ้น ขณะที่บริการ cloud ทำให้เริ่ม cluster ได้ง่ายขึ้น Workload, latency, availability, ทีมดูแล และค่าใช้จ่ายจึงเป็นตัวกำหนดร่วมกัน ไม่ใช่ขนาดข้อมูลเพียงอย่างเดียว

ข้อดีของ Scale Up ที่มักถูกมองข้าม

เครื่องเดียวไม่มี network partition ภายใน process ใช้ shared memory ได้ และ transaction ข้ามข้อมูลหลายส่วนทำได้ง่ายกว่า การ debug, profiling และ deployment มักตรงไปตรงมากว่า หาก workload พอดีเครื่องเดียว การ Scale Up อาจเป็นการออกแบบที่ง่ายและคุ้มที่สุด

ข้อดีของ Scale Out ที่ไม่ได้มีเพียงกำลังรวม

Scale Out ช่วยแบ่ง failure domain เพิ่ม capacity ทีละส่วน และกระจายงานไปใกล้ผู้ใช้หรือข้อมูลได้ แต่ประโยชน์เหล่านี้เกิดเมื่อ software แบ่ง state และงานได้จริง การเพิ่มเครื่องให้โปรแกรมที่มี lock กลางหรือฐานข้อมูลไฟล์เดียวไม่ทำให้ระบบกระจายโดยอัตโนมัติ

Strong Scaling กับ Weak Scaling

Strong scaling คงขนาดงานเดิมแล้วเพิ่มทรัพยากร เพื่อดูว่าเวลาลดลงเท่าใด ส่วน Weak scaling เพิ่มขนาดงานตามจำนวนทรัพยากร เพื่อดูว่าระบบรักษาเวลาไว้ได้หรือไม่ ทั้งสองตอบคนละคำถาม

รายงานเดิมกับธุรกิจที่โตขึ้น
ถ้าต้องการให้รายงานข้อมูล 1 TB เสร็จเร็วขึ้น เรากำลังถาม strong scaling แต่ถ้าผู้ใช้และข้อมูลโตเป็นสองเท่าพร้อมเพิ่มเครื่องสองเท่า แล้วต้องการให้เวลาตอบเท่าเดิม เรากำลังถาม weak scaling

Scalability ไม่เท่ากับ Speed

ระบบ A อาจเร็วกว่า B ที่ workload ปัจจุบัน แต่พอข้อมูลโต B อาจเพิ่ม throughput ได้ดีกว่า Scalability จึงมองการเปลี่ยนแปลงเมื่อ workload กับทรัพยากรโต ไม่ใช่เวลา ณ จุดเดียว

ควรวัดหลายมิติ:

Amdahl ยังตามมาถึงศูนย์ข้อมูล

หากงานส่วนหนึ่งต้องผ่าน coordinator หรือทำเรียงลำดับ ต่อให้ส่วนอื่นกระจายได้ การเพิ่ม worker จะให้ผลลดลงเรื่อย ๆ ในระบบข้อมูล serial fraction อาจอยู่ใน metadata, commit, global sort, driver หรือ stage boundary

นอกจากนี้ overhead ของการกระจายไม่ได้คงที่เสมอ จำนวน worker มากขึ้นอาจเพิ่ม communication และ scheduling cost จึงเป็นไปได้ที่เพิ่มเครื่องแล้วงานช้าลง ไม่ใช่เพียงเร็วขึ้นน้อยลง

Stateless Scale ง่ายกว่า Stateful แต่ระบบจริงหลีก state ไม่ได้ทั้งหมด

Service แบบ stateless ส่ง request ไป instance ใดก็ได้ จึงเพิ่มหรือลด instance ง่าย ส่วน stateful service ต้องคิดว่า state อยู่ที่ไหน ทำสำเนาอย่างไร และย้าย partition เมื่อเพิ่มเครื่องอย่างไร

แนวทางทั่วไปคือแยก compute ที่ปรับจำนวนได้ง่ายออกจาก storage ที่รักษา state แต่การแยกนี้เพิ่ม network I/O และอาจลด locality อีกครั้ง ทุก abstraction จึงแลกปัญหาชุดหนึ่งกับอีกชุดหนึ่ง

5ความล้มเหลวในระดับศูนย์ข้อมูล: ยิ่งมีชิ้นส่วนมาก ยิ่งพบเหตุการณ์บ่อย

ถ้าเครื่องหนึ่งมีโอกาสล้มเหลวน้อย การมีเครื่องหลายพันตัวไม่ได้ทำให้แต่ละเครื่องแย่ลง แต่ทำให้โอกาสที่ “มีบางเครื่องกำลังมีปัญหา” สูงขึ้น ระบบจึงต้องทำงานต่อได้เมื่อบางส่วนหาย ช้า หรือสื่อสารกันไม่ได้

Failure Domain

ความล้มเหลวเกิดได้หลายขอบเขต ตั้งแต่ process, disk, machine, rack, datacenter จนถึง region การทำสำเนาควรกระจายข้ามขอบเขตที่ต้องการทน หากสำเนาทั้งหมดใช้ power supply หรือ switch เดียวกัน จำนวนสำเนาอาจดูมากแต่ป้องกันเหตุร่วมไม่ได้

Replication กับ Erasure Coding

Replication เก็บสำเนาเต็มหลายชุด อ่านและกู้คืนง่ายแต่ใช้พื้นที่มาก Erasure coding แยกข้อมูลพร้อม parity ให้กู้คืนจากบางส่วน ใช้พื้นที่คุ้มกว่าแต่การสร้างและซ่อมข้อมูลใช้ computation กับ network มากกว่า ระบบอาจใช้ replication กับข้อมูลร้อน และ erasure coding กับข้อมูลเย็น

Retry, Idempotency และ Duplicate Work

เมื่อ task timeout ระบบไม่รู้เสมอว่ามันยังทำอยู่ เสร็จแล้วแต่คำตอบหาย หรือหยุดจริง การ retry อาจสร้างงานซ้ำ Output commit และ idempotent operation จึงสำคัญ ไม่เช่นนั้น task สองสำเนาอาจเขียนผลซ้ำหรือขัดกัน

Straggler และ Speculative Execution

Stage เสร็จเมื่อ task สุดท้ายเสร็จ Worker ที่ช้าเพียงตัวเดียวจึงลาก tail latency ทั้งงาน Framework อาจเปิด task สำรองบนเครื่องอื่น แต่ถ้าความช้าเกิดจาก data skew ไม่ใช่เครื่องผิดปกติ สำเนาใหม่ก็ยังรับข้อมูลก้อนใหญ่เท่าเดิม การแก้ต้องเริ่มจาก partitioning

Recovery มีต้นทุนและใช้ bandwidth เดียวกับงานปกติ

เมื่อ disk เสีย ระบบต้องอ่านสำเนาและสร้างข้อมูลใหม่ การซ่อมแซมใช้ network กับ storage throughput ซึ่งอาจกระทบ Query ของผู้ใช้ Capacity planning จึงต้องเหลือทรัพยากรสำหรับ recovery ไม่ใช่ออกแบบให้ใช้งานปกติเต็ม 100%

ระบบที่ไม่มีพื้นที่หายใจเปราะบาง
Utilization สูงสุดดูคุ้มในรายงาน แต่เมื่อเกิด traffic spike, retry storm หรือ replica repair ระบบไม่มีทรัพยากรรับเหตุการณ์ผิดปกติ ประสิทธิภาพกับความทนทานจึงต้องออกแบบร่วมกัน

6Scheduling และ Placement: งานควรไปรันที่ไหน

Scheduler ต้องจับคู่ความต้องการของงานกับทรัพยากรที่กระจายอยู่ โดยพิจารณา CPU, memory, GPU, local data, topology, priority และงานอื่นที่กำลังแชร์เครื่อง ปัญหานี้คล้าย bin packing แต่มี dependency กับเวลาและ failure เพิ่มเข้ามา

Data-local, Rack-local และ Off-rack

ถ้ารัน task บนเครื่องที่มี block เรียกว่า data-local หากอยู่คนละเครื่องแต่ rack เดียวกันเป็น rack-local และถ้าข้าม rack ต้องใช้ bandwidth ส่วนกลางมากขึ้น Scheduler อาจยอมรอเครื่อง local ชั่วครู่ แต่ถ้ารอนานเกินไปก็เสีย CPU idle จึงต้องแลก locality กับเวลารอคิว

Resource Fragmentation

คลัสเตอร์อาจมี CPU และ memory รวมเหลือมาก แต่ไม่มีเครื่องใดเหลือทั้งสองอย่างพอสำหรับ task ใหญ่ เช่น บางเครื่องเหลือ CPU แต่ RAM เต็ม อีกเครื่อง RAM เหลือแต่ CPU เต็ม ทรัพยากรจึงแตกเป็นชิ้นที่ใช้ร่วมกันไม่ได้ การกำหนด task size มีผลต่อ utilization

Fairness, Priority และ SLA

ระบบหลายผู้ใช้ต้องตัดสินว่างาน batch ใหญ่ควรใช้คลัสเตอร์ได้แค่ไหนเมื่อมี Query เร่งด่วนเข้ามา Fair scheduling, queue และ preemption ช่วยแบ่งทรัพยากร แต่การหยุดงานอาจทิ้ง intermediate state และเสียงานที่ทำไปแล้ว

Autoscaling มองย้อนหลังเสมอ

Autoscaler เพิ่มเครื่องหลัง metric แสดงว่าโหลดสูง แต่การเปิดเครื่องและ warm cache ใช้เวลา หาก workload พุ่งเร็ว ระบบอาจช้าก่อน capacity ใหม่พร้อม การ scale down เร็วเกินไปก็ทำให้ cache หายและเกิดการย้าย state การปรับอัตโนมัติจึงต้องเข้าใจ delay กับ hysteresis

โจทย์ Placement
มี worker ว่างสองตัว ตัวแรกมีข้อมูล local แต่ CPU ใช้ 80% ตัวที่สอง CPU ว่างแต่ต้องอ่านข้อมูลข้าม rack ควรเลือกตัวใด? ไม่มีคำตอบตายตัว ต้องเทียบขนาดข้อมูล เวลา queue, network load และ deadline ของงาน

7ต้นทุน พลังงาน และการใช้ทรัพยากรให้คุ้ม

ระบบที่เร็วที่สุดอาจไม่ใช่ระบบที่คุ้มที่สุด การเพิ่มเครื่องลดเวลาได้แต่เพิ่มค่า compute, storage, network และการดูแล การวัดควรรวม cost ต่อผลลัพธ์ ไม่ใช่ดูเวลาจบอย่างเดียว

ต้นทุนที่มองเห็นกับต้นทุนที่ซ่อนอยู่

ต้นทุนตัวอย่าง
ComputeCPU/GPU hour, memory reservation และเวลาที่เครื่องว่างแต่ยังจ่าย
Storageข้อมูลดิบ สำเนา checkpoint intermediate result และ version เก่า
NetworkShuffle, replication, cross-zone และการนำข้อมูลออกจากผู้ให้บริการ
OperationsMonitoring, upgrade, incident response, security และเวลาของทีม
Opportunityผลวิเคราะห์ช้าเกินใช้ หรือระบบซับซ้อนจนเปลี่ยนแปลงได้ช้า

Performance per Watt และ Carbon Awareness

ศูนย์ข้อมูลใช้พลังงานทั้งกับ computation และ cooling งานที่อ่านข้อมูลซ้ำหรือใช้ GPU ไม่เต็มยังใช้พลังงานโดยไม่สร้างผลลัพธ์ การปรับ file layout, cache และ batch size จึงลดทั้งเวลา ค่าใช้จ่าย และพลังงานได้พร้อมกัน

งาน batch ที่ไม่เร่งด่วนอาจเลื่อนไปช่วงที่พลังงานสะอาดหรือ capacity ว่างมากกว่าได้ แต่ต้องรักษา deadline และข้อกำกับตำแหน่งข้อมูล การวางงานจึงเริ่มรวมมิติด้านพลังงานเข้ากับ performance

Utilization สูงไม่ใช่เป้าหมายเดียว

การใช้เครื่องใกล้ 100% ทำให้ cost ต่อทรัพยากรดูดี แต่ queue และ tail latency อาจเพิ่มมากเมื่อไม่มี headroom ระบบออนไลน์จึงต้องเหลือพื้นที่รับ burst และ failure ส่วน batch cluster อาจเน้น utilization สูงกว่าได้

ตัวชี้วัดที่ควรดูร่วมกัน
เวลาเสร็จ, throughput, p95/p99 latency, utilization, cost ต่อ Query, energy ต่อ job, error rate และ recovery time ไม่มีตัวเลขเดียวสรุปคุณภาพระบบได้ทั้งหมด

8เมื่อยุคเปลี่ยน: จุดตัดระหว่างเครื่องเดียวกับคลัสเตอร์ขยับอยู่เสมอ

แล้ว · commodity hardware ~2017
ตอนนี้ · 2025-2026
เซิร์ฟเวอร์ทั่วไป: CPU 8-32 core, RAM 16-64GB, ดิสก์ 1-3TB, เครือข่าย 10 Gigabit Ethernet
เครื่องเดี่ยวมี core, RAM และ NVMe มากขึ้นอย่างมาก และ accelerator กลายเป็นทรัพยากรสำคัญในหลาย workload ตัวเลขจริงแตกต่างตามรุ่นและงบประมาณ จึงควรวัดจากเครื่องเป้าหมายแทนการใช้สเปกตัวอย่างเป็นเกณฑ์ถาวร
Grey area ระหว่าง vertical/horizontal scaling อยู่ที่ระดับ 10TB-1PB ของข้อมูล (ประมาณการปี 2017)
Analytical engine บนเครื่องเดียวใช้ columnar execution, vectorization และ storage ที่เร็วขึ้น จึงรับงานที่เคยต้องกระจายได้มากกว่าเดิม แต่คำว่า “หลาย TB” ยังไม่พอบอกว่ารันเครื่องเดียวได้ ต้องดู Query, compression, memory, concurrency และเวลาที่ธุรกิจยอมรอ
Cluster ระดับ TOP500 วัดกันที่ FLOPS ล้วน ๆ
ศูนย์ข้อมูลต้องรองรับ workload ผสม ทั้ง SQL analytics, stream processing, AI training และบริการออนไลน์ จึงต้องดู memory, network, storage, accelerator, latency และพลังงานร่วมกับ FLOPS
Hadoop เน้น local disk และนำ computation ไปหา data
หลายระบบแยก storage ออกจาก compute ผ่าน object storage เพื่อขยายแต่ละส่วนอิสระ แล้วชดเชย locality ที่ลดลงด้วย cache, column pruning, predicate pushdown และเครือข่ายที่เร็วขึ้น
ข้อคิดสำคัญ
บทเรียนนี้ไม่ได้แปลว่า "Big Data หมดความสำคัญ" — มันแปลว่าเส้นแบ่งระหว่างปัญหาที่ต้องใช้ระบบกระจายกับปัญหาที่ใช้เครื่องเดียวได้ขยับไปเรื่อย ๆ วิศวกรที่ดีต้องประเมินใหม่เสมอว่าปัญหาตรงหน้าจำเป็นต้องกระจายจริงหรือไม่ ก่อนที่จะแบกความซับซ้อนของระบบกระจายมาโดยไม่จำเป็น

คำถามตัดสินใจ: เครื่องเดียว คลัสเตอร์ หรือบริการที่แยก Storage/Compute

คำถามถ้าคำตอบเป็นเช่นนี้แนวทางที่ควรพิจารณา
Working set พอดีเครื่องเดียวหรือไม่พอดีและ Query ไม่ชนกันมากเริ่มจากเครื่องเดียวเพื่อความง่าย แล้ววัดก่อนกระจาย
ต้องเพิ่ม capacity ทีละน้อยหรือไม่ข้อมูลและผู้ใช้โตต่อเนื่องเกินเพดานเครื่องScale Out พร้อมออกแบบ partition และ failure handling
Compute กับ storage โตพร้อมกันหรือไม่โตคนละจังหวะและ workload เปลี่ยนตามเวลาแยก storage/compute เพื่อปรับจำนวนอิสระ แต่ประเมิน network cost
ต้องตอบหลายผู้ใช้พร้อมกันหรือไม่Concurrency สูงและมี SLAแยก workload, queue, admission control และ capacity สำหรับ tail
ข้อมูลย้ายข้ามพื้นที่ได้หรือไม่ติดข้อกำกับหรือ egress costวาง computation ในพื้นที่เดียวกับข้อมูลและลดการเคลื่อนย้าย

9จะรู้ได้อย่างไรว่าระบบติดตรงไหน: วัดทั้งเส้นทาง ไม่ใช่ดูเครื่องเดียว

ในเครื่องเดียว เราอาจเปิด Task Manager หรือ profiler แล้วเห็นภาพส่วนใหญ่ แต่ในศูนย์ข้อมูลหนึ่ง Query ผ่านหลาย service, worker, switch และ storage การดู CPU เฉลี่ยของคลัสเตอร์จึงอาจซ่อนเครื่องที่ร้อนจัดหรือ task ที่ช้าผิดปกติไว้

Metrics, Logs และ Traces ตอบคนละคำถาม

ข้อมูลสังเกตการณ์ตอบคำถามตัวอย่าง
Metricsระบบมีแนวโน้มอย่างไร และค่าใดเกินขอบเขตCPU, memory, queue length, throughput, p99 latency
Logsเหตุการณ์เฉพาะเกิดอะไรขึ้น พร้อมรายละเอียดบริบทTask failed, out-of-memory, retry, permission denied
TracesRequest หนึ่งเดินผ่านส่วนใดและใช้เวลาตรงไหนอ่าน metadata → scan → Shuffle → aggregate → response
Profilesภายใน process ใช้ CPU หรือ memory กับ function ใดSerialization, hashing, compression, garbage collection

Metric ชี้ว่าปัญหาเกิดเมื่อใด Trace ชี้เส้นทางที่ช้า Log ให้รายละเอียดเหตุการณ์ และ profile ชี้ function ภายใน ไม่มีชนิดใดแทนอีกชนิดได้ทั้งหมด

ค่าเฉลี่ยซ่อน Tail

ถ้า task 99 ตัวเสร็จในหนึ่งวินาที แต่อีกตัวใช้หนึ่งนาที ค่าเฉลี่ยอาจยังดูไม่ร้าย แต่ stage ต้องรอหนึ่งนาที Percentile เช่น p95, p99 และค่าสูงสุดช่วยเห็นหางของ distribution ซึ่งมีผลโดยตรงต่อ distributed job

ร้านอาหารที่คิดจากเวลาเฉลี่ย
ลูกค้าส่วนใหญ่ได้อาหารในสิบนาที แต่โต๊ะหนึ่งรอหนึ่งชั่วโมง ค่าเฉลี่ยอาจยังสวยเพราะมีลูกค้าจำนวนมาก แต่สำหรับโต๊ะนั้นบริการล้มเหลว ระบบกระจายก็เช่นกัน ผู้ใช้หรือ task ที่อยู่ปลายหางไม่หายไปเพราะค่าเฉลี่ยดี

Utilization ต่ำไม่ได้แปลว่าไม่มีคอขวด

CPU เฉลี่ย 30% อาจเกิดจากทุกเครื่องว่าง หรือเกิดจากครึ่งหนึ่งเต็ม 100% แต่อีกครึ่งไม่มีข้อมูลทำ ข้อมูลเฉลี่ยระดับคลัสเตอร์จึงต้องดูคู่กับ distribution ต่อ worker และ partition

อีกกรณีคือ CPU ต่ำเพราะกำลังรอ storage หรือ network หากเพิ่ม CPU ระบบไม่เร็วขึ้น ควรดู I/O wait, throughput, queue และเวลาที่ task อยู่แต่ละสถานะ

Skew มองเห็นได้จากขนาด Partition และเวลาของ Task

หาก task ส่วนใหญ่ประมวลผล 100 MB แต่บางตัวรับ 20 GB ปัญหาอยู่ที่การแบ่งข้อมูล ไม่ใช่ประสิทธิภาพเครื่อง การเพิ่ม worker ไม่สามารถแบ่ง partition ที่สร้างไปแล้วโดยอัตโนมัติเสมอ ต้องแก้ key, salting, repartition หรือใช้ adaptive execution ตามความสามารถของ engine

Queue บอกความสัมพันธ์ระหว่าง Arrival Rate กับ Service Rate

ถ้างานเข้ามาเร็วกว่าระบบทำเสร็จ Queue จะโตต่อเนื่อง แม้แต่ละ request ยังตอบได้ ระบบกำลังสะสมหนี้เวลา การเพิ่ม capacity, ลดงานต่อ request หรือทำ backpressure ต้องเกิดก่อน queue ใช้ memory หมดหรือ latency เกิน SLA

วัดก่อนและหลังด้วย Workload เดียวกัน

การเปรียบเทียบต้องควบคุมขนาดข้อมูล รูปแบบ Query, cache state, concurrency และ failure condition หากรอบใหม่เร็วขึ้นเพราะข้อมูลอยู่ใน cache แต่รอบเก่าเป็น cold start เราไม่ควรสรุปว่า architecture ใหม่เร็วกว่าโดยไม่แยกสาเหตุ

แบบฝึกวินิจฉัย
Job ช้าลงสองเท่า CPU เฉลี่ยลดจาก 70% เหลือ 35% Network เต็ม และ task บางตัว spill ลง disk ข้อมูลชุดนี้ชี้ว่าการเพิ่ม CPU ไม่น่าช่วย ควรตรวจ partition size, Shuffle volume, serialization และ memory pressure ก่อน

10สรุปบทและขั้นตอนถัดไป

การมองศูนย์ข้อมูลเป็นคอมพิวเตอร์หนึ่งเครื่องช่วยให้เราออกแบบ abstraction ที่จัดการทรัพยากรจำนวนมากได้ แต่ “หนึ่งเครื่อง” ในที่นี้มีลักษณะพิเศษ:

แนวคิดสำคัญของบทนี้จึงไม่ใช่ “Scale Out ดีกว่า Scale Up” แต่คือเลือกขอบเขตที่เหมาะกับ workload เครื่องเดียวให้ความง่ายและ shared memory คลัสเตอร์ให้ capacity กับ failure isolation ส่วนการแยก storage ออกจาก compute ให้ความยืดหยุ่นแต่เพิ่ม data movement

ก่อนออกแบบระบบ ควรตอบให้ได้ว่า:

  1. งานติด compute, memory, storage, network หรือ coordination
  2. ข้อมูลอยู่ตรงไหน และลด byte ก่อนส่งได้หรือไม่
  3. partition กระจายงานสมดุลหรือมี hotspot
  4. ต้องทน failure ขอบเขตใด และ recovery ใช้ทรัพยากรเท่าใด
  5. เพิ่มเครื่องแล้ว throughput, latency และ cost เปลี่ยนอย่างไร
สะพานไปบทที่ 4
บทนี้มองศูนย์ข้อมูลจากภาพรวม บทถัดไปจะเปิดดูเครื่องยนต์ของ GFS/HDFS และ MapReduce ว่าระบบรู้ตำแหน่ง block อย่างไร ส่ง Map task ไปหา data อย่างไร ทำสำเนาเพื่อรับ failure อย่างไร และเหตุใด Shuffle จึงเป็นจุดที่ข้อมูลต้องเดินทางอีกครั้ง
ขั้นตอนถัดไป

เลือกงานวิเคราะห์หนึ่งงานแล้ววาดสามตำแหน่ง: ข้อมูลอยู่ที่ไหน computation เริ่มที่ไหน และผลย่อยถูกรวมตรงไหน จากนั้นวงเส้นทางที่ข้อมูลต้องข้ามเครื่อง แผนภาพนี้จะช่วยให้บท HDFS และ MapReduce ไม่กลายเป็นการจำชื่อ component แต่เป็นคำตอบต่อปัญหา placement กับ data movement ที่เห็นอยู่แล้ว

คำถามทบทวนความเข้าใจ
  1. อธิบายแนวคิด “The Datacenter is the Computer” พร้อมระบุสิ่งที่ abstraction ซ่อนได้และสิ่งที่ผู้พัฒนายังต้องรับผิดชอบ
  2. จากตัวอย่างฐานข้อมูล 1 TB อธิบายสมมุติฐานของเวลาประมาณ 35 วันกับ 5.6 ชั่วโมง และเหตุใดจึงไม่ควรนำตัวเลขไปใช้เป็น benchmark ปัจจุบันตรง ๆ
  3. เปรียบเทียบ latency กับ bandwidth และอธิบายว่า batch size แลก throughput กับเวลารออย่างไร
  4. อธิบายความต่างระหว่าง compute-, memory-, storage-, network- และ coordination-intensive workload
  5. เปรียบเทียบ Scale Up กับ Scale Out โดยยกข้อดีที่อีกฝ่ายไม่มีอย่างน้อยด้านละสองข้อ
  6. อธิบาย Strong Scaling กับ Weak Scaling พร้อมออกแบบการทดลองอย่างละหนึ่งแบบ
  7. อธิบายเหตุผลที่ replica สามชุดใน rack เดียวไม่ได้ป้องกัน rack failure
  8. วิเคราะห์ว่าเหตุใดการแยก storage ออกจาก compute ลด locality แต่ยังได้รับความนิยมในบางสถาปัตยกรรม
  9. เลือก workload หนึ่งงานแล้วเสนอ metric ด้าน performance, reliability และ cost ที่ควรวัดร่วมกัน