Canva 的会话撤销难题

Canva 是一个在线设计平台,拥有数亿用户,每天产生海量会话。当用户注销、修改密码或管理员强制下线时,需要立即撤销这些会话,防止未授权访问。然而,在分布式系统中,会话数据分散在多个服务中,如何高效、可靠地撤销数亿个会话,是一个不小的挑战。

Canva 的工程师在 InfoQ 上分享了他们的解决方案:基于 Amazon S3 的架构。这个架构的核心思路是,将会话撤销信息存储到 S3 中,利用 S3 的高可用性和可扩展性,来管理大规模的会话撤销。

为什么选择 S3?

传统的会话管理通常使用 Redis 或数据库,但在数亿会话的规模下,这些方案会遇到瓶颈。Redis 虽然快,但内存有限,且需要处理持久化问题;数据库则可能成为性能瓶颈。S3 作为对象存储,具有几乎无限的容量和高持久性,适合存储不经常变动的数据。Canva 将撤销列表(即哪些会话需要被撤销)存储在 S3 上,每个会话有一个唯一的标识符,撤销时只需将标识符写入 S3 的某个对象中。

这种设计的好处是,S3 的读写操作是简单的 HTTP 请求,易于水平扩展,且成本相对较低。Canva 的架构师在分享中提到,他们利用 S3 的事件通知功能,在对象创建时触发后续处理,从而实现了异步的会话撤销。

架构如何工作?

具体来说,Canva 的架构分为几个部分:

  • 会话创建:用户登录时,生成一个会话 ID,并将会话数据存储在常规的会话存储中(如 Redis)。
  • 撤销请求:当需要撤销某个会话时,系统会生成一个撤销记录,包含会话 ID 和撤销时间,然后写入 S3 的一个特定前缀下。
  • 异步处理:S3 的对象创建事件会触发一个 Lambda 函数,该函数读取撤销记录,并通知相关的服务(如认证服务、API 网关)使该会话失效。
  • 定期清理:为了避免 S3 中积累过多过期记录,Canva 会定期清理旧的撤销记录。

这种设计将撤销操作从同步路径中解耦,使得撤销请求可以快速返回,而实际的会话失效在后台异步完成。这对于大规模系统来说非常重要,因为同步撤销数亿个会话可能会导致延迟和资源耗尽。

值得借鉴的思路

Canva 的案例展示了如何利用云原生服务(如 S3 和 Lambda)来解决大规模分布式系统中的实际问题。对于其他面临类似挑战的公司,这个架构有几点启示:

  • 利用对象存储的扩展性:当数据量巨大且访问模式简单时,对象存储可能比传统数据库更合适。
  • 异步化处理:将耗时的操作异步化,可以提高系统的响应速度和稳定性。
  • 事件驱动架构:通过事件触发后续处理,可以灵活地扩展功能,而不需要修改核心系统。

当然,这个方案也有其适用场景。如果会话撤销需要实时生效,那么异步处理可能不适用。Canva 的架构师在分享中也提到,他们权衡了实时性和扩展性,最终选择了这种折中方案。

总的来说,Canva 的 S3 会话撤销架构是一个值得关注的技术实践,它为大规模分布式系统的会话管理提供了一种新的思路。

参考来源