亚马逊AWS官方博客

DynamoDB 设计与建模最佳实践之 AI 数字人场景

互联网浪潮中,科技改变生活,真切地让我们感受到工作的提效,生活的便利,娱乐的多样化。伴随更多的业务需求和极速的系统膨胀,作为核心价值的数据存储方案设计,也变得越发重要,NoSQL(Not only SQL)也逐渐深入人心。亚马逊云科技秉承专门构建的理念,为客户提供完整的云原生数据战略体系,为不同业务类型,提供最优解。

1. Why DynamoDB

自 2007 年的第一篇“Dynamo 研究论文”,到 2012 年 Amazon DynamoDB 服务的推出。现在,亚马逊云科技在大型非关系数据库和云服务技术领域 18 年持续投入,带给我们一款为互联网规模的应用程序而生,快速、高度可靠且具有成本效益的 NoSQL 数据库服务。

Amazon DynamoDB 是一种完全托管式、无服务器的 NoSQL 键值数据库,旨在运行任何规模的高性能应用程序。每天持续处理超过 10 万亿个请求。且可提供无限的可扩展性,稳定的个位数毫秒级性能和高达 99.999% 的可用性。

基于 DynamoDB 的能力和使用场景,如何以最佳实践的方式在 AI 场景发挥作用,是很多客户关心的话题。

2. 业务场景描述

AIGC(AI-Generated Content,人工智能生成内容)风靡全球,而 LLM(Large Language Model)创造力和智慧是最惊艳的部分。但是在工程化的过程中,我们希望数字人可以有“记忆”,来延续对话的上下文。那么会话的记忆存储,就需要一个可以承载高并发,低延迟的数据库来支撑业务。

2.1 架构图详解

根据业务需求,将大语言模型 Bedrock Claude2 和 Amazon DynamoDB 结合,来实现智能“问答”和“记忆”。

问答流程:

  1. user 发起访问
  2. 基于 Amazon Elastic Kubernetes Service(Amazon EKS)运行的 AI 数字人应用,接收对话请求
  3. APP 查询 DynamoDB 会话的历史记录,并结合当前会话内容,整合信息
  4. 发送整合后信息到 Bedrock Claude2,获取“回答”
  5. APP 发送“回答”给 user

3. 数据查询/存储方案

在理清业务需求和技术实现架构之后,我们需要针对会话历史信息的存储和查询,进行详尽的技术拆解。

3.1 表设计和实体关系详解

  • 聊天会话表用于记录用户和 AI 数字人之间的聊天 ID(chat_id)。
  • 应用程序会根据用户 ID(user_id)和 AI 数字人(ai_id),获取当前#ACTIVE#的 chat_id。
  • 用户可以选择删除旧的 chat_id(软删除,在数据库要保留这条记录,通过 delete_time 时间戳等信息来表示历史聊天)。
  • 用户也可以重启聊天会话,同时删除旧的聊天会话,创建一个新的聊天会话。
  • 因此,一个用户跟 AI 数字人之间允许有多条聊天会话记录,但是同一时间有且仅有一条处于活跃状态#ACTIVE#的聊天会话记录。

3.1.1 ERD(数据库实体关系图)

涉及的实体包括:用户(user_id),AI 数字人(ai_id),聊天会话(chat_id)
用户跟 AI 数字人之间是多对多的关系:

  • 用户可以跟多个 AI 数字人存在多条聊天会话记录;
  • AI 数字人也可以跟多个用户存在多条聊天会话记录;

3.1.2 访问模式(聊天会话的增删改查)

  • 创建新的聊天会话 – CreateChat
  • 获取指定聊天会话 – GetChatByUser_Id_and_AI_Id
  • 删除聊天会话 – DeleteChat
  • 重启聊天会话 – RenewChat
  • 更新指定会话 AI_Version – UpdateAIVersionByChat_Id

4. DynamoDB 数据建模&表格设计

4.1 表格设计

我们需要一个基表存储数据,同时需要一个 GSI(Global Secondary Index)辅助查询。

  • 基表名称:chat_session
  • 全局二级索引名称:GSI1_chat(选择 Keys_Only 模式)

表格定义:

4.2 表格设计技巧

DynamoDB 是一个全托管,且简单易用的数据库。但是如何发挥其性能优势,也是需要我们知其善用。
这里我们就罗列一些小技巧:

  • 有效利用 DynamoDB 排序键的特性:
    例如标记活跃状态的 SK 前缀是#ACTIVE#,以#字符开头,让这条记录在排序过程中保持置顶。
  • 兼顾业务和技术的 Key 设计:
    场景 1. chat_id,我们可以使用 ULID (一种全局唯一且可以按字典序排序的标识符格式),其比随机 UUID 增加了时间戳,查询性能会更好。
    场景 2. 在以 user_id & ai_id 作为查询条件,且以时间维度排序所有历史聊天会话的场景,ULID 就可以提供更好的查询性能。

4.3 表数据样例

  • 基表插入数据后的样式
  • GSI 的数据样式

5. 访问模式实现

在完成表格设计之后,如何消费数据,以满足业务需求? 后续内容会详细介绍。

5.1 创建新的聊天会话 – CreateChat

在基表 chat_session 上执行 putItem 操作,通过条件判断表达式(ConditionExpression),确定当前表中不存在这条记录,才执行写入新的聊天会话。如果条件判断检查失败,则返回应用端 ConditionalCheckFailedException,表示数据库中存在这条记录。需要应用端做业务逻辑判断再操作。

put_item_params = {
    'TableName': 'chat_session',
    'Item': {
        'PK': {'S': user_id},
        'SK': {'S': '#ACTIVE#' + ai_id},
        'chat_id': {'S': chat_id},
        'create_time': {'S': create_timestamp},
        'GSI1PK': {'S': chat_id}
    },
    'ConditionExpression': 'attribute_not_exists(PK) AND attribute_not_exists(SK)'
}

5.2 获取指定聊天会话 – GetChatByUser_Id_and_AI_Id

在基表 chat_session 上执行 getItem 操作,指定 PK=user_id and SK=#ACTIVE#ai_id,获取返回结果。

5.3 标记删除聊天会话 – DeleteChat

组合操作完成这个场景,首先 getItem 获取到当前活跃聊天会话记录的所有属性。然后事务写入,插入一条有 delete_time 的历史会话记录,并删除当前活跃聊天会话记录。相关步骤参数见下面:

第一步:getItem PK=user_id and SK=#ACTIVE#ai_id, 可以复用上面的 getChatByUser_id_and_ai_id 函数。获取到这条 Item 所有信息记录下来。

第二步:事务写入
putItem PK=user_id and SK=ai_id#OLD#chat_id,其他属性包括 chat_id, ai_version,create_time,delete_time.
deleteItem PK=user_id and SK=#ACTIVE#ai_id

5.4 重新启动聊天会话 – RenewChat

组合操作完成这个场景,跟上面软删除很类似,只是在事务写入时候,使用 updateItem。首先 getItem 获取到当前活跃聊天会话记录的所有属性。然后事务写入,插入一条有 delete_time 的历史会话记录,然后更新当前活跃聊天会话记录,为最新的 ai_version,chat_id。相关步骤参数见下面:

第一步:getItem PK=user_id and SK=#ACTIVE#ai_id, 可复用 getChatByUser_id_and_ai_id 函数。获取到这条 Item 所有信息记录下来。

第二步:事务写入
putItem PK=user_id and SK=ai_id#OLD#chat_id,其他属性包括 chat_id,ai_version,create_time,delete_time
updateItem PK=user_id and SK=#ACTIVE#ai_id,其他属性包括 chat_id,ai_version,create_time,GSI1PK

5.5 更新指定会话 AI_Version – UpdateAIVersionByChat_Id

第一步:GSI1_chat 中 getItem PK=chat_id;拿到基表的 PK,SK
第二步:基表 chat_session 中 updateItem,PK=user_id,SK=#ACTIVE#ai_id

5.6 访问模式和实现方法汇总

为便于理解,我们将前面的访问模式,结合具体的实现方法,通过表格的形式进行汇总。

总结

通过以上内容,我们希望你理解“专门构建”的含义,不再根据数据库设计业务,而是通过业务选择适合的数据库。在类似场景下,DynamoDB 作为 Key-Value 数据库,可以充分发挥高并发、低延迟、高稳定性的特点,支撑核心业务的稳定运行。也希望通过本文,带来更清晰的 DynamoDB 的建模方法、建表模式,以及高性能查询的最佳实践。


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

参考链接

  1. Amazon DynamoDB
  2. Gaming profile schema design in DynamoDB

本篇作者

许晓亮

亚马逊云科技解决方案架构师,负责基于亚马逊云科技云计算方案架构的咨询和设计,在国内推广亚马逊云科技云平台技术和各种解决方案。擅长数据库和大数据领域,结合云原生特性,为客户设计高效稳定的全球化系统方案。

李君

亚马逊云科技数据库解决方案技术专家,负责基于亚马逊云计算数据库产品的技术咨询与解决方案工作,特别专注于从 SQL 到 NoSQL 数据库的设计、测试、迁移、运维及优化等工作。