การรัน MongoDB ใน production
mongod ตัวเดียวที่รันบนเครื่องแล็ปท็อปของคุณนั้นยอดเยี่ยมสำหรับการเรียนรู้ แต่เป็นสิ่งที่ผิดที่สุดที่จะเอาไปวางไว้หน้าผู้ใช้จริง ทันทีที่ฐานข้อมูลเก็บข้อมูลที่ผู้คนพึ่งพา จะมีคำถามสี่ข้อตามมาที่ server เดี่ยวตอบได้ไม่ดีนัก จะเกิดอะไรขึ้นเมื่อเครื่องนั้นเครื่องเดียวพัง? จะเกิดอะไรขึ้นเมื่อเครื่องเดียวไม่สามารถเก็บข้อมูลทั้งหมดหรือรับ traffic ทั้งหมดได้อีกต่อไป? ทำไม query ที่เคยตอบทันทีเมื่อสัปดาห์ที่แล้วตอนนี้กลับใช้เวลาสองวินาที? และใครกันแน่ที่ได้รับอนุญาตให้อ่านข้อมูลนี้ และผ่านการเชื่อมต่อแบบไหน?
โมดูลนี้พูดถึงคำถามทั้งสี่ข้อนี้ และ MongoDB มีคำตอบที่ชัดเจนสำหรับแต่ละข้อ High availability มาจาก replica set — ข้อมูลของคุณหลายชุดที่เลือกผู้นำคนใหม่โดยอัตโนมัติเมื่อชุดหนึ่งล้มเหลว การ scale ในแนวนอน มาจาก sharding — การแบ่ง collection เชิงตรรกะหนึ่งอันออกไปยังหลายเครื่อง เพื่อให้ทั้งชุดข้อมูลและภาระงานถูกแบ่งกัน Performance มาจากการเข้าใจว่าเวลาหายไปไหน: การ profile query ที่ช้า, การเก็บ working set ไว้ในหน่วยความจำ, และการเลือกใช้ index ที่เหมาะสม Security มาจากการเปิดการป้องกันที่ปิดอยู่โดยค่าเริ่มต้น: authentication, การเข้ารหัสระหว่างการส่ง, และเครือข่ายที่ไม่เปิดให้ฐานข้อมูลถูกเข้าถึงจากอินเทอร์เน็ตสาธารณะ
รูปร่างของ deployment ใน production
หัวข้อที่มีชื่อว่า “รูปร่างของ deployment ใน production”แนวคิดเชิงโครงสร้างสองอย่าง — replication และ sharding — ซ้อนกันอยู่ replica set ให้ความทนทานแก่ข้อมูลหนึ่งชุด ส่วน sharded cluster คือ replica set หลายชุด แต่ละชุดถือ ส่วนหนึ่ง ของข้อมูล โดยมี router อยู่ด้านหน้าที่รู้ว่าส่วนไหนอยู่ที่ไหน:
flowchart TB
App["Application"] --> Router["mongos router"]
Router --> CSRS["Config servers (replica set)"]
Router --> ShardA
Router --> ShardB
subgraph ShardA["Shard A — replica set"]
PA["Primary"] --> S1A["Secondary"]
PA --> S2A["Secondary"]
end
subgraph ShardB["Shard B — replica set"]
PB["Primary"] --> S1B["Secondary"]
PB --> S2B["Secondary"]
end อ่านไดอะแกรมนั้นจากล่างขึ้นบน แต่ละกล่องที่แรเงาคือ replica set หนึ่งชุด: primary หนึ่งตัวบวก secondaries ที่ถือข้อมูลชุดเดียวกัน เพื่อให้ node เดียวที่ล้มเหลวไม่ทำให้ข้อมูลสูญหาย วางสองชุดนั้นเคียงข้างกัน ให้แต่ละชุดถือ collection คนละส่วน แล้วเอา mongos router มาวางด้านหน้าเพื่อนำทุก request ไปยังส่วนที่ถูกต้อง — นั่นคือ sharded cluster คุณไม่จำเป็นต้องเริ่มด้วยการ shard; deployment ส่วนใหญ่อยู่อย่างมีความสุขเป็น replica set เดี่ยวได้เป็นเวลานาน และจะ shard ก็ต่อเมื่อเครื่องเดียวตามไม่ทันจริง ๆ เท่านั้น
โมดูลนี้ครอบคลุมอะไรบ้าง
หัวข้อที่มีชื่อว่า “โมดูลนี้ครอบคลุมอะไรบ้าง”บทเรียนเรียงตามลำดับเดียวกับคำถามทั้งสี่ข้อ:
- การรัน MongoDB ใน production — ภาพรวมเรื่อง availability, scale, performance และ security นี้
- Replica sets — primaries, secondaries, oplog ที่คอยทำให้ทุกตัวซิงค์กัน และ election อัตโนมัติที่เลือก primary ใหม่เมื่อตัวหนึ่งล้มเหลว
- Sharding — การแบ่ง collection ตาม shard key ข้าม shards, บทบาทของ balancer และ config servers, และวิธีเลือก shard key ที่คุณจะไม่ต้องเสียใจภายหลัง
- Performance และ profiling — การหา query ที่ช้าด้วย database profiler, การอ่าน
explainซ้ำ, และวิธีแก้ไขทั่วไปที่ทำให้ query กลับมาเร็วอีกครั้ง - Security และ Atlas — authentication และ roles, TLS, การล็อกเครือข่าย, encryption at rest, และวิธีที่ MongoDB Atlas มอบทั้งหมดนี้ให้คุณในรูปแบบ managed service
เคล็ดลับและข้อควรระวัง
หัวข้อที่มีชื่อว่า “เคล็ดลับและข้อควรระวัง”- ฟีเจอร์เหล่านี้ประกอบกันมากกว่าจะแข่งกัน คุณมักจะรัน replica set ก่อนเสมอเพื่อ availability และจะเพิ่ม sharding ภายหลังก็ต่อเมื่อ scale บังคับเท่านั้น ส่วน security ใช้กับทั้งสองอย่างตั้งแต่วันแรก
- Sharding ไม่ใช่พลาสเตอร์ปิดแผลสำหรับ performance ของ query ที่ช้า การขาด index ก็เจ็บปวดพอ ๆ กันไม่ว่าจะมีสิบ shard หรือมีเครื่องเดียว แก้ performance ก่อน แล้วค่อย scale ทีหลัง
- ความผิดพลาดใน production ที่พบบ่อยที่สุดเป็นสิ่งที่หลีกเลี่ยงได้ง่ายที่สุด: การปล่อยฐานข้อมูลให้เข้าถึงได้บนอินเทอร์เน็ตโดยปิด authentication ไว้ บทเรียนเรื่อง security มีอยู่ก็เพื่อให้คุณไม่ทำเช่นนั้น
ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
mongod เดี่ยว | ตั้งค่าง่ายที่สุด ต้นทุนต่ำสุด | ไม่มี high availability เครื่องเดียวคือ single point of failure |
| Replica set | Automatic failover, กระจาย read ไปยัง secondaries ได้ | Write ยังไปที่ primary เดียวเสมอ, ต้องดูแล infrastructure เพิ่มขึ้น |
| Sharded cluster | Scale ทั้ง write และ storage ในแนวนอน | Operational complexity สูงขึ้นมาก, shard key ที่เลือกผิดแก้ทีหลังยาก |
| Self-managed | ควบคุม infrastructure ได้เต็มที่ | ต้องรับผิดชอบ patch, backup และ security เองทั้งหมด |
| MongoDB Atlas | ลดภาระงาน ops, ปลอดภัยโดยค่าเริ่มต้น | ควบคุมรายละเอียดระดับ low-level ได้น้อยกว่า, ต้นทุนคิดตาม usage |
บทเรียนวัดอะไรไว้บ้าง
หัวข้อที่มีชื่อว่า “บทเรียนวัดอะไรไว้บ้าง”ทุกตัวเลขในนี้จับจากเครื่อง Mac นี้ด้วย mongo 8.3.11, mongosh 2.11.1 และ Node driver 7.7.0 บน Docker container ชั่วคราว (แต่ละตัวจำกัด 512 MB) ที่ลบทิ้งหลังใช้งาน
- Replica set — primary ที่ล่มทำให้การเขียนหนึ่งครั้งค้างราว 10.8 วินาที (เอกสารบอกว่าค่ามัธยฐานของ election “should not typically exceed 12 seconds”); ตัวที่หยุดอย่างสะอาดค้าง 0.3 วินาที; เมื่อสองในสามสมาชิกหายไป ตัวที่รอดปฏิเสธการเขียน
- Sharding — shard key แบบ timestamp ทำให้ 100 000 จาก 100 000 document อยู่บน shard เดียว ส่วน key แบบ hashed แบ่ง 48 900 / 51 100; ไม่ต้องใช้
enableSharding - Performance — profile entry ที่เป็น
COLLSCANตรวจ 49 999 document เพื่อคืน 5 000; client ต่อ request ทำให้ connection ใหม่เพิ่มขึ้นมาก - Security — container เริ่มต้นรับ insert โดยไม่ต้องมี credential;
Command find requires authentication; การไม่ใส่authSourceล้มด้วย code 18
Mental Model
หัวข้อที่มีชื่อว่า “Mental Model”สี่คำถามอิสระ สี่กลไกอิสระ: สำเนาและเสียงโหวต (availability), ช่วงของ key (scale), ตัวนับ (performance), ประตู (security) ไม่มีอันไหนแทนอันอื่นได้ — replica set ไม่ scale การเขียน, sharding ไม่แก้ index ที่ขาด, TLS ไม่แทน authentication
Common Misconceptions
หัวข้อที่มีชื่อว่า “Common Misconceptions”- “shard ตั้งแต่วันแรกเพราะข้อมูลจะโต” — replica set เดียวรับได้มาก; sharding เพิ่มสี่โปรเซสแม้ใน lab ที่เล็กที่สุด และการตัดสินใจเรื่อง key ถาวร (เปลี่ยนได้ แต่ resharding ใช้อย่างน้อยห้านาที)
- “security เป็นงานครั้งเดียว” — certificate หมดอายุ (CA ใน lab ตั้งให้อายุ 2 วันโดยตั้งใจ), user และ role ค่อย ๆ เปลี่ยน
- “HA ที่ไม่เคย failover คือ HA” — ซ้อมมัน: การล่มกับการหยุดอย่างสะอาดทำให้การเขียนหยุด 10.8 วินาทีเทียบกับ 0.3 วินาทีใน lab