한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

คู่มือเกมแลค › L12 ฐานข้อมูล

คำสั่ง Redis ที่ช้า Redis blocking commands (single-threaded)

ID สาเหตุ db-redis-block · ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟรา DB (ทีมอินฟรา)

เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →

Redis ประมวลผลคำสั่งทีละคำสั่ง คำสั่งที่ช้าเพียงคำสั่งเดียวจึงขวางทุกคำขอที่ตามมา

ทำไม ใช้ KEYS ค้นทั้งหมดระหว่างให้บริการ, อ่านหรือลบอันดับหรือลิสต์ที่มีสมาชิกหลายล้านตัวทั้งก้อน → ผลคือ คำขออื่นทั้งหมดต้องรอจนคำสั่งนั้นเสร็จ (หลายสิบ ms ถึงหลายวินาที) → บนหน้าจอ ฟีเจอร์ที่ใช้เซสชัน อันดับ และแคชหยุดแวบพร้อมกัน, ล็อกอินช้า

อาการ
ค้าง, อินพุตดีเลย์, เข้าเกมไม่ได้/โหลดไม่จบ
ปัจจัย
การหยุดชะงัก, ความหน่วง
ใครเจอ
ทั้งเซิร์ฟเวอร์, เฉพาะบางฟีเจอร์
เกิดเมื่อไร
สุ่มเป็นครั้งคราว, เป็นรอบสม่ำเสมอ
ผู้รับผิดชอบ
ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟรา DB (ทีมอินฟรา)
งานฝั่งทีมพัฒนาเกม
ใช้ SCAN แทน KEYS, แบ่งคีย์ใหญ่, ลบด้วย UNLINK (ลบเบื้องหลัง), กระจายเวลาหมดอายุที่กระจุกอยู่ในวินาทีเดียวกัน
งานฝั่งทีมอินฟรา
เฝ้าดูบันทึกคำสั่งช้า (SLOWLOG), บล็อกคำสั่งอันตรายอย่าง KEYS บนเซิร์ฟเวอร์ที่ให้บริการจริง, ตรวจคีย์ใหญ่เป็นประจำ, ปิด THP และกันหน่วยความจำไว้พอสำหรับ fork, ทำการบันทึก RDB และ AOF บน replica
ตัวเลขที่ควรรู้
คำสั่งทั่วไปใช้ไม่ถึง 1 ms ถ้าจัดการสมาชิกหลายล้านตัวในครั้งเดียว อาจใช้ตั้งแต่หลายร้อย ms ไปจนถึงหลายวินาที
บนกราฟ
พุ่งแบบสุ่มเป็นครั้งคราว · ดีเลย์การตอบของ Redis, จำนวนคำสั่งที่ช้า
จุดที่ต้องดู
ดูคำสั่งที่เกิน slowlog-log-slower-than ด้วย SLOWLOG GET และเปิด latency monitor (ค่าเริ่มต้นปิด) ด้วย CONFIG SET latency-monitor-threshold แล้วดูดีเลย์แยกตามอีเวนต์ เช่น fork และ expire-cycle ด้วย LATENCY LATEST และ LATENCY DOCTOR ตรวจเวลา fork และคีย์ใหญ่ด้วย latest_fork_usec ใน INFO และ redis-cli --bigkeys
สัญญาณว่าใช่
ช่วงที่หยุด SLOWLOG มีคำสั่ง KEYS หรือคำสั่งที่จัดการคีย์ใหญ่ทั้งก้อน หรือ LATENCY บันทึกอีเวนต์ fork หรือ expire-cycle ในช่วงเดียวกันนานตั้งแต่หลายสิบ ms ขึ้นไป
สัญญาณว่าไม่ใช่
SLOWLOG และ LATENCY ว่างแต่ช้าเฉพาะฝั่งเซิร์ฟเวอร์เกม: น่าจะเป็นเครือข่ายหรือการรอภายในเซิร์ฟเวอร์เกม (SLOWLOG วัดแค่เวลารันคำสั่ง ไม่รวมเวลารับส่งกับไคลเอนต์)
วิธีตรวจ
ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)
รายละเอียดเพิ่มเติม
ตอน fork โปรเซสเพื่อสร้างไฟล์บันทึก (RDB snapshot) หรือเขียน AOF ใหม่ ก็หยุดเช่นกัน บนเซิร์ฟเวอร์ปัจจุบันใช้ราว 10 ms ต่อหน่วยความจำ 1 GB ถ้า 30 GB ก็ประมาณ 300 ms ถ้าเปิด huge page (THP) ไว้ หลัง fork การเขียนแต่ละครั้งจะคัดลอก huge page ทั้งหน้า (copy-on-write) ทำให้ทั้งเวลาหยุดและการใช้หน่วยความจำเพิ่มขึ้นมาก จึงมักปิด THP และกันหน่วยความจำเหลือไว้มาก ๆ ตอนที่คีย์จำนวนมากหมดอายุในวินาทีเดียวกัน Redis ก็หยุดแวบเพราะต้องลบคีย์เหล่านั้น

แหล่งอ้างอิง

  1. Diagnosing latency issues Redis
    เธรดเดียวประมวลผลคำขอตามลำดับ คำสั่งที่ช้าจึงขวางทุกคำขอที่ตามมา, ใช้ SCAN แทน KEYS, fork วัดจริงบนเครื่อง physical และ VM รุ่นใหม่ได้ราว 9–13 ms ต่อ 1 GB, THP ทำให้ดีเลย์และหน่วยความจำพุ่งจากการคัดลอกหลัง fork, คีย์จำนวนมากหมดอายุในวินาทีเดียวกันทำให้หยุด
  2. KEYS Redis
    ใช้บน production ด้วยความระมัดระวังอย่างยิ่ง อาจทำลายประสิทธิภาพบน DB ขนาดใหญ่ได้ (บนโน้ตบุ๊กระดับทั่วไป คีย์ 1,000,000 ตัวใช้ 40 ms)
  3. UNLINK Redis
    การลบแบบ asynchronous ที่ถอดคีย์ออกทันทีแล้วไปคืนหน่วยความจำในเธรดอื่น
  4. SLOWLOG Redis
    log คำสั่งช้าที่บันทึกคำสั่งที่เกิน slowlog-log-slower-than, เวลารันไม่รวม I/O รับส่งกับไคลเอนต์
  5. Redis latency monitoring Redis
    latency-monitor-threshold ค่าเริ่มต้น 0 (ปิด), LATENCY LATEST และ LATENCY DOCTOR, บันทึกดีเลย์แยกตามอีเวนต์ เช่น fork และ expire-cycle
  6. INFO Redis
    latest_fork_usec: เวลาที่ fork ครั้งล่าสุดใช้ (ไมโครวินาที)
  7. Redis CLI Redis
    --bigkeys: ไล่ดู keyspace เพื่อหาคีย์ใหญ่

สาเหตุที่ควรดูประกอบ

ชั้นเดียวกัน: L12 ฐานข้อมูล

สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (ค้าง)

ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง