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

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

在中配置服务器端缓存和 API 有效负载压缩 Amazon AppSync

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

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

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

实例类型

Amazon AppSync 将亚马逊 ElastiCache (Redis OSS) 实例托管在与您的 Amazon AppSync API 相同的 Amazon 账户和 Amazon 区域中。

有以下 ElastiCache (Redis OSS)实例类型可供选择:

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 月起,这些旧实例类型可以继续使用,但将弃用这些实例类型而不建议使用。我们建议您使用此处描述的通用实例类型。

缓存行为

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

没有服务器端缓存。

完整请求缓存

完全请求缓存是一种单独缓存解析器执行结果的机制。使用此设置, Amazon AppSync 缓存请求期间调用的所有解析器的执行,每个解析器都单独缓存。每个解析器的数据均从其数据源中检索,并填充缓存,直到存活时间 (TTL) 到期。对于后续的 API 请求,将从缓存中返回每个特定解析器的结果。这意味着,除非TTL已过期,否则不会直接联系数据源。 Amazon AppSync 使用context.argumentscontext.identity映射的内容作为每个解析器的缓存密钥。

每个解析器的缓存

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

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

  • context.argumentscontext.source

  • context.argumentscontext.identity.sub

  • context.arguments.id 或上下文参数。 InputType.id

  • context.source.idcontext.identity.sub

  • context.identity.claims.username

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

操作级别缓存

操作级缓存将整个 GraphQL 查询操作响应作为一个整体存储。启用后,成功的查询响应会被缓存到其 TTL 到期,可缓存的最大响应大小为 15 MB。对于后续使用相同缓存密钥的查询请求,将直接从缓存中提供响应,在 TTL 未过期时不执行任何解析器。

操作级缓存的缓存密钥是使用以下各项的组合生成的:

  • 请求的 JSON 负载中的某些属性:

    • 这个query字符串

    • 这个operationName字符串

    • variables张地图

  • context.identity地图(不包括 context.identity.sourceIp IAM 和 Amazon Cognito 请求)

  • context.request.headers地图(不包括下一节中列出的某些保留标题)

请求使用的授权类型也会影响缓存密钥。对于 IAM 授权的请求,缓存密钥还将包括允许和拒绝的资源列表。对于 Lambda 授权的请求,缓存密钥还将包括被拒绝的字段列表。

缓存密钥将考虑中找到的所有请求标头context.request.headers,但以下保留标头除外,这些标头通常是特定请求所独有的:

  • authorization

  • cloudfront-forwarded-proto

  • cloudfront-is-desktop-viewer

  • cloudfront-is-mobile-viewer

  • cloudfront-is-smarttv-viewer

  • cloudfront-is-tablet-viewer

  • cloudfront-viewer-asn

  • cloudfront-viewer-country

  • content-length

  • host

  • priority

  • sec-ch-ua

  • sec-ch-ua-mobile

  • sec-ch-ua-platform

  • viax-amz-cf-id

  • x-amz-date

  • x-amz-security-token

  • x-amzn-appsync-is-vpce-request

  • x-amzn-remote-ip

  • x-amzn-requestid

  • x-amzn-trace-id

  • x-forwarded-for

缓存生存时间

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

缓存加密

当您使用 Amazon AppSync服务器端数据缓存功能时,静态和传输中的加密将始终为新缓存启用,并且无法禁用。

要对现有 API 缓存启用加密,请删除缓存,然后重新创建。

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

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

缓存逐出

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

逐出缓存条目

要从缓存中逐出项目,请使用 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] 组成。

当你尝试获取 a 时Note,为了构建缓存密钥,使用getNote查询的id参数在其服务器端缓存中 Amazon AppSync 执行查找。

在您更新 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) { return update({ key: { id: ctx.args.id }, update: { context: ctx.args.content } }); } export function response(ctx) { extensions.evictFromApiCache('Query', 'getNote', { 'ctx.identity.username': ctx.args.username, 'ctx.args.id': ctx.args.id, }); return ctx.result; }

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

压缩 API 响应

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

注意

2020 年 6 月 1 日之后 APIs 创建的所有新版本均可进行压缩。

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

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

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