คู่มือเกมแลค › L12 ฐานข้อมูล
แคชสแตมปีด Cache stampede / thundering herd
ID สาเหตุ db-cache-stampede · ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟรา DB (ทีมอินฟรา)
เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →
ถ้าแคชของข้อมูลยอดนิยมหมดอายุพร้อมกัน คำขอหลายพันรายการจะแห่ไปที่ DB พร้อมกัน
ทำไม ข้อมูลยอดนิยมที่เก็บใน Redis หรือที่อื่นหมดอายุพร้อมกัน → ผลคือ คำขอที่พยายามสร้างข้อมูลเดียวกันใหม่แห่ไปที่ DB พร้อมกัน → บนหน้าจอ DB โหลดเกิน หลายฟีเจอร์จึงช้าลงหรือค้างต่อ ๆ กันไป
- อาการ
- อินพุตดีเลย์, ค้าง, เข้าเกมไม่ได้/โหลดไม่จบ
- ปัจจัย
- การหยุดชะงัก, ความหน่วง
- ใครเจอ
- ทั้งเซิร์ฟเวอร์
- เกิดเมื่อไร
- เป็นรอบสม่ำเสมอ, ตอนคนแห่มารวมกัน
- ผู้รับผิดชอบ
- ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟรา DB (ทีมอินฟรา)
- งานฝั่งทีมพัฒนาเกม
- สุ่มกระจายเวลาหมดอายุ, ให้คำขอเดียวรีเฟรช ที่เหลือใช้ค่าเก่า
- งานฝั่งทีมอินฟรา
- จัด replica และ failover อัตโนมัติไม่ให้แคชว่างทั้งก้อนเมื่อ Redis รีสตาร์ตหรือขัดข้อง, ตรวจว่า DB มีกำลังเหลือพอรับได้แม้แคชว่าง
- บนกราฟ
- พุ่งเป็นรอบ · อัตรา hit ของแคช, จำนวนคิวรีต่อวินาทีของ DB
- จุดที่ต้องดู
- keyspace_hits และ keyspace_misses (อัตรา hit), expired_keys และการรีสตาร์ต (uptime_in_seconds) จาก INFO ของ Redis วางซ้อนกับจำนวนคิวรีต่อวินาทีของ DB และนับว่าในจังหวะนั้นมีคิวรีเดียวกันรันพร้อมกันบน DB กี่ตัว (MySQL SHOW PROCESSLIST, PostgreSQL pg_stat_activity)
- สัญญาณว่าใช่
- ช่วงที่ cache miss พุ่งขึ้นทันที จำนวนคิวรี DB พุ่งตาม และคิวรีที่รันพร้อมกันส่วนใหญ่เป็นคิวรีเดียวกันที่อ่านข้อมูลเดียวกัน ตรงกับรอบหมดอายุของคีย์ยอดนิยมหรือเวลาที่ Redis รีสตาร์ต
- สัญญาณว่าไม่ใช่
- cache miss เท่าปกติแต่คิวรี DB เพิ่มอย่างเดียว: น่าจะเป็นคนแห่ล็อกอิน (db-login-storm) หรืองาน batch (db-batch)
- วิธีตรวจ
- ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)
- รายละเอียดเพิ่มเติม
- ถ้า Redis รีสตาร์ตหรือขัดข้องจนแคชว่างทั้งก้อน ก็เกิดเรื่องเดียวกัน ยิ่งระบบที่วางใจแคชจนตั้ง DB ไว้เล็กยิ่งเสี่ยง
แหล่งอ้างอิง
- Scaling Memcache at Facebook (NSDI '13) USENIX
เมื่อคีย์ที่ใช้บ่อยถูก invalidate การอ่านจำนวนมากจะแห่ไปที่ DB (thundering herd), ป้องกันด้วย lease (ให้ไคลเอนต์เดียวรีเฟรช) และการคืนค่าเก่า, คลัสเตอร์ที่แคชว่างต้องวอร์มแยก - Optimal Probabilistic Cache Stampede Prevention VLDB Endowment
เมื่อรายการยอดนิยมหมดอายุ หลายคำขอจะสร้างใหม่พร้อมกัน (cache stampede), ป้องกันด้วยการรีเฟรชล่วงหน้าแบบสุ่มตามความน่าจะเป็นก่อนหมดอายุ - High availability with Redis Sentinel Redis
failover อัตโนมัติที่ promote replica เมื่อเซิร์ฟเวอร์หลักล่ม - INFO Redis
keyspace_hits และ keyspace_misses (จำนวนครั้งที่ค้นคีย์เจอและไม่เจอ), expired_keys (จำนวนคีย์ที่หมดอายุ), uptime_in_seconds (เวลาตั้งแต่เริ่มทำงาน) - SHOW PROCESSLIST Statement MySQL
คำสั่งที่กำลังรัน (Info) และเวลาที่อยู่ในสถานะปัจจุบัน (Time, วินาที) ของแต่ละเซสชัน - The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
pg_stat_activity: คิวรีที่กำลังรันอยู่ (query) ของแต่ละเซสชัน
สาเหตุที่ควรดูประกอบ
ชั้นเดียวกัน: L12 ฐานข้อมูล
สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (อินพุตดีเลย์)
ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง