You need to enable JavaScript to run this app.
导航
基于 Redis JSON 构建 MongoDB 二级缓存访问实时数据
最近更新时间:2024.12.04 10:53:39首次发布时间:2024.09.30 16:45:05

本文介绍基于火山引擎缓存数据库 Redis 企业版和文档数据库 MongoDB 版构建 MongoDB 二级缓存访问实时数据的解决方案。

方案目标

本解决方案旨在通过 RedisAnt 应用实现实时缓存 JSON 数据,实时连接同步 MongoDB 数据库,同时支持自动向本地缓存写入数据来维持数据实时一致性。
RedisAnt 应用程序可以让自动化维护本地缓存变得非常容易。它免去了人工维护添加或更新数据的逻辑,只需要您为应用系统的目标客户定义数据来源, RedisAnt 就能自动完成本地缓存相关的其余操作。
这种基于火山引擎缓存数据库 Redis 企业版文档数据库 MongoDB 版构建 MongoDB 二级缓存来实现实时数据客户端访问的能力,在游戏场景中具备很高的实际应用价值。

方案架构

RedisAnt 架构主要包含服务端(RedisAnt server)和客户端(RedisAnt client)两个部分,其中:

  • RedisAnt server
    建立在 MongoDB 数据库之上的 RedisAnt server 会监控 MongoDB 的 OpLogs, 并将变更数据通过 Redis Pub/Sub 发布到 RedisAnt client。

  • RedisAnt client
    客户端启动时会从 MongoDB 数据库中拉取全量数据,并通过 Redis Pub/Sub 实时订阅数据更新,然后将变更数据写入 Redis 缓存中,便于前端服务通过 RedisJson 模块读取 JSON 数据。

RedisAnt 应用系统的架构设计如下图所示。

方案实现

准备工作

您需要提前准备如下资源并为各资源设置相关配置。

资源分类所需配置

ECS

在本文解决方案中需要准备如下 ECS 相关资源:

  1. 创建一个 ECS 实例。具体操作步骤,请参见购买并使用云服务器实例
  2. ECS 服务器上安装了 Go 和 Make 环境。

Redis

在本文解决方案中,RedisAnt server 和 RedisAnt client 均需使用 Redis 实例。因此您需要分别为 server 和 client 准备对应的 Redis 资源,其中:

  • RedisAnt server
    1. 创建一个缓存数据库 Redis 实例作为 RedisAnt server。具体操作步骤,请参见创建实例(社区版)或创建实例(企业版)。
    2. 为 Redis 实例设置访问白名单。具体操作步骤,请参见设置白名单(社区版)或设置白名单(企业版)。
    3. (可选)为 Redis 实例开启公网访问。开启公网访问的操作步骤,请参见开启公网访问(社区版)或开启公网访问(企业版)。
  • RedisAnt client
    1. 创建一个缓存数据库 Redis 企业版实例作为 RedisAnt client,并在创建 Redis 企业版实例时选择加载 RedisJSON 模块。具体操作步骤,请参见创建实例
    2. 为 Redis 企业版实例设置访问白名单。具体操作步骤,请参见创建白名单
    3. (可选)为 Redis 企业版实例开启公网访问。开启公网访问的操作步骤,请参见开启公网访问

说明

  • Redis 社区版和企业版实例均支持 Pub/Sub 功能,因此您可以任意选择 Redis 社区版或企业版实例作为 RedisAnt server;但仅 Redis 企业版支持 RedisJSON 模块,因此仅支持选择 Redis 企业版实例作为 RedisAnt client。
  • 本文解决方案对 Redis 社区版实例的数据库版本、实例类型、是否开启分片、节点规格等配置,以及 Redis 企业版实例的数据存储形态、规格等配置均未做具体要求,您可以根据业务需要自主选择。
  • Redis 社区版和企业版实例均默认提供了私网连接地址,若需要通过私网访问 Redis 实例,需确保 ECS 实例与 Redis 实例属于同一 VPC 网络;若需要通过公网访问 Redis 实例,需先为实例开启公网访问。

MongoDB

在本文解决方案中需要准备如下 MongoDB 相关资源:

  1. 创建一个文档数据库 MongoDB 版实例。具体操作步骤,请参见创建实例
  2. 为 MongoDB 实例设置访问白名单。具体操作步骤,请参见设置白名单
  3. (可选)为 MongoDB 实例申请公网连接地址。申请公网地址的操作步骤,请参见申请公网地址

说明

  • 本文解决方案对 MongoDB 版实例的数据库版本、实例类型、节点规格等配置未做具体要求,您可以根据业务需要自主选择。
  • MongoDB 版实例默认提供了私网连接地址,若需要通过私网访问 MongoDB 实例,需确保 ECS 实例与 MongoDB 实例属于同一 VPC 网络;若需要通过公网访问 MongoDB 实例,需先为实例申请公网连接地址。

操作步骤

  1. 登录已安装了对应 Go 和 Make 环境的 ECS 实例。

  2. 在 ECS 的命令行窗口或命令终端工具中,执行如下命令克隆代码。

    git clone https://github.com/redis-developer/redis-ant.git
    
  3. 进入 RedisAnt 项目(本文示例中 RedisAnt 项目目录的名称为 redis-ant,后续操作步骤均使用该目录),并在该项目的根目录下执行如下命令添加 Make 依赖。

    make setup
    
  4. 在 RedisAnt 项目中找到如下 4 个配置文件,并根据您的 Redis 和 MongoDB 实例的实际情况修改对应配置。

    1. redis-ant/cmd/redis-ant-server/main.go 文件
      文档数据库 MongoDB 版实例不支持 SRV 的连接方式,因此需要在 main.go 文件中的 mongoSTR 位置(文件中第 47 行代码),删除MongoDB 连接地址字符串中的 +srv 部分。
      修改前后的代码示例对比如下(如下代码仅展示了设置 MongoDB 连接地址的相关部分):

      • 修改前的代码
      mongoSTR := "mongodb+srv://" + config.Config.MongoUser + ":" + config.Config.MongoPass + "@" + config.Config.MongoURI
      
      • 修改后的代码
      mongoSTR := "mongodb://" + config.Config.MongoUser + ":" + config.Config.MongoPass + "@" + config.Config.MongoURI
      
    2. redis-ant/internal/mdb/mongoClient.go 文件
      需要在 mongoClient.go 文件中进行如下修改:

      • 文档数据库 MongoDB 版实例不支持 SRV 的连接方式,因此需要在 mongoClient.go 文件中的 connectionURI 位置(文件中第 39 行代码),删除MongoDB 连接地址字符串中的 +srv 部分。
      • 此外,为保证访问 MongoDB 实例时可以获取正确的身份验证凭据,还需要在因此需要在 mongoClient.go 文件中的 connectionURI 位置(文件中第 39 行代码),在MongoDB 连接地址字符串的末尾增加 authSource=admin 字段。

      修改前后的代码示例对比如下(如下代码仅展示了设置 MongoDB 连接地址的相关部分):

      • 修改前的代码
      func OpenConnection(URI, username, password string) *mongo.Client {
      // Step: Get the context with timeout
      ctx, cancel := context.WithTimeout(context.Background(), connectTimeout*time.Second)
      defer cancel()
      
      // Step: Create a connection string using credentials
      connectionURI := fmt.Sprintf("mongodb+srv://%s:%s@%s/test?retryWrites=true&w=majority", username, password, URI)
      
      • 修改后的代码
      func OpenConnection(URI, username, password string) *mongo.Client {
      // Step: Get the context with timeout
      ctx, cancel := context.WithTimeout(context.Background(), connectTimeout*time.Second)
      defer cancel()
      
      // Step: Create a connection string using credentials
      connectionURI := fmt.Sprintf("mongodb://%s:%s@%s/test?retryWrites=true&w=majority&authSource=admin", username, password, URI)
      
    3. redis-ant/env 文件
      env 文件中,分别为您的 MongoDB 实例、Redis 社区版实例(作为 RedisAnt server)、和Redis 企业版实例(作为 RedisAnt client)设置对应连接信息。

      export GLOBAL_REDIS_URL=<Redis 社区版实例的连接地址>:<Redis 社区版实例的端口,默认为 6379>
      export GLOBAL_REDIS_PASS=<Redis 社区版实例 default 账号的密码>
      export GLOBAL_REDIS_PORT=<Redis 社区版实例的端口,默认为 6379>
      
      export MONGO_URI=<MongoDB 实例完整连接地址串,包括域名和端口号信息>
      export MONGO_USER=<MongoDB 数据库账号,默认为 root>
      export MONGO_PASS=<MongoDB 数据库账号对应的密码>
      
      export client_REDIS_URL=<Redis 企业版实例的连接地址>:<Redis 企业版实例的端口,默认为 6379>
      export client_REDIS_PASS=<Redis 企业版实例 default 账号的密码>
      export client_REDIS_PORT=<Redis 企业版实例的端口,默认为 6379>
      

      代码示例如下。

      export GLOBAL_REDIS_URL=redis-cnlfqfxzk8zxt****.redis.volces.com:6379
      export GLOBAL_REDIS_PASS=Pwd_test****
      export GLOBAL_REDIS_PORT=6379
      
      export MONGO_URI=mongoshard40518f13****0.mongodb.volces.com:3717,mongoshard40518f13****1.mongodb.volces.com:3717
      export MONGO_USER=root
      export MONGO_PASS=Pwd_test****
      
      export client_REDIS_URL=redis-cnlftomq75f8p****.redis.volces.com:6379
      export client_REDIS_PASS=Pwd_test****
      export client_REDIS_PORT=6379
      

      说明

      • 您可以在 Redis 控制台上查看实例的连接地址域名和端口号;若您忘记 Redis 实例 default 账号的密码,您也可以在控制台上修改或重置密码。具体操作步骤,请参见:
      • 您可以在 MongoDB 控制台上查看实例的连接地址域名和端口号;您还可以控制台上为 MongoDB 实例创建数据库账号,具体操作步骤,请参见:
    4. redis-ant/ant_source.yml 文件
      ant_source.yml 文件中,将代码中的相关配置替换为您 MongoDB 数据库的真实设置。

      database: "<MongoDB 所用数据库的名称>"
      collection: "<MongoDB 所用集合的名称>"
      key_field: "<MongoDB 所用集合的索引字段>"  
      

      代码示例如下。

      database: "users"
      collection: "devices"
      key_field: "user_id"
      
  5. 在 RedisAnt 项目目录下,分别执行如下命令完成对应操作:

    1. 执行 make build 命令编译文件。
      编译完成后会得到两个新的可执行文件:redis-ant-clientredis-ant-server
      返回结果如下图所示。
    2. 执行如下命令应用 env 文件中设置的环境变量。
      source ./env
      
    3. 执行如下命令启动 RedisAnt client 服务。
      nohup ./bin/redis-ant-client &
      
    4. 执行如下命令启动 RedisAnt server 服务。
      nohup ./bin/redis-ant-server &
      

    说明

    后续再次使用 RedisAnt 应用时,仅需在 RedisAnt 项目下通过最后两个命令分别启动 RedisAnt client 和 RedisAnt server 服务即可。

后续操作

成功启动 RedisAnt client 和 RedisAnt server 服务后,您可以参考如下操作步骤进行数据验证:

  1. 连接 MongoDB 实例并在目标数据库中写入测试数据。
    具体操作步骤如下:

    1. 连接 MongoDB 实例。具体操作步骤,请参见通过 Mongo Shell 工具连接实例
    2. 在命令行中执行 use <数据库名称> 命令进入目标数据库。
      本文以 users 数据库为例,示例如下。
      use users
      
    3. 执行如下命令往 users 数据库中写入测试数据。
      db.devices.insert({"user_id": 1, "device_id": "Test", "consent": true})
      
      返回示例如下。
  2. 连接 RedisAnt client 所用的 Redis 企业版实例,并验证是否能查询到 MongoDB 中刚写入的测试数据。
    具体操作步骤如下:

    1. 连接 Redis 实例。具体操作步骤,请参见通过 Redis-cli 连接实例
    2. 在命令行中执行 json.get 1 名称查询数据,查看并对比返回结果是否与 MongoDB 中写入的测试数据一致。
      数据验证成功的返回示例如下。