文档首页/ 分布式缓存服务 DCS/ 最佳实践/ 业务应用/ 使用DCS实现游戏开合服的数据同步
更新时间:2024-09-25 GMT+08:00

使用DCS实现游戏开合服的数据同步

方案概述

应用场景

游戏业务开合服,指一些大型网络游戏为了吸引新玩家,在运营一段时间后,会开启新服务区,当新服务区开放后,老服务区用户存在流向新服务区的趋势,用户数逐渐减少,为了改善老服务区用户的游戏体验,延长游戏生命周期,游戏开发商通常会进行新老服务区合并,将新开和原有的两个服务器(区)的数据合并到一个服务器(区),使新老玩家就能在同一个区进行游戏。在这个过程中,会遇到如何将不同服务器数据同步的相关问题。

解决方案

在游戏开合服方面,使用分布式缓存服务(DCS)的Redis缓存可以应用到以下场景:

  • 跨服数据同步

    游戏合服后,需要将多个游戏服务器的数据进行同步,以保证游戏数据的一致性。可以使用Redis的消息队列pub/sub机制,将数据变更消息发布到Redis的频道中,其他游戏服务器订阅该频道,接收数据变更消息,从而实现数据同步。

  • 跨服资源共享

    游戏合服后,可以将多个游戏服务器的资源进行共享,例如玩家道具、金币等。可以使用Redis的分布式锁机制,来保证多个游戏服务器对资源的访问互斥,避免资源冲突。

  • 跨服排行榜

    游戏合服后,可以将多个游戏服务器的排行榜进行合并,以展示全服的排名情况。可以使用Redis的有序集合机制,来存储排行榜数据,并进行排名计算和查询。

在以上三种应用场景中,“跨服资源共享”的实现方式可以参考使用DCS实现热点资源顺序访问,“跨服排行榜”的实现方式可以参考使用DCS实现排行榜功能

本篇文档主要介绍如何通过Redis的消息队列pub/sub机制,实现“跨服数据同步”。

在使用Redis进行游戏合服方面的应用时,需要考虑数据一致性、性能和安全等方面的问题,避免出现数据错误、性能瓶颈或者安全漏洞等问题。

前提条件

  • 已创建DCS缓存实例,且状态为“运行中”。
  • 客户端所在服务器与DCS缓存实例网络互通:
    • 客户端与Redis实例所在VPC为同一VPC

      同一VPC内网络默认互通。

    • 客户端与Redis实例所在VPC为相同region下的不同VPC

      如果客户端与Redis实例不在相同VPC中,可以通过建立VPC对等连接方式连通网络,具体请参考:缓存实例是否支持跨VPC访问?

    • 客户端与Redis实例所在VPC不在相同region

      如果客户端服务器和Redis实例不在同一region,仅支持通过云专线打通网络,请参考云专线

    • 公网访问

      客户端公网访问Redis 4.0/5.0/6.0实例请参考使用Nginx实现公网访问DCS使用华为云ELB公网访问DCS

实施步骤

  1. 使用Redis-py库中的Redis()方法在每个游戏服务器上创建一个Redis客户端连接。
  2. 使用pubsub()方法在每个游戏服务器上创建一个Redis订阅者和发布者。用于订阅其他游戏服务器发布的消息,以及发布本地游戏服务器的数据更新消息。当某个游戏服务器需要更新数据时,它会将更新的消息发布到Redis消息队列中。其他游戏服务器会收到更新消息并相应地更新各自的本地数据。
  3. 定义一个publish_update()方法发布更新消息,并在listen_updates()方法中使用subscriber.listen()方法来监听更新消息。
  4. 当收到更新消息时,通过调用handle_update()方法来处理更新消息并更新本地数据。在游戏服务器中,通过调用publish_update()来发布更新消息,以及调用listen_updates()来监听更新消息。

示例代码

以下是使用Redis-py库实现消息队列pub/sub机制进行游戏跨服数据同步的示例代码(本示例代码以python2为例):

import redis
 # 创建Redis客户端连接,Redis实例连接地址和端口需替换为实际获取的值
redis_client = redis.Redis(host='localhost', port=6379, db=0)
 # 创建Redis订阅者
subscriber = redis_client.pubsub()
subscriber.subscribe('game_updates')
 # 创建Redis发布者
publisher = redis_client
 # 发布更新消息
def publish_update(update):
    publisher.publish('game_updates', update)
 # 处理更新消息
def handle_update(update):
    # 处理更新消息,更新本地数据
    print('Received update:', update)
 # 监听更新消息
def listen_updates():
    for message in subscriber.listen():
        if message['type'] == 'message':
            update = message['data']
            handle_update(update)
 # 在游戏服务器中调用发布更新消息的方法
publish_update('player_data_updated')
 # 在游戏服务器中调用监听更新消息的方法
listen_updates()

输出结果:

D:\workspace\pythonProject\venv\Scripts\python.exe D:\workspace\pythonProject\test2.py 
Received update: b'player_data_updated'