在Amazon Cognito之上构建可扩展的用户搜索层
概述
Amazon Cognito 提供了强大的用户认证与管理功能,但在面对海量用户(例如成千上万的账户)时,其内置的 ListUsers API 在高级搜索场景(如模糊匹配、跨多个自定义属性的复杂过滤、亚秒级响应)下可能无法满足需求。本方案旨在通过构建一个独立的搜索层来解决这一问题,它能够实现实时数据同步与高性能查询,对于SRE快速定位用户、执行故障排查或支持团队响应工单至关重要。
核心概念
该架构是一个事件驱动的CQRS(命令查询职责分离)模式,通过两条数据流(摄入与搜索)将数据的写入与查询解耦。
- 数据摄入流:负责将 Cognito 中的用户变更实时同步到搜索索引中。它通过两种机制触发:
- Cognito Lambda 触发器:在用户认证流程的关键节点(如注册后的
PostConfirmation和每次登录前的PreTokenGeneration)捕获用户数据,并写入 DynamoDB。 - AWS CloudTrail 与 EventBridge:捕获通过控制台或CLI执行的管理员操作(如创建用户、更新属性),这些操作不会触发Lambda触发器。EventBridge 规则监听这些API调用,触发 Lambda 函数读取最新用户状态并更新 DynamoDB。
- Cognito Lambda 触发器:在用户认证流程的关键节点(如注册后的
- 搜索流:提供高性能的查询接口。经过身份验证的用户通过 API Gateway 提交查询请求,请求经由 Lambda 函数转发至 amazon-opensearch-service 执行搜索,最终将格式化后的结果返回前端。
DynamoDB 作为用户数据的权威记录存储和变更事件源(通过 DynamoDB Streams),而 OpenSearch Serverless 则提供强大的全文搜索与过滤能力。
实践
以下是构建此搜索层的详细步骤和关键设计点:
1. 数据同步与索引
- 创建 DynamoDB 用户表:存储用户配置文件的规范副本,包含
cognitoUserId(分区键)、email、lastName、groups、lastLoginTime等字段。启用 DynamoDB Streams 以捕获所有数据变更。 - 部署 Cognito 触发器 Lambda:
- 处理
PostConfirmation事件:在用户首次注册时,在 DynamoDB 表中创建初始记录。 - 处理
PreTokenGeneration事件:在每次用户登录时,更新lastLoginTime和使用的appClientId。 - 重要:此 Lambda 部署在 VPC 内,且 Cognito 强制其执行时间不超过5秒。需确保其逻辑高效,或使用预配置并发来避免冷启动延迟。
- 处理
- 配置 CloudTrail 与 EventBridge:
- 启用 CloudTrail 以记录 Cognito 的管理平面 API 调用。
- 创建 EventBridge 规则,匹配
source: ["aws.cognito-idp"]的事件,目标为另一个 Lambda 函数。 - 该 Lambda 函数接收到事件后,使用 Cognito Admin API 获取最新的用户属性,并将其写入 DynamoDB 表(覆盖或创建记录)。
- 构建索引管道:
- 为 DynamoDB 流配置一个事件源映射,触发
OSS-ingest-lambda。 OSS-ingest-lambda解析流事件(INSERT/MODIFY),从 DynamoDB 事件记录中提取新/旧图像数据,然后使用 OpenSearch 客户端将数据更新到 OpenSearch Serverless 索引中。
- 为 DynamoDB 流配置一个事件源映射,触发
2. 构建搜索 API
- 配置 OpenSearch Serverless:创建一个集合和索引,为用户数据字段(如
email,lastName,groups)定义合适的映射(例如,为email启用分词器以支持前缀匹配)。 - 部署搜索 Lambda:
- 通过 API Gateway 的 Cognito 授权器进行 JWT 验证。
- 该 Lambda 函数接收查询参数(如
q,filterGroups),构建 OpenSearch DSL 查询。 - 使用 AWS IAM 角色(具有只读权限)连接 OpenSearch Serverless,并执行查询。
- 处理分页(
from和size)并将结果格式化返回。
- 创建 API Gateway:配置 REST API,将搜索请求路由到搜索 Lambda 函数。
SRE 要点
- 与可靠性、可观测性的关联:
- 延迟与可用性:该架构的搜索性能(SLO:如99%的查询延迟<200ms)直接依赖于 OpenSearch Serverless 的性能和搜索 Lambda 的冷启动状态。应对 Lambda 启用 Provisioned Concurrency 来保障搜索端的低延迟。数据摄入路径的延迟(从Cognito事件到OpenSearch索引可见)是另一个关键的SLO。
- 数据一致性:摄入管道的事件驱动特性意味着数据最终一致。SRE 需要监控 DynamoDB Streams 的延迟和失败事件,以及 Lambda 执行失败率,以确保搜索索引与 Cognito 源数据保持同步。
- 最佳实践与常见反模式:
- 最佳实践:为 Cognito 触发器 Lambda 和搜索 Lambda 分别创建最小权限的 IAM 角色。使用指数退避重试来处理 OpenSearch 的
429错误。为 DynamoDB 表和 OpenSearch 索引启用自动备份。 - 常见反模式:不要在
PreTokenGeneration触发器中执行耗时操作(如复杂的外部API调用),这将导致认证超时。避免让索引管道依赖于单一区域的 DynamoDB Streams,以防区域性服务中断。
- 最佳实践:为 Cognito 触发器 Lambda 和搜索 Lambda 分别创建最小权限的 IAM 角色。使用指数退避重试来处理 OpenSearch 的
- 相关指标(SLI/SLO/SLA):
- 摄入 SLI:从 Cognito 事件发生到用户数据在 OpenSearch 中可搜索的端到端延迟。
- 摄入可靠性:DynamoDB 流处理失败率、Lambda 函数错误率。
- 搜索 SLI:搜索 API 的请求延迟(P90, P99)、成功率、查询吞吐量。
- 搜索准确性:关键业务查询(如按邮件前缀查找)返回预期结果的比率。
此架构通过将搜索能力从核心认证服务中解耦,为SRE和运维团队提供了一个可靠、高性能的工具,用于快速检索和排查用户账户相关问题。