คู่มือเกมแลค › L11 ดิสก์
การเขียน log แบบ synchronous Synchronous logging
ID สาเหตุ dk-sync-log · ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา)
เปิดการ์ดในฉบับหลักที่มีภาพและการทดลอง →
ถ้าเธรดเกมต้องรอให้ดิสก์เขียนเสร็จทุกครั้งที่เขียน log หนึ่งบรรทัด พอดิสก์ยุ่ง เกมก็หยุดเดินไปด้วย
ทำไม เขียน log การต่อสู้และการเทรดลงไฟล์โดยตรงจากเธรดเกม → ผลคือ ถ้าสั่งให้เขียนลงดิสก์แบบแน่นอน (fsync) หรือบัฟเฟอร์การเขียนของ OS (page cache) เต็มถึงขีดจำกัด ตอนที่ดิสก์ยุ่ง การเขียนหนึ่งครั้งจะใช้เวลาหลายสิบ ms → บนหน้าจอ หยุดแวบในการต่อสู้ที่มี log เยอะ
- อาการ
- กระตุก, ค้าง
- ปัจจัย
- การหยุดชะงัก
- ใครเจอ
- บางจุด/บางแชนแนล, ทั้งเซิร์ฟเวอร์
- เกิดเมื่อไร
- ตอนคนแห่มารวมกัน
- ผู้รับผิดชอบ
- ผู้รับผิดชอบหลัก พัฒนาเซิร์ฟเวอร์ (ทีมพัฒนาเกม) · ร่วมกับ อินฟราเซิร์ฟเวอร์ (ทีมอินฟรา)
- งานฝั่งทีมพัฒนาเกม
- ใช้ async logging (บัฟเฟอร์ในหน่วยความจำ + เธรดแยก), ลดปริมาณ log, ไม่เรียก fsync ในเธรดเกม
- งานฝั่งทีมอินฟรา
- รัน log rotation และการบีบอัด log ด้วยลำดับความสำคัญ I/O ต่ำ, แยก log ไว้คนละดิสก์กับข้อมูล, มอนิเตอร์ดีเลย์การเขียนดิสก์
- บนกราฟ
- พุ่งแบบสุ่มเป็นครั้งคราว · เวลาต่อทิกของเซิร์ฟเวอร์, ดีเลย์การเขียนดิสก์
- จุดที่ต้องดู
- w_await และ aqu-sz จาก iostat -x 1 วางซ้อนกับเวลาต่อทิก และใช้ perf trace -p PID --duration 10 หาการเรียก write และ fsync ในเซิร์ฟเวอร์เกมที่ใช้เวลาเกิน 10 ms พร้อมเธรดที่เรียก
- สัญญาณว่าใช่
- ช่วงที่ทิกพุ่ง การเรียก write และ fsync ของเธรดเกมใช้เวลาหลายสิบ ms และดีเลย์การเขียนดิสก์ก็พุ่งในจังหวะเดียวกัน มักตรงกับเวลาทำ log rotation หรือบีบอัด log
- สัญญาณว่าไม่ใช่
- เธรดเกมไม่มี system call ที่ใช้เวลานานแต่ทิกยังพุ่ง: น่าจะเป็นสาเหตุอื่น เช่น GC, ล็อก หรือทิกเกินงบ ถ้านานเฉพาะเธรดที่เขียน log อย่างเดียว จะไม่กระทบการเดินของเกม
- วิธีตรวจ
- ใช้เครื่องมือฝั่งอินฟรา (ไม่ต้องใช้โค้ดเกม)
- รายละเอียดเพิ่มเติม
- ปกติ OS จะรับการเขียนไว้ในหน่วยความจำ (page cache) ก่อนแล้วค่อยเขียนลงดิสก์ทีหลัง log หนึ่งบรรทัดจึงมักเสร็จทันที การหยุดเกิดขึ้นเมื่อสั่งให้เขียนแบบแน่นอนด้วย fsync, เมื่อการเขียนที่กองรอเกินขีดจำกัดจน OS บล็อกการเรียกเขียน และเมื่อทำ rotation หรือบีบอัดไฟล์ log ด้วยเหตุนี้ ปกติจึงไม่มีปัญหา แต่จะพุ่งเฉพาะตอนที่ดิสก์ยุ่ง
แหล่งอ้างอิง
- fsync(2) — Linux manual page Linux man-pages
fsync ส่งข้อมูลที่เปลี่ยนแปลงลงไปถึงดิสก์ (รวมแคชของดิสก์) และบล็อกจนกว่าอุปกรณ์จะแจ้งว่าเสร็จ - Documentation for /proc/sys/vm/ Linux kernel
เมื่อการเขียนที่กองรอ (dirty) ถึง dirty_ratio โปรเซสที่กำลังเขียนต้องรับหน้าที่เขียนลงดิสก์เอง - ionice(1) — Linux manual page util-linux
งานที่รันด้วยลำดับความสำคัญ I/O แบบ idle จะได้ใช้ดิสก์เฉพาะตอนที่โปรแกรมอื่นไม่ได้ใช้ดิสก์ - iostat(1) — Linux manual page sysstat
-x: w_await (เวลาประมวลผลเฉลี่ยของคำขอเขียน รวมเวลาที่รอในคิว), aqu-sz (ความยาวคิวเฉลี่ย ชื่อเดิมคือ avgqu-sz) - perf-trace(1) — Linux manual page perf
-p ติดตาม system call ของโปรเซสที่รันอยู่, --duration แสดงเฉพาะการเรียกที่ใช้เวลานานกว่าจำนวน ms ที่กำหนด
สาเหตุที่ควรดูประกอบ
ชั้นเดียวกัน: L11 ดิสก์
สาเหตุจากชั้นอื่นที่ทำให้เกิดอาการเดียวกัน (กระตุก)
ดูการ์ดในฉบับหลักที่มีภาพและการทดลอง