Thiết Kế Máy Chủ Dữ Liệu - nói dối e blog

Thiết Kế Máy Chủ Dữ Liệu

Hôm nay chính thức bắt đầu xây dựng hệ thống máy chủ dữ liệu. Về cơ bản, tôi mong muốn toàn bộ các yêu cầu truy xuất dữ liệu từ các dịch vụ logic trên cụm server sẽ được xử lý tập trung thông qua một máy chủ dữ liệu duy nhất. Về thao tác ghi dữ liệu, đây sẽ là quá trình truyền một chiều - các máy chủ logic chỉ cần gửi yêu cầu đọc/ghi đĩa mà không cần xác nhận trạng thái. Về vấn đề đọc dữ liệu, hiện tại tôi đã có phương án xử lý: máy chủ dữ liệu sẽ chỉ giao tiếp trực tiếp với máy chủ vị trí khi thực hiện thao tác tải dữ liệu, sau đó chuyển toàn bộ thông tin cần thiết về máy chủ vị trí quản lý.

Máy chủ vị trí thông qua việc phân tích dữ liệu sẽ xác định được luồng dữ liệu của người chơi cần được định tuyến đến máy chủ logic nào. Cơ chế này dựa trên nguyên tắc mỗi người chơi có một tập dữ liệu độc lập và chỉ tồn tại duy nhất tại một cảnh (scene) bất kỳ thời điểm nào. Khi một tập dữ liệu đang hoạt động, nó sẽ chỉ thuộc về duy nhất một máy chủ logic. Ưu điểm lớn của thiết kế này là việc chuyển cảnh trở nên cực kỳ đơn giản: chỉ cần yêu cầu người chơi thoát khỏi cảnh hiện tại, gửi lệnh ghi dữ liệu về máy chủ dữ liệu, sau đó chuyển toàn bộ dữ liệu liên quan. Trong quá trình ghi đĩa, máy chủ dữ liệu sẽ lưu cache dữ liệu đồng thời cập nhật vị trí mới lên máy chủ vị trí và chuyển tiếp dữ liệu về vị trí tương ứng. Máy chủ vị trí sau đó sẽ chuyển tiếp dữ liệu đến cảnh mới.

Với quy trình đăng nhập và đăng xuất, chúng ta có thể thiết kế hai cảnh ảo chuyên dụng: một cảnh xử lý đăng nhập và một cảnh xử lý đăng xuất. Mỗi kết nối mới sẽ tự động được chuyển đến cảnh đăng nhập - nơi sẽ phát lệnh tải dữ liệu (thực tế không cần thiết lập giao thức tải dữ liệu riêng biệt). Sau đó hệ thống sẽ tự động thực hiện chuyển cảnh. Đối với đăng xuất, người chơi sẽ được chuyển đến cảnh đăng xuất - một không gian “lỗ đen” nơi kết nối có thể được ngắt một cách an toàn.

Khi người chơi di chuyển liên tục giữa các cảnh, để tránh việc chuyển tiếp dữ liệu lặp lại không cần thiết, chúng ta có thể áp dụng cơ chế đánh dấu “bẩn” (dirty flag) cho dữ liệu người chơi. Nếu dữ liệu không bị đánh dấu bẩn, hệ thống có thể bỏ qua việc chuyển tiếp. Dấu hiệu này còn có ý nghĩa quan trọng khác: nếu dữ liệu không bẩn mà cache trên máy chủ dữ liệu lại không tồn tại, hệ thống sẽ tự động phát sinh yêu cầu đọc từ bộ nhớ ngoài. Đây thực chất chính là một yêu cầu đọc dữ liệu.

Khi trình bày thiết kế này trong công ty đầu tháng này, tôi đã nhận được một số câu hỏi từ đồng nghiệp. Một trong những thắc mắc điển hình là cách xử lý thông tin bang hội - dạng dữ liệu đặc thù không thuộc về bất kỳ người chơi cụ thể nào. Nếu chúng ta tạo một đối tượng phi người chơi để lưu trữ loại dữ liệu này, rất có thể nó sẽ bị phân tán trên nhiều máy chủ logic khác nhau, tạo ra thách thức lớn cho thiết kế.

Sau khi suy nghĩ kỹ, tôi đã tìm ra cách giải quyết vấn đề này ngay trong thiết kế hệ thống. Cụ thể, với ví dụ về bang hội, chúng ta có thể thiết kế một cảnh “tổng đàn” (headquarter) ảo. Cảnh này có thể hoàn toàn ảo về mặt biểu diễn trên client - ví dụ chỉ là một giao diện đơn giản nơi các người chơi khi tham gia sẽ không nhìn thấy nhau. Cách thiết kế này giúp giảm đáng kể lượng thông tin liên lạc.

Bất cứ khi nào người chơi cần truy vấn hoặc sửa đổi dữ liệu bang hội, hệ thống sẽ bắt buộc họ “vào tổng đàn” để thực hiện thao tác (tức là xử lý trên một tiến trình độc lập duy nhất). Sau khi hoàn tất, người chơi sẽ tự động quay về vị trí ban đầu mà không hề nhận ra mình đã “đi xa”. Thiết kế này mở ra nhiều khả năng phát triển gameplay mới - ví dụ như việc mở các “phân đàn” ở nhiều nơi khác nhau. Khi tổ chức vận chuyển vật資 từ tổng đàn đến phân đàn, thực tế toàn bộ dữ liệu kho bãi đều được quản lý trên cùng một tiến trình. Về mặt biểu diễn, người chơi có cảm giác đang vận chuyển hàng hóa qua quãng đường xa xôi, nhưng thực chất chỉ là thay đổi thông tin sở hữu vật phẩm.

Ngay cả các giao dịch “hối phiếu” cũng có thể được xử lý hiệu quả. Khi người chơi nhận một giao dịch hối phiếu, hệ thống có thể yêu cầu họ quay về tổng đàn để kiểm tra uy tín bang hội hoặc xác thực khả năng thanh toán. Vì sau khi phát hành, dữ liệu hối phiếu đã được chuyển sang quản lý cá nhân, không còn liên quan trực tiếp đến dữ liệu bang hội.

Thiết kế này tất nhiên sẽ tạo ra độ trễ nhất định trong việc sao chép dữ liệu bang hội - ví dụ người chơi không thể biết ngay ai là bang chủ mới hay các thay đổi trong bang. (Đây chỉ là ví dụ, nếu thực sự muốn giải quyết, có thể sử dụng kênh chat không đáng tin cậy). Tuy nhiên tôi cho rằng điều này hoàn toàn phù hợp với thực tế - trong thế giới thực, việc tiếp nhận thông tin cũng phụ thuộc vào nguồn phát sinh thông tin đó.

Khi đã thấu hiểu các nguyên lý này, tôi cảm thấy thiết kế tổng thể vẫn giữ được sự đơn giản vốn có, hoàn toàn phù hợp với nguyên tắc KISS (Giữ cho mọi thứ đơn giản và trực quan). Mỗi tiến trình chỉ cần tập trung làm tốt một việc duy nhất :)

P/s: Thiết kế này cũng làm nổi bật tầm quan trọng của máy chủ theo dõi trạng thái (heartbeat server). Các cảnh ảo như quản lý bang hội có thể thiết lập tần suất heartbeat thấp hơn (không cần 10Hz như trong xử lý chiến đấu), từ đó giảm tải cho tiến trình mà không ảnh hưởng nhiều đến trải nghiệm người chơi.

0%