缓存和压缩 - Amazon AppSync
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

缓存和压缩

Amazon AppSync 的服务器端数据缓存功能在内存缓存中高速提供数据,从而提高性能并减少延迟。这减少了直接访问数据源的需求。缓存适用于单位解析器和管道解析器。

Amazon AppSync 还允许您压缩 API 响应,以便更快地加载和下载负载内容。这可能会减轻应用程序的压力,同时还可能会降低数据传输费用。压缩行为是可配置的,您可以自行决定进行设置。

请参阅本节以帮助在 Amazon AppSync API 中定义所需的服务器端缓存和压缩行为。

实例类型

Amazon AppSync 在与您的 Amazon AppSync API 相同的 Amazon 账户和 Amazon 区域中托管 Amazon ElastiCache for Redis 实例。

可以使用以下 ElastiCache for Redis 实例类型:

small

1 个 vCPU、1.5 GiB RAM、低到中网络性能

medium

2 个 vCPU、3 GiB RAM、低到中网络性能

large

2 个 vCPU、12.3 GiB RAM,高达 10 Gb 网络性能

xlarge

4 个 vCPU、25.05 GiB RAM,高达 10 Gb 网络性能

2xlarge

8 个 vCPU、50.47 GiB RAM,高达 10 Gb 网络性能

4xlarge

16 个 vCPU、101.38 GiB RAM,高达 10 Gb 网络性能

8xlarge

32 个 vCPU、203.26 GiB RAM、10 Gb 网络性能(并非在所有区域中都提供)

12xlarge

48 个 vCPU、317.77 GiB RAM、10 Gb 网络性能

注意

过去,您指定了特定的实例类型(例如 t2.medium)。自 2020 年 7 月起,这些旧实例类型可以继续使用,但将弃用这些实例类型而不建议使用。我们建议您使用此处描述的通用实例类型。

缓存行为

以下是与缓存相关的行为:

没有服务器端缓存。

完整请求缓存

如果数据没有位于缓存中,则会从数据源中检索数据并填充缓存,直到生存时间 (TTL) 到期。对您的 API 的所有后续请求都从缓存中返回。这意味着除非 TTL 到期,否则,不会直接连接到数据源。在该设置中,我们将 context.argumentscontext.identity 映射的内容作为缓存键。

每个解析器的缓存

对于该设置,必须明确选择每个解析器以缓存响应。您可以在解析器上指定 TTL 和缓存键。您可以指定的缓存键是顶级映射 context.argumentscontext.sourcecontext.identity 以及/或者这些映射中的字符串字段。TTL 值是必需的,但缓存键是可选的。如果您未指定任何缓存键,则默认值是 context.argumentscontext.sourcecontext.identity 映射内容。

例如,您可以使用以下组合:

  • context.argumentscontext.source

  • context.argumentscontext.identity.sub

  • context.arguments.idcontext.arguments.InputType.id

  • context.source.idcontext.identity.sub

  • context.identity.claims.username

在您仅指定 TTL 而没有指定缓存键时,解析器的行为与完整请求缓存相同。

缓存生存时间

该设置定义在内存中存储缓存条目的时间。最大 TTL 为 3,600 秒(1 小时),之后自动删除条目。

缓存加密

缓存加密具有以下两种形式。这些与 ElastiCache for Redis 允许的设置类似。只有在首次为 Amazon AppSync API 启用缓存时,您才能启用加密设置。

  • 传输中加密 - Amazon AppSync、缓存和数据源(不安全的 HTTP 数据源除外)之间的请求在网络级别进行加密。由于在终端节点中加密和解密数据需要进行一些处理,因此,传输中加密可能会影响性能。

  • 静态加密 - 在交换操作期间从内存保存到磁盘的数据在缓存实例中进行加密。该设置也会影响性能。

要使缓存条目无效,您可以使用 Amazon AppSync 控制台或 Amazon Command Line Interface (Amazon CLI) 进行刷新缓存 API 调用。

有关更多信息,请参阅 Amazon AppSync API 参考中的 ApiCache 数据类型。

缓存逐出

在您设置 Amazon AppSync 的服务器端缓存时,您可以配置最大 TTL。该值定义在内存中存储缓存条目的时间。在必须从缓存中删除特定条目的情况下,您可以在解析器的请求或响应中使用 Amazon AppSync 的 evictFromApiCache 扩展实用程序。(例如,如果数据源中的数据发生变化,并且缓存条目现已过时。) 要从缓存中逐出某个项目,您必须知道该项目的键。因此,如果您必须动态逐出项目,我们建议使用每个解析器的缓存,并明确定义一个用于将条目添加到缓存的键。

逐出缓存条目

要从缓存中逐出项目,请使用 evictFromApiCache 扩展实用程序。指定类型名称和字段名称,然后提供一个键值项目对象以构建要逐出的条目的键。在该对象中,每个键表示 context 对象中的一个有效条目,该条目在缓存解析器的 cachingKey 列表中使用。每个值是用于构建键值的实际值。您必须按照与缓存解析器的 cachingKey 列表中的缓存键相同的顺序,将项目放入对象中。

例如,请参阅以下架构:

type Note { id: ID! title: String content: String! } type Query { getNote(id: ID!): Note } type Mutation { updateNote(id: ID!, content: String!): Note }

在该示例中,您可以启用每个解析器的缓存,然后为 getNote 查询启用该功能。接下来,您可以将缓存键配置为由 [context.arguments.id] 组成。

在您尝试获取 Note 以构建缓存键时,Amazon AppSync 使用 getNote 查询的 id 参数在其服务器端缓存中执行查找。

在您更新 Note 时,您必须逐出特定注释的条目,以确保下一个请求从后端数据源中获取该注释。为此,您必须创建一个请求处理程序。

以下示例说明了一种使用该方法处理逐出的方法:

import { util, Context } from '@aws-appsync/utils'; import { update } from '@aws-appsync/utils/dynamodb'; export function request(ctx) { extensions.evictFromApiCache('Query', 'getNote', { 'ctx.args.id': ctx.args.id }); return update({ key: { id: ctx.args.id }, update: { context: ctx.args.content } }); } export const response = (ctx) => ctx.result;

或者,您也可以在响应处理程序中处理逐出。

在处理 updateNote 变更时,Amazon AppSync 尝试逐出条目。如果成功清除条目,响应将在 extensions 对象中包含一个 apiCacheEntriesDeleted 值,以显示删除的条目数:

"extensions": { "apiCacheEntriesDeleted": 1}

根据身份逐出缓存条目

您可以根据 context 对象中的多个值创建缓存键。

例如,采用以下架构,该架构将 Amazon Cognito 用户池作为默认身份验证模式并由 Amazon DynamoDB 数据源提供支持:

type Note { id: ID! # a slug; e.g.: "my-first-note-on-graphql" title: String content: String! } type Query { getNote(id: ID!): Note } type Mutation { updateNote(id: ID!, content: String!): Note }

Note 对象类型保存在 DynamoDB 表中。该表具有一个组合键,该组合键将 Amazon Cognito 用户名作为主键,并将 Noteid(短标签)作为分区键。这是一个多租户系统,允许多个用户托管和更新他们的私有 Note 对象,这些对象从不进行共享。

由于这是一个读取密集型系统,因此,getNote 查询使用每个解析器的缓存进行缓存,缓存键由 [context.identity.username, context.arguments.id] 组成。在更新 Note 后,您可以逐出该特定 Note 的条目。您必须按照解析器的 cachingKeys 列表中指定的相同顺序将组件添加到对象中。

以下示例说明了这一点:

import { util, Context } from '@aws-appsync/utils'; import { update } from '@aws-appsync/utils/dynamodb'; export function request(ctx) { extensions.evictFromApiCache('Query', 'getNote', { 'ctx.identity.username': ctx.identity.username, 'ctx.args.id': ctx.args.id, }); return update({ key: { id: ctx.args.id }, update: { context: ctx.args.content } }); } export const response = (ctx) => ctx.result;

后端系统也可以更新 Note 并逐出条目。例如,采用以下变更:

type Mutation { updateNoteFromBackend(id: ID!, content: String!, username: ID!): Note @aws_iam }

您可以逐出条目,但将缓存键的组件添加到 cachingKeys 对象中。

在以下示例中,逐出是在解析器响应中进行的:

import { util, Context } from '@aws-appsync/utils'; import { update } from '@aws-appsync/utils/dynamodb'; export function request(ctx) { extensions.evictFromApiCache('Query', 'getNote', { 'ctx.identity.username': ctx.args.username, 'ctx.args.id': ctx.args.id, }); return update({ key: { id: ctx.args.id }, update: { context: ctx.args.content } }); } export const response = (ctx) => ctx.result;

如果已在 Amazon AppSync 外部更新您的后端数据,您可以调用使用 NONE 数据源的变量以从缓存中逐出项目。

压缩 API 响应

Amazon AppSync 允许客户端请求压缩的负载。如果请求,将压缩并返回 API 响应,以响应指示希望压缩内容的请求。压缩的 API 响应加载速度更快,内容下载速度更快,并且您的数据传输费用也可能会下降。

注意

压缩适用于在 2020 年 6 月 1 日之后创建的所有新 API。

Amazon AppSync 尽力压缩对象。在极少数情况下,Amazon AppSync 可能会根据多种因素(包括当前容量)跳过压缩。

Amazon AppSync 可以将 GraphQL 查询负载大小压缩到 1,000 到 10,000,000 字节之间。要启用压缩,客户端必须发送具有 gzip 值的 Accept-Encoding 标头。可以检查响应 (gzip) 中的 Content-Encoding 标头值以验证压缩。

默认情况下,Amazon AppSync 控制台中的查询浏览器自动设置请求中的标头值。如果您执行的查询具有足够大的响应,可以使用浏览器开发人员工具确认压缩。