การแลกเปลี่ยนด้าน Durability
การตั้งค่า appendfsync
หัวข้อที่มีชื่อว่า “การตั้งค่า appendfsync”ความทนทานของ AOF ขึ้นอยู่กับความถี่ที่ Redis flush AOF buffer ลงดิสก์ directive appendfsync ควบคุมสิ่งนี้ด้วยสามโหมด:
always: fsync หลังทุกคำสั่ง — ไม่สูญหายข้อมูล, throughput ต่ำที่สุดeverysec: fsync ทุกวินาที — สูญเสียข้อมูลได้มากที่สุด 1 วินาที, สมดุลที่ดี (แนะนำ)no: OS ตัดสินใจเองว่าจะ flush เมื่อใด — throughput สูงที่สุด, การสูญหายของข้อมูลไม่แน่นอน
# ความทนทานสูงสุด — ทุก write ถูก fsyncappendfsync always
# สมดุล — สูญเสียข้อมูลได้มากที่สุด 1 วินาที (แนะนำ)appendfsync everysec
# เร็วที่สุด — OS ควบคุมการ flush, สูญหายไม่แน่นอนappendfsync noสิ่งที่อาจสูญหายเมื่อเกิด crash
หัวข้อที่มีชื่อว่า “สิ่งที่อาจสูญหายเมื่อเกิด crash”| โหมด | ข้อมูลสูญหายสูงสุด | Throughput |
|---|---|---|
always | 0 คำสั่ง | ต่ำที่สุด |
everysec | ~1 วินาที | ดี |
no | ตั้งแต่ OS flush ล่าสุด | สูงที่สุด |
| RDB only | ตั้งแต่ snapshot ล่าสุด | สูงที่สุด |
การรวม persistence กับ replication
หัวข้อที่มีชื่อว่า “การรวม persistence กับ replication”การรัน replica ไม่ได้แทนที่ความจำเป็นของ persistence การรัน replica ที่ crash และ restart จะโหลดจากไฟล์ persistence ของตัวเอง (หรือ sync จาก primary) แนวทางที่ดีที่สุด: เปิดใช้ persistence บน replica อย่างอิสระ ไม่ใช่แค่บน primary เท่านั้น
127.0.0.1:6379> CONFIG GET appendfsync1) "appendfsync"2) "everysec"127.0.0.1:6379> CONFIG SET appendfsync alwaysOK127.0.0.1:6379> CONFIG GET appendfsync1) "appendfsync"2) "always"CONFIG GET appendfsync
CONFIG SET appendfsync always
CONFIG GET appendfsyncข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
appendfsync always | ไม่สูญหายข้อมูลแม้ crash | fsync() ทุกคำสั่ง ทำให้ throughput ต่ำที่สุดในสามโหมด |
appendfsync everysec | สมดุลระหว่างความทนทานกับ throughput เหมาะกับ production ส่วนใหญ่ | สูญเสียข้อมูลได้สูงสุด ~1 วินาทีเมื่อ crash |
appendfsync no | throughput สูงสุด ไม่มี overhead จาก fsync | OS ตัดสินใจเองว่าจะ flush เมื่อใด ข้อมูลสูญหายได้ไม่แน่นอนหากดิสก์ยังไม่ flush |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- คิดว่า replica ทดแทนความจำเป็นของ persistence ได้ — replica ที่ crash และ restart ก็ต้องโหลดจากไฟล์ persistence ของตัวเอง (หรือ sync ใหม่จาก primary) ควรเปิด persistence บน replica แยกต่างหาก ไม่ใช่พึ่งพา primary เพียงอย่างเดียว
- ใช้
appendfsync noในระบบที่ทนการสูญหายข้อมูลไม่ได้ — โหมดนี้ให้ throughput สูงสุดแต่ปล่อยให้ OS ตัดสินใจเวลา flush เอง หาก crash ก่อน OS flush ข้อมูลตั้งแต่ flush ล่าสุดจะหายทั้งหมด - ไม่ทดสอบ recovery หลัง crash จริง — การตั้งค่า
appendfsyncที่ถูกต้องไม่มีประโยชน์ถ้าไม่เคยลองทำkill -9แล้วดูว่า Redis restart และโหลดข้อมูลกลับมาได้ตามที่คาดไว้จริงหรือไม่
💡 ตัวอย่างจากของจริง
GitHub — ใช้
appendfsync everysecเป็นค่ามาตรฐานสำหรับ Redis instance ที่เก็บข้อมูลสำคัญ เพื่อรักษาสมดุลระหว่าง durability กับ write throughput บน workload ที่มีการเขียนหนักFinancial-grade queue systems — ระบบที่เกี่ยวกับธุรกรรมทางการเงินมักเลือก
appendfsync alwaysแม้ throughput จะต่ำลง เพราะยอมรับการสูญหายข้อมูลแม้แต่คำสั่งเดียวไม่ได้