Sách trắng lag game › Tra theo triệu chứng
Trễ thao tác: 76 nguyên nhân và đội phụ trách
Tên gọi khác: input lag, delay, phản hồi chậm, thiếu cảm giác tay
Mở từ điển triệu chứng gốc có hình minh họa →
Từ lúc bấm đến lúc thấy kết quả mất một khoảng thời gian. Bản thân màn hình có thể vẫn mượt.
Bấm nút skill thì 0,2–0,5 giây sau mới ra chiêu. Các hành động cần xác nhận như nhặt đồ, hội thoại, giao dịch đều chậm.
Thời gian khứ hồi (ping) dài, hoặc có hàng đợi bị dồn ở đâu đó. Hãy xem khoảng cách, hàng đợi của router, Nagle (tính năng của TCP gom các gói nhỏ lại rồi mới gửi), hàng đợi của server. Nếu ping thấp mà lúc nào cũng ì thì hãy xem phía PC của bạn như V-Sync hay FPS thấp, hoặc thiết kế bắt mọi hành động phải chờ server xác nhận (chương về cơ chế đồng bộ).
Nguyên nhân gây ra triệu chứng này
L1 Tiến trình game phía client
- Tải render khi đông người: Khi hàng trăm người cùng hiện trên một màn hình như lúc công thành hay đánh world boss, riêng chi phí vẽ đã vượt quá sức máy. (Phát triển client (Đội phát triển game))
- Nghẽn xử lý gói tin trên main thread: Nếu mỗi khung hình chỉ xử lý một lượng gói tin cố định, số gói dồn tới sẽ liên tục bị đẩy sang khung hình sau. (Phát triển client (Đội phát triển game))
- V-Sync và hàng đợi render: GPU xếp vài khung hình đã vẽ vào hàng đợi rồi mới đẩy ra theo chu kỳ của màn hình, và trong lúc đó thao tác bị trễ. (Phát triển client (Đội phát triển game))
L2 OS và thiết bị phía client
L3 Mạng gia đình
- Kênh Wi-Fi bị nghẽn: Ở nơi có hàng chục router như chung cư, các thiết bị phải chia nhau cùng một kênh nên phải chờ tới lượt truyền. (Bên ngoài (Bên ngoài))
- Bufferbloat (hàng đợi của router): Khi ai đó trong nhà tải video lên hoặc tải file lớn xuống, hàng đợi của router dồn lượng gói tin tương đương hàng trăm ms, và gói tin game cũng phải chờ phía sau. (Bên ngoài (Bên ngoài))
- Trễ chuyển trạng thái RRC (chế độ tiết kiệm điện của mạng di động): Khi không có dữ liệu trong một lúc, điện thoại hạ kết nối sóng xuống trạng thái tiêu thụ điện thấp, và đến gói tin kế tiếp phải kích hoạt lại nên bị trễ. (Phát triển client (Đội phát triển game))
L4 Đường truyền Internet
- Độ trễ lan truyền (khoảng cách vật lý): Ngay cả ánh sáng trong cáp quang cũng chỉ đi được khoảng 200.000 km trong 1 giây. Server ở xa thì dù tốt đến đâu vẫn chậm. (Hạ tầng server (Đội hạ tầng))
- Internet vệ tinh (quỹ đạo thấp, địa tĩnh): Với Internet vệ tinh, sóng phải đi lên vũ trụ rồi quay về. Vệ tinh địa tĩnh chỉ riêng thời gian khứ hồi đã hơn 0,5 giây. Vệ tinh quỹ đạo thấp như Starlink bình thường thì nhanh, nhưng vào lúc tuyến đường được phân lại, độ trễ dao động và đôi khi kết nối đứt quãng trong chốc lát. (Bên ngoài (Bên ngoài))
- Định tuyến đi đường vòng: Do hợp đồng kết nối giữa các nhà mạng, dữ liệu tới cả server ở gần cũng phải đi vòng qua nơi xa. (Hạ tầng mạng (Đội hạ tầng))
- Sự cố cáp quang biển, đường truyền quốc tế: Khi cáp quang biển bị đứt, dữ liệu phải đi vòng theo tuyến xa trong nhiều tuần (có khi nhiều tháng) cho đến khi sửa xong, và các đường truyền còn lại bị nghẽn. (Bên ngoài (Bên ngoài))
- Nhà mạng giới hạn tốc độ và quản lý lưu lượng: Khi dùng vượt dung lượng data, hoặc với gói cước có quản lý một số loại lưu lượng, gói tin bị làm chậm hoặc bị bỏ. (Bên ngoài (Bên ngoài))
- Đi qua VPN hoặc phần mềm tăng tốc game: Khi bật VPN hoặc phần mềm tăng tốc game, gói tin sẽ đi qua server trung chuyển của công ty đó. Nếu server trung chuyển ở xa hoặc đông, kết nối lại chậm hơn cả khi không bật. (Bên ngoài (Bên ngoài))
L5 Thiết bị mạng trung tâm dữ liệu
- Đi qua hệ thống chống DDoS, chặn nhầm: Để chặn tấn công, lưu lượng được chuyển qua trung tâm lọc DDoS nên tuyến đường dài ra, và đôi khi người chơi bình thường bị nhầm là kẻ tấn công và bị chặn. (Hạ tầng mạng (Đội hạ tầng))
- Đường truyền trung tâm dữ liệu bị bão hòa: Nếu việc phân phối bản cập nhật, gửi log, sao lưu dùng chung đường truyền với game thì đường truyền bị đầy. (Hạ tầng mạng (Đội hạ tầng))
L6 Card mạng server
- Ngắt NIC dồn vào một core: Nếu NIC chỉ gửi ngắt báo gói tin đến cho một core CPU, core đó sẽ thành điểm nghẽn. (Hạ tầng server (Đội hạ tầng))
- Gộp ngắt quá mức: Để giảm tải cho CPU, NIC gom gói tin lại rồi báo một lần, nên gói bị trễ đúng bằng thời gian gom. (Hạ tầng server (Đội hạ tầng))
- Băng thông NIC bị bão hòa: Khi dùng tới giới hạn của card 1 Gbps hay 10 Gbps, hàng đợi gửi dài ra và cuối cùng gói bị bỏ. (Phát triển server (Đội phát triển game))
- Độ trễ chờ gộp gói GRO/LRO: Đây là tính năng gộp nhiều gói thành một để giảm tải cho CPU. Tùy cấu hình, gói game nhỏ đôi khi phải chờ một chút gói tiếp theo để gộp cùng. (Hạ tầng server (Đội hạ tầng))
L7 OS server (kernel)
- Độ trễ vọt lên do quản lý nguồn điện của server (C-state, điều chỉnh xung nhịp): Core CPU đang rảnh sẽ vào trạng thái tiết kiệm điện sâu (C-state) và hạ xung nhịp để tiết kiệm điện. Khi có gói tin hoặc timer đến, core cần thời gian để thức dậy và nâng xung nhịp, nên việc xử lý gói nhỏ bị cộng thêm độ trễ. (Hạ tầng server (Đội hạ tầng))
- Hiệu năng thay đổi sau khi cập nhật OS, kernel, driver hoặc firmware: Code game không đổi, nhưng server chậm đi kể từ khi cập nhật OS, kernel, driver hoặc firmware. Bản cập nhật có thể làm thay đổi giá trị mặc định, bộ lập lịch, các biện pháp giảm thiểu lỗ hổng CPU (mitigations) và cách driver hoạt động. (Hạ tầng server (Đội hạ tầng))
L8 Socket và giao thức
- Thuật toán Nagle + delayed ACK: Thuật toán Nagle (gom gói nhỏ lại để gửi) và delayed ACK (gửi ACK muộn) tác động chồng lên nhau, nên mỗi lần tách một message ra ghi nhiều lần là bị trễ 40–200 ms. (Phát triển server (Đội phát triển game))
- Slow start sau thời gian nhàn rỗi: Khi kết nối nhàn rỗi một lúc, TCP thu nhỏ lại cửa sổ tắc nghẽn (lượng dữ liệu gửi được trong một lần), nên khi đột ngột gửi dữ liệu lớn, TCP phải chia ra gửi nhiều lượt. (Hạ tầng server (Đội hạ tầng))
- Lượng gửi giảm mạnh do kiểm soát tắc nghẽn: TCP coi mất gói là tín hiệu tắc nghẽn và giảm tốc độ gửi 30–50%. Mất gói do Wi-Fi cũng bị xử lý y như vậy. (Hạ tầng server (Đội hạ tầng))
- Kiến trúc I/O blocking: Với kiến trúc mà thread không làm được việc gì khác trong lúc chờ một socket, người chơi càng đông thì cả hệ thống càng chậm. (Phát triển server (Đội phát triển game))
L9 Tiến trình game phía server
- Vượt tick budget: Khi khối lượng việc trong một tick vượt budget, chu kỳ tick của server bị kéo dài, và cả khu vực đó chạy chậm lại hoặc giật khựng. (Phát triển server (Đội phát triển game))
- Broadcast bùng nổ: Gửi chuyển động của một người cho tất cả những ai nhìn thấy người đó thì số bản cập nhật phải gửi tăng theo bình phương số người tụ tập. (Phát triển server (Đội phát triển game))
- Quá tải khu vực chạy trên một thread (hotspot): Với kiến trúc mỗi khu vực do một thread phụ trách, khi người chơi dồn vào một chỗ, chỉ một core đó lên 100%. (Phát triển server (Đội phát triển game))
- Tranh chấp lock: Khi nhiều thread cùng chờ một lock để ghi cùng một dữ liệu, dù có thêm thread thì mỗi lúc cũng chỉ một thread chạy. (Phát triển server (Đội phát triển game))
- Hàng đợi message bị dồn ứ: Khi yêu cầu đến nhanh hơn tốc độ xử lý và dồn vào hàng đợi, các yêu cầu phía sau vài giây sau mới được xử lý hoặc bị bỏ. (Phát triển server (Đội phát triển game))
- Chi phí serialize và nén: Việc chuyển dữ liệu cần gửi thành byte và nén cũng tốn CPU, và khi đông người, chi phí này tăng vọt. (Phát triển server (Đội phát triển game))
- Cạn thread pool: Khi mọi worker thread xử lý việc đều bị kẹt ở các việc chậm, yêu cầu mới chỉ biết chờ vô thời hạn. (Phát triển server (Đội phát triển game))
- Giao tranh dồn vào một mục tiêu (world boss): Khi hàng trăm người cùng đánh một boss, phần tính toán cho một con boss dồn vào một chỗ, và thông tin đòn đánh được gửi cho mọi người đang nhìn thấy. (Phát triển server (Đội phát triển game))
- Spawn dồn dập khi vào khu vực đông người: Khi bạn teleport vào một thị trấn chật kín người, server phải gửi cùng lúc ngoại hình, trang bị và trạng thái của hàng trăm người vừa lọt vào tầm nhìn. (Phát triển server (Đội phát triển game))
- Đối tượng tích tụ (vật phẩm và vật triệu hồi không được dọn): Vật phẩm rơi trên đất, vật triệu hồi, timer đã xong lẽ ra phải biến mất. Nếu chúng không được dọn mà cứ tích tụ, server chạy càng lâu thì mỗi tick càng nhiều việc. (Phát triển server (Đội phát triển game))
- Bản cập nhật làm thay đổi mô hình lưu lượng: Khi nội dung, hiệu ứng hoặc trường đồng bộ mới làm tăng kích thước và tần suất gói tin, server đang chạy tốt bắt đầu chạm giới hạn MTU, băng thông và số gói kể từ sau bản cập nhật. (Phát triển server (Đội phát triển game))
L11 Ổ đĩa
- fsync dồn dập: Mỗi yêu cầu ghi dữ liệu xuống ổ đĩa “chắc chắn” mất từ 0,1 ms đến vài chục ms tùy ổ đĩa, và khi các yêu cầu dồn lại thì hàng đợi dài ra. (Phát triển server (Đội phát triển game))
- Cạn burst credit của ổ đĩa cloud: Một số ổ đĩa cloud và cấu hình server nhỏ có burst credit cho phép tạm chạy nhanh hơn mức cơ bản. Khi giờ bận kéo dài làm credit cạn, tốc độ đột ngột tụt xuống. (Hạ tầng server (Đội hạ tầng))
- Chạm giới hạn IOPS, hàng đợi bão hòa: Khi vượt số yêu cầu ổ đĩa xử lý được trong 1 giây, hàng đợi dài ra và độ trễ tăng vọt. (Hạ tầng server (Đội hạ tầng))
- Tác vụ sao lưu, nén, quét: Khi sao lưu lúc rạng sáng, nén log hoặc quét bảo mật chiếm trọn ổ đĩa, việc đọc ghi của server game bị dồn lại. (Hạ tầng server (Đội hạ tầng))
- Độ trễ seek của HDD: HDD phải di chuyển đầu đọc trên đĩa từ (seek), nên mỗi lần đọc ghi dữ liệu nằm rải rác mất gần 10 ms. (Hạ tầng server (Đội hạ tầng))
L12 Cơ sở dữ liệu
- Query không có index: Không có index thì muốn tìm các dòng thỏa điều kiện, DB phải đọc toàn bộ bảng (full scan). (Phát triển server (Đội phát triển game))
- Tranh chấp khóa trên hot row: Khi ai cũng muốn sửa cùng một dòng (kho bang hội, vật phẩm hot ở nhà đấu giá, bộ đếm toàn server), mỗi lúc chỉ một người lấy được khóa. (Phát triển server (Đội phát triển game))
- Deadlock trong DB: Khi hai transaction (nhóm thao tác DB được xử lý như một khối) chờ dòng mà bên kia đã khóa, DB buộc phải hủy một bên. (Phát triển server (Đội phát triển game))
- Cạn connection pool: Số kết nối tạo sẵn tới DB là cố định, nên khi query chậm chiếm giữ kết nối, các yêu cầu còn lại phải chờ. (Phát triển server (Đội phát triển game))
- Checkpoint, flush log: Đúng lúc DB định kỳ ghi dồn các thay đổi trong bộ nhớ xuống ổ đĩa, query chậm đi. (Hạ tầng DB (Đội hạ tầng))
- Cache lạnh (ngay sau khởi động lại): Khi DB khởi động lại, cache trong bộ nhớ trống trơn, nên một thời gian mọi truy vấn đều phải đọc từ ổ đĩa. (Hạ tầng DB (Đội hạ tầng))
- Đăng nhập ồ ạt và query N+1: Nếu tải một nhân vật mà phải truy vấn riêng lẻ vài chục lần, thì vài chục nghìn người đăng nhập cùng lúc sẽ thành hàng triệu query. (Phát triển server (Đội phát triển game))
- Tác vụ batch khối lượng lớn: Nếu chạy tổng hợp bảng xếp hạng, gửi thư hàng loạt hay dọn dữ liệu cũ trong lúc đang vận hành, các tác vụ này sẽ chiếm khóa và ổ đĩa. (Phát triển server (Đội phát triển game))
- Cache stampede: Khi cache của dữ liệu được dùng nhiều hết hạn cùng lúc, hàng nghìn yêu cầu đồng loạt dồn về DB. (Phát triển server (Đội phát triển game))
- Transaction mở quá lâu: Nếu một transaction mở quá lâu, nó giữ khóa mãi, và DB không dọn (purge) được dữ liệu phiên bản cũ nên toàn bộ hệ thống chậm dần. (Phát triển server (Đội phát triển game))
- Lệnh Redis chậm: Redis xử lý lần lượt từng lệnh một, nên một lệnh chậm sẽ chặn mọi yêu cầu phía sau. (Phát triển server (Đội phát triển game))
- Query chậm do kế hoạch thực thi thay đổi: Code không đổi, nhưng nếu DB đổi cách xử lý cùng một query (kế hoạch thực thi), query hôm qua mất 2 ms thì hôm nay mất vài trăm ms. (Hạ tầng DB (Đội hạ tầng))
- Khóa do thay đổi schema (DDL) khi đang vận hành: Nếu thêm cột hay index vào bảng trong lúc đang phục vụ, chỉ vì một khóa cần trong chốc lát mà mọi yêu cầu dùng bảng đó có thể phải chờ. (Hạ tầng DB (Đội hạ tầng))
L13 Kiến trúc và vận hành server
- Đi qua gateway hoặc proxy: Khi đặt một server trung gian giữa client và server game, mỗi lần đi qua nó lại cộng thêm thời gian xử lý, và server đó trở thành điểm lỗi duy nhất (single point of failure). (Phát triển server (Đội phát triển game))
- Sự cố dây chuyền: Khi một service chậm đi, các server gọi đến nó bị giữ lại để chờ phản hồi, và cả những tính năng không liên quan cũng đứng lại. (Phát triển server (Đội phát triển game))
- Triển khai và khởi động lại: Khi khởi động lại server để cập nhật mà không chuyển kết nối đi nơi khác, những người đang ở server đó bị mất kết nối, đồng thời việc lưu dữ liệu ngay trước khi tắt và việc kết nối lại dồn vào cùng một lúc. (Phát triển server (Đội phát triển game))
- Quá nhiều macro và bot: Bot gửi yêu cầu thường xuyên hơn người thật rất nhiều, dần chiếm mất năng lực xử lý của server. (Phát triển server (Đội phát triển game))
- Lỗi matchmaking hoặc phân bổ region: Nếu bị xếp vào server ở region xa thay vì region gần, dù đường truyền vẫn ổn, riêng người chơi đó luôn có ping cao. (Phát triển server (Đội phát triển game))
Thiết kế đồng bộ
- Chỉ hiển thị sau khi server phản hồi (mô hình yêu cầu-phản hồi): Khi bấm nút, không có animation hay âm thanh nào cho đến khi server trả lời. Ping trở thành chính tốc độ phản hồi. (Phát triển client (Đội phát triển game))
- Giao thức nhiều lượt khứ hồi tuần tự (chatty): Nếu một thao tác cần nhiều lượt khứ hồi tới server theo thứ tự, ping bị nhân lên đúng bấy nhiêu lần. (Phát triển server (Đội phát triển game))
- Không có buffer input cho skill: Nếu phải nhận xác nhận từ server rằng skill trước đã xong mới bấm được skill tiếp theo, mỗi nhịp combo sẽ bị chen thêm một khoảng thời gian khứ hồi. (Phát triển client (Đội phát triển game))
- Khung phán định ngắn bị ping ăn mất: Nếu thời gian phải phản ứng ngắn như né tránh, parry, đỡ đòn, ping sẽ ăn mất khoảng thời gian đó và tạo ra những đòn không thể né. (Phát triển server (Đội phát triển game))
- Lockstep phải chờ người chơi chậm nhất: Trong cấu trúc mọi người cùng tính chung một lượt, chỉ cần input của một người đến muộn là tất cả phải chờ. (Phát triển server (Đội phát triển game))
- Chờ tick hai lần: Nếu gom yêu cầu tới tick sau mới xử lý, rồi kết quả lại đợi đến tick sau nữa mới gửi, khoảng cách tick bị cộng vào hai lần. (Phát triển server (Đội phát triển game))
Sự cố chỉ một số người gặp
- Kích thước bộ đệm input theo người chơi: Nếu server gom input của mỗi người một chút rồi lấy ra một input mỗi tick, người khác thấy mượt, nhưng thời điểm hành động của chính người đó được xác nhận trên server sẽ muộn đi tương ứng. (Phát triển server (Đội phát triển game))
- Một đồng đội chậm và cơ chế boss: Trong cơ chế raid đòi hỏi mọi người cùng phản ứng vào một thời điểm định sẵn, phản ứng muộn của một người chậm sẽ thành thất bại của cả tổ đội. (Phát triển server (Đội phát triển game))
- Dữ liệu của một nhân vật quá lớn: Nhân vật tích hàng nghìn vật phẩm, thư, hoặc có danh sách bạn bè, danh sách chặn, buff nhiều bất thường thì lượng dữ liệu phải xử lý khi vào game, khi lưu và khi thông báo cho xung quanh lớn gấp nhiều lần người khác. Chỉ nhân vật đó chậm, bất kể đường truyền. (Phát triển server (Đội phát triển game))
- Ngân sách gửi và mức ưu tiên theo kết nối: Nếu server đặt giới hạn lượng gửi cho từng kết nối và gửi những thứ ở gần trước, bên có giới hạn thấp sẽ nhận NPC ở xa muộn hoặc không nhận được. (Phát triển server (Đội phát triển game))
Nguyên nhân gốc của truyền lại TCP
- Host server nhận bỏ gói tin: Gói tin đã đến được server nhưng bị bỏ vì ring buffer của NIC (bộ đệm tạm giữ gói tin vừa đến) bị tràn, hoặc core xử lý nhận gói của kernel bị bão hòa. (Hạ tầng server (Đội hạ tầng))
- Truyền lại không cần thiết do độ trễ tăng vọt: Gói tin vẫn đến nơi, chỉ là đến rất muộn trong chốc lát; nếu độ trễ đó dài hơn RTO thì bên gửi xác định là mất rồi truyền lại. (Bên ngoài (Bên ngoài))
- Truyền lại nhanh không cần thiết do gói đến sai thứ tự: Khi đi qua nhiều tuyến hoặc các link được gộp, thứ tự gói tin có thể bị đảo; bên nhận dùng ACK trùng (duplicate ACK) để báo “có gói bị thiếu”, và bên gửi gửi lại cả gói vẫn còn nguyên vẹn. (Hạ tầng mạng (Đội hạ tầng))
- ACK đến muộn hoặc bị mất (chiều tải lên bị bão hòa): Dữ liệu đã đến nơi, nhưng nếu ACK báo “đã nhận” bị trễ hoặc bị mất trong hàng đợi upload đang đầy, bên gửi sẽ xác định là mất gói rồi truyền lại. (Bên ngoài (Bên ngoài))
- Cấu hình RTO không hợp với môi trường: Hạ RTO tối thiểu quá thấp thì chỉ trễ một chút cũng sinh ra truyền lại không cần thiết, còn giá trị mặc định (200 ms) lại quá dài với game nên mỗi lần mất gói là đứng lâu. (Hạ tầng server (Đội hạ tầng))
Xem từ điển triệu chứng gốc có hình minh họa