Nếu thread game chờ ổ đĩa ghi xong từng dòng log, thì lúc ổ đĩa bận, game cũng bị dừng theo.
Vì sao Thread game ghi log chiến đấu và log giao dịch thẳng vào file → Dẫn đến Khi yêu cầu lưu chắc chắn (fsync), hoặc khi bộ đệm ghi của OS (page cache) chạm giới hạn, một lần ghi lúc ổ đĩa bận mất tới vài chục ms → Trên màn hình Khựng trong những trận đánh sinh nhiều log
Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Hạ tầng server (Đội hạ tầng)
Việc cần làm (Đội phát triển game)
Ghi log bất đồng bộ (bộ đệm trong bộ nhớ + thread riêng), giảm lượng log, không gọi fsync trên thread game.
Việc cần làm (Đội hạ tầng)
Chạy log rotation và nén log với mức ưu tiên I/O thấp, để log trên ổ đĩa khác với dữ liệu, giám sát độ trễ ghi ổ đĩa.
Trên đồ thị
Thỉnh thoảng vọt lên bất chợt · Thời gian xử lý tick của server, độ trễ ghi ổ đĩa
Chỗ cần xem
Đặt w_await, aqu-sz của iostat -x 1 chồng lên thời gian xử lý tick, dùng perf trace -p PID --duration 10 tìm các lời gọi write, fsync mất hơn 10 ms trong server game và thread đã gọi chúng
Đúng nếu
lúc tick vọt lên, lời gọi write, fsync của thread game mất vài chục ms, đồng thời độ trễ ghi ổ đĩa cũng vọt lên. Thường trùng với lúc log rotation hoặc nén log
Loại trừ nếu
thread game không có system call nào chạy lâu mà tick vẫn vọt lên → nguyên nhân khác như GC, lock, vượt tick budget. Chỉ thread chuyên ghi log có lời gọi chạy lâu → không ảnh hưởng đến game
Cách kiểm tra
Kiểm tra bằng công cụ hạ tầng (không cần code game)
Tìm hiểu thêm
Thông thường OS nhận thao tác ghi vào bộ nhớ (page cache) trước rồi mới ghi xuống ổ đĩa sau, nên ghi một dòng log thường xong ngay. Tình trạng dừng xảy ra khi fsync yêu cầu lưu chắc chắn, khi lượng ghi tồn đọng vượt giới hạn khiến OS chặn lời gọi ghi, hoặc khi file log được rotate hay nén. Vì vậy bình thường không sao, chỉ vọt lên đúng lúc ổ đĩa bận.
Nguồn
fsync(2) — Linux manual pageLinux man-pages fsync đẩy dữ liệu đã thay đổi xuống tận ổ đĩa (kể cả cache của ổ đĩa) và chặn cho tới khi thiết bị báo hoàn tất
Documentation for /proc/sys/vm/Linux kernel Khi lượng ghi tồn đọng (dirty) chạm dirty_ratio, chính tiến trình đang ghi phải tự đảm nhận việc ghi xuống ổ đĩa
ionice(1) — Linux manual pageutil-linux Tác vụ chạy với mức ưu tiên I/O idle chỉ được dùng ổ đĩa khi không chương trình nào khác đang dùng
iostat(1) — Linux manual pagesysstat -x: w_await (thời gian xử lý trung bình của yêu cầu ghi, tính cả thời gian chờ trong hàng đợi), aqu-sz (độ dài hàng đợi trung bình, tên cũ là avgqu-sz)
perf-trace(1) — Linux manual pageperf -p theo dõi system call của tiến trình đang chạy, --duration chỉ hiện các lời gọi mất lâu hơn số ms chỉ định