ข้ามไปยังเนื้อหา

การแลกเปลี่ยนด้าน Durability

ความทนทานของ AOF ขึ้นอยู่กับความถี่ที่ Redis flush AOF buffer ลงดิสก์ directive appendfsync ควบคุมสิ่งนี้ด้วยสามโหมด:

  • always: fsync หลังทุกคำสั่ง — ไม่สูญหายข้อมูล, throughput ต่ำที่สุด
  • everysec: fsync ทุกวินาที — สูญเสียข้อมูลได้มากที่สุด 1 วินาที, สมดุลที่ดี (แนะนำ)
  • no: OS ตัดสินใจเองว่าจะ flush เมื่อใด — throughput สูงที่สุด, การสูญหายของข้อมูลไม่แน่นอน
# ความทนทานสูงสุด — ทุก write ถูก fsync
appendfsync always
# สมดุล — สูญเสียข้อมูลได้มากที่สุด 1 วินาที (แนะนำ)
appendfsync everysec
# เร็วที่สุด — OS ควบคุมการ flush, สูญหายไม่แน่นอน
appendfsync no
โหมดข้อมูลสูญหายสูงสุดThroughput
always0 คำสั่งต่ำที่สุด
everysec~1 วินาทีดี
noตั้งแต่ OS flush ล่าสุดสูงที่สุด
RDB onlyตั้งแต่ snapshot ล่าสุดสูงที่สุด

การรัน replica ไม่ได้แทนที่ความจำเป็นของ persistence การรัน replica ที่ crash และ restart จะโหลดจากไฟล์ persistence ของตัวเอง (หรือ sync จาก primary) แนวทางที่ดีที่สุด: เปิดใช้ persistence บน replica อย่างอิสระ ไม่ใช่แค่บน primary เท่านั้น

127.0.0.1:6379> CONFIG GET appendfsync
1) "appendfsync"
2) "everysec"
127.0.0.1:6379> CONFIG SET appendfsync always
OK
127.0.0.1:6379> CONFIG GET appendfsync
1) "appendfsync"
2) "always"
CONFIG GET appendfsync
CONFIG SET appendfsync always
CONFIG GET appendfsync
ตัวเลือกBenefitCost
appendfsync alwaysไม่สูญหายข้อมูลแม้ crashfsync() ทุกคำสั่ง ทำให้ throughput ต่ำที่สุดในสามโหมด
appendfsync everysecสมดุลระหว่างความทนทานกับ throughput เหมาะกับ production ส่วนใหญ่สูญเสียข้อมูลได้สูงสุด ~1 วินาทีเมื่อ crash
appendfsync nothroughput สูงสุด ไม่มี overhead จาก fsyncOS ตัดสินใจเองว่าจะ 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 จะต่ำลง เพราะยอมรับการสูญหายข้อมูลแม้แต่คำสั่งเดียวไม่ได้

โหมด `appendfsync` ใดที่รับประกันว่าจะไม่มีการสูญหายของข้อมูลเมื่อเกิด crash?
โหมด `appendfsync` ใดที่แนะนำสำหรับการ deploy ใน production ส่วนใหญ่?
การสูญหายของข้อมูลสูงสุดเมื่อใช้ `appendfsync everysec` คือเท่าใด?
การรัน Redis replica แทนที่ความจำเป็นของ persistence บนแต่ละ node หรือไม่?