我对 Canva 实时鼠标指针实现
Canva 的工程团队着手开发一种解决方案,用于处理同时进行设计的用户的实时鼠标指针交互。该解决方案需要支持每位用户每秒 3 次更新,单个设计最多可容纳 50 位用户,同时确保可扩展性和性能。
短期解决方案:以后端为中心的架构
最初,Canva 团队依靠 WebSockets 和 Redis 来实现实时更新。后端设计为无状态,Redis 充当消息代理。随着负载的增加,系统通过添加新的服务器实例进行水平扩展,每个实例管理 WebSocket 连接并通过 Redis 进行通信。然而,挑战在于平衡这些无状态实例之间的通信。
为了优化 Redis,他们使用 Redis Streams 来获取会话控制信息,使用 PubSub 来获取实时鼠标指针更新,从而为 PubSub 消息创建了一个专用的 Redis 实例。尽管存在一些限制,但该架构成功支持了每秒高达 100,000 次鼠标指针更新,即使在高峰使用率下,系统也能高效处理负载。关键优化包括对指针数据进行二进制编码和批量提交到 Redis,从而将后端和 Redis 的 CPU 负载降低了 30%。
然而,为了满足每个用户每秒 60 次更新的要求,需要一种新的解决方案。
长期解决方案:WebRTC 实施
长期愿景是转向基于 WebRTC 的解决方案,以减少后端负载并提高可扩展性。WebRTC 支持点对点通信,无需服务器往返。Canva 团队决定使用 WebRTC 在客户端之间直接发送序列化的鼠标指针数据,使用 WebSockets 进行信令并通过 STUN/TURN 服务器进行 NAT 遍历。
该系统采用网状拓扑结构进行 WebRTC 连接,每个用户都直接与其他用户连接,从而减少对后端的依赖。大约 50% 的连接是直接对等的,而其余连接在无法建立直接连接时则使用 TURN 服务器。WebRTC 解决方案虽然实施起来很复杂,但在处理高频更新方面提供了更好的可扩展性和效率。
主要见解:
要深入了解 Canva 使用的技术实现、挑战和优化策略,请阅读 Medium 上的完整博客!