头图
本文作者:有内鬼

背景介绍

1.2021年开始,社交直播活动中台因为需要支持的产品越来越多,优化过程中发现对于很多读场景来说中心缓存的读取已经成为了性能瓶颈,所以大量业务场景
开始采取二级缓存方案,将原来的中心 memcache 作为二级缓存,采用 guava、local memcache 作为一级缓存,来减少网络 IO、提升链路性能。

2.活动中台在发展过程中,因为需要支持多个产品,产品业务方的业务需求差异越来越大,统一运营后台已经无法满足业务方需求,于是决定将运营后台各业务线独立
应用开发维护,不再在领域服务中维护运营后台代码,并且拆离运营后台后也有利于领域服务稳定,但是这样就带来了不同应用清理缓存的问题。

3.常见的解决思路都是通过广播数据变更的思路去解决本地缓存更新的问题,如订阅数据库的 binlog ,基于注册中心响应方式。

首先我们决定采用的是订阅数据库表变更 binlog 广播消息的方案,当相关表发生变更后,通知所有相关领域服务,然后清理本地缓存。该种方案在实际使用一段时间后,
出现了一些问题:

运行层面上执行链路隐蔽,当出现缓存不一致问题时,很难快速定位到哪台实例的缓存是错误的。

代码层面上入口隐蔽,除了开发者团队其他成员无法快速得知相关缓存清理链路,导致维护成本越来越高。

运营后台随着不同业务独立开发后,各业务开发人员并不想再在运营后台工程中额外花费时间编写清理中心缓存的代码。

4.通过订阅数据库 binlog 方式的不良体验后,我们决定寻找更优雅的解决方案。首先调研了市面上的一些开源方案,发现都不尽满意:

中心缓存大多只支持 redis,并且依赖并不可靠的 pub / sub 不够健壮,并且团队使用的中心缓存是 memcache

框架年久失修、实现方式不优雅、不方便使用,模拟spring-cache的注解形式,同样会造成链路隐蔽的问题。

综上所述,团队决定自行开发一款能够应用于多级缓存一致性场景的框架,对这款框架的目标:

能够清晰的让团队成员了解所有缓存清理链路和多级缓存的使用情况,并且框架要足够简单易用,不会对团队成员使用造成困扰额外增加开发成本。

框架要足够健壮,首先要有异常重试机制,其次清理缓存的执行链路都要记录,便于排查问题。最后要能够支持更加复杂的业务场景,不限于只能支持二级缓存。

良好适配团队的技术栈。

详细设计

1.模型抽象

以一个最简单的二级缓存清理为例,当配置发生变更需要清理缓存时,需要先清理二级缓存即中心缓存,然后再清理一级缓存即本地缓存,整体链路可以抽象为一个单向链表。

一棵树在极端情况下会退化成一个链表,我们反向思考就代表我们可以将上面的单向链表复杂为一棵树,从而可以支持更加复杂的缓存清理场景。一个缓存清理事件不再只
清理一个中心缓存和一个本地缓存,层级也不再最多只能支持两层,理论上可以支持无数层。所以在缓存管道中,我们把缓存清理链路抽象为树结构,缓存清理事件作为树的
根节点,事件源下面是缓存清理链路的叶子节点,每条路径又可以看做一个单向链表。

2.缓存管道应用结构

缓存管道应用分为两大模块:节点发现模块、事件执行模块

节点发现模块:缓存管道通过监听固定zk路径下的变化事件,来维护执行缓存清理的节点信息,供执行缓存清理事件时使用。为了保证一致性,还会每隔一段时间全量
比对节点信息,保障节点信息的正确。

事件执行模块:当缓存管道接收到缓存清理事件后,会根据接收事件的编码,获取到由开发人员编排的缓存清理节点链路,根据链路结构通过长链接同步执行节点清理
缓存操作,失败后不会 fast-fail,会最多进行3次重试,完全失败后存入失败流水,供后续调度任务扫描继续重试。

3.执行节点

节点订阅与发现:引入缓存管道提供的执行器sdk包的领域服务,在启动过程中会向固定的 zookeeper 地址写入节点信息(所属事件源编码、ip、执行节点编码)。
缓存管道监听到该路径下的变化后,会在缓存管道的发现中心对节点信息进行维护,供后续清理缓存时调用。

节点调用与执行:缓存管道通过长链接与执行节点进行通信同步获得调用结果。调用节点分为两种策略,所有选一对应中心缓存的清理,在所有提供清理中心缓存清理功
能的节点中选取一个进行调用即可。第二种策略为选取所有对应本地缓存的清理,本地缓存的清理需要调用所有提供清理本地缓存的节点。

4.接入方式

缓存管道提供了两个 sdk,对应事件发送方和缓存清理执行方,让开发人员方便接入。

事件发送 sdk 一般接入方为缓存清理事件发起者,例如运营后台。当配置发生变更想要清理缓存时,直接调用提供的sdk即可产生缓存清理事件,然后由缓存管道去执行。

缓存清理执行 sdk 一般接入方为需要执行缓存清理的服务,即领域服务,他们在运行过程中会读缓存,当发生配置变更时,他们需要清理自己的缓存信息。

5.缓存事件节点结构配置

每个缓存清理事件都有自己唯一的事件编码,事件编码下就是不同缓存清理节点的节点编码结构关系。我们为这种关系维护提供了运营后台,开发人员可以在完成接入后在运营
后台自行编排缓存清理执行链路。这样所有开发人员也可在运营后台完全直观的看到所有多级缓存的缓存清理链路,不再隐藏在代码中。

缓存管道全景图

总结

社交直播缓存管道上线快1年时间,从派对房选取一个小业务作为试点开始,如今已经大规模应用在了社交直播活动业务中,很关键的支持了活动扩展点组件、活动交易平台的发展。
中间也经历过出海改造,海外配合降本部署方式从一个产品一个集群改造为一个机房一个集群。后续希望能够将该系统推广到更多的业务中去实践,让它继续发展。

云音乐社交直播活动中台技术团队,主要负责社交直播相关产品的活动、增值、营收类业务研发,为 Look 直播、声波、心遇、HeartUp 等相关产品提供一站式的活动中台解决方案,重点围绕着社交、直播场景营收增值活动架构体系中台化建设为方向。欢迎有兴趣的同学一起交流。

云音乐技术团队
3.6k 声望3.5k 粉丝

网易云音乐技术团队


引用和评论

0 条评论