服务器 频道

货拉拉缓存中间件建设之路--DataMesh架构探索与创新历程

  缓存有什么作用?当一个服务达到瓶颈时,必然会引入缓存提高性能。而当缓存自身达到瓶颈时,就需要建设缓存的集群管理能力。

  对于任何一家互联网企业,访问量达到一定规模后,缓存组件必然会面对极大的挑战。所以,建设稳定的缓存集群管理能力,资源交付能力,确保并发数持续增长下,缓存组件能够稳如泰山,是企业技术发展的重中之重。

  一、背景

  前几年,随着货拉拉业务的稳步增长,基础资源使用量也在持续扩张,缓存架构面临了不小的挑战。

  服务用量持续上升,集群快速水平扩容需要解决;新服务快速增加,需要有更快的资源交付能力;业务越来越多元化,缓存使用场景更加复杂,需要集群和数据治理能力;强依赖缓存的服务越来越多,单集群爆炸半径变大,稳定性面临挑战。另外,货拉拉依然处于PHP服务向Java改造的阵痛期,多语言带来的难题也急需解决。

  为了解决这些难题,缓存架构经历了几次架构演进。从单点主从到Codis、哨兵模式,并最终整合为RedisCluster集群模式,之后又引入了DataMesh中间件,提高集群稳定性,引入数据治理手段。无论是资源管理还是稳定性层面,都得到了非常大的提升。

  二、面临挑战

  我们对缓存组件的要求,是需要至少兼备以下四种能力:

  首先,访问延迟极低。缓存作为响应时间敏感的数据产品,要求响应时间需要不高于10ms,这是上限。平均延迟在2ms以下。

  高可用方面,缓存服务要求SLA要求是99.999%,这意味着一年的周期里,只能停顿5分钟,发生故障时几秒内恢复。

  尽量降低非逻辑性质的研发投入,弱化对定制client的依赖。

  同时,还需要适配多种业务场景,比如分布式锁等。

  这些能力要求,给我们带来了很多方面的挑战。

  架构高可用挑战

  Redis常用的高可用方案有这四种模式,单点的主从、哨兵模式管理集群、Redis Cluster模式和部署Codis proxy。

  •主从模式,可以解决单点故障,故障需要人工干预,显然达不到秒级恢复的要求。

  •哨兵模式解决了主从切换的问题,而且水平扩展很方便,但部署较为复杂,需要维护哨兵集群。

  •Codis通过部署proxy解决管理集群,而且有可视化Dashboard,缺点是会多一层网络消耗。

  同时,哨兵和Codis部署方式相当高可用强依赖第三方组件。

  相比之下,我们选择了,去中心化的Redis Cluster,依赖集群本身gossip维护集群,同样支持集群线性调整。当然Redis Cluster也有缺点,需要有智能客户端。

  资源交付效率

  解决了高可用,在运维方面,我们的交付、扩缩容、数据治理都依赖数据管控平台。这三个场景基本覆盖了DB运维的大部分场景。DBA在资源创建前就初始化了无状态缓存节点并加入资源池,资源申请阶段只需要根据调度算法选出散列节点,组成集群。意味着我们有更快速的集群创建能力。资源池调度算法可以保证主节点散列,集群更健壮。

  扩缩容和故障迁移能力依赖Redis Cluster本身的 migrate,在DB管控系统实现了slot迁移,节点扩容脚本自动化。

  数据治理方面,缓存会做定期RDB,数据持久化到云盘,做数据备份,以及全量Key分析,筛选出流量热点。

  三、DataMesh建设历程

  依托于Redis Cluster我们搭建了稳定性强,运维简便的缓存架构。但是实际使用中还存在很多痛点。比如,容灾迁移有些场景需要客户端感知,数据治理只在DB层面,缺乏客户端侧的数据,还有缺乏DB保护措施等等。

  为了解决这些问题,我们尝试探索了DataMesh架构。

  DataMesh是什么?

  DataMesh本质上,是一层Redis代理。我们在接入层和数据产品层之间,以Sidecar的方式部署了DataMesh 。

  DataMesh代理缓存请求,提供了数据分片、限流、集群切换等能力。

  它的整体部署架构如下图展示

  DataMesh Sidecar依赖发布系统跟随APP拉起,通过K8S服务平台管理版本。服务发现依赖于配置中心,同时对监控平台输出缓存性能数据。

  为什么用Sidecar方式部署?

  首先,最关键的,速度快。Sidecar代理走回环网络,不会带来额外网络消耗,平均处理延迟只有0.02毫秒,对响应速度要求极高的缓存系统非常友好。其次,依靠K8S调度系统,管理sidecar生命周期,减少了维护agent的成本。同时K8S提供了可靠的资源隔离,sidecar不会影响服务本身,且自身的资源占用维持在预期水位内。DataMesh本身资源占用也极小,单个POD平均资源占用小于0.1核。

  DataMesh部署架构

  这里是DataMesh在K8S的部署结构

  Deamonset负责管理执行文件和配置文件,POD内,DataMesh Container内启动代理进程和守护进程。Sidecar和Deamonset挂载相同的宿主机目录,来实现文件发布和进程发布分离。这个架构支撑DataMesh可以在流量不间断的情况下发布。

  流量不间断升级特性

  K8S集群中,一个Node通常有几十甚至上百POD在运行,如果每个POD单独升级Sidecar,会导致瞬时网络流量飙升,如果分批升级,又会把升级时间窗口拉的很长。所以我们设计了配置升级与进程升级隔离的发布方式,由Deamonset进程维护配置和执行文件版本。完成后发布系统定义POD分组,做分批发布。进程发布由发布系统触发通知守护进程,守护进程拉起新代理进程,并平滑关闭老进程。

  不间断升级对DataMesh架构有非常重要的意义。他允许我们在版本向下兼容的情况下不需要中断服务而实现升级。

  四、最终收益

  功能收益

  1.智能代理

  对于客户端侧,提供了Smart Client,动态监听slot迁移,主从切换等集群变更,更新集群拓扑,命令重发,实现请求不中断。同时支持多个分片下的请求pipeline。

  2.集群迁移

  智能集群迁移,是当缓存集群遭到灾难性破坏,导致整个集群不可用的时候,可以通过运维事件变更,动态切换到新的缓存集群,这是依赖datamesh前后端连接分离,新集群连接创建后即自动恢复。

  3.数据治理

  很多场景下,缓存作为关系型数据库的保护层,如果缓存崩塌了,意味着流量攻击可能会由数据库承担。在这方面,DataMesh做了连接收敛,前后端连接隔离,来降低缓存产品的连接压力。同时,datamesh代理时会做热key分析,上报热点key的qps和payload,再配合DataMesh的key级别的限流、降级功能,解决热Key问题。

  智能运维体系

  依托DataMesh中间件的管控系统,货拉拉搭建了事件驱动的高效运维模型。DBA可以根据DataMesh的能力约定变更手段,比如热Key降级,集群迁移、扩缩容等等。

  当监控平台上报事件告警的时候,DBA运维可以发起变更,DataMesh控制台会将变更事件下发到对应节点,从而触发限流/降级等操作。DataMesh控制台会监控变更事件状态,用于溯源。最终变更效果反馈在监控系统中。

  我们可以发现,这套流程完全不需要缓存使用方参与。因为这套体系下,所有触发的动作都是DataMesh和DB运维平台约定的。对于客户端来说,缓存的运维体系是个黑盒,所有变更不需要担心重启,DataMesh可以保障自动恢复,这是缓存运维能力极大的提升。

  五、发展规划

  总结一下,货拉拉的缓存体系经历了数代变革,最终敲定Redis Cluster部署模式,并在此基础上引入DataMesh中间件架构,简化接入成本,补足运维能力。

  DataMesh是一个新型的技术理念,经过我们在缓存上的实践验证,取得结果还是很理想的。DataMesh的编程能力,补足了很多运维上的盲点。我们对它的期望,不仅局限于Redis,未来会提供Mysql、MQ等多种基础组件的代理,以及管理能力。

0
相关文章