一.配置的那些事儿
1.业务背景
作为大型复杂分布式系统,微博平台中存在大量的配置信息,这些配置信息定义了平台中的RPC服务和资源(memcached、redis、mysql等)的地址,以及这些服务和资源的元数据信息。
在微博早期,配置信息散落在工程的代码中,这种方式简单方便,但是微博平台系统规模扩大和业务部署复杂度的提升带来了一些问题:
服务按照业务和重要程度部署在多个池子,不同池子的配置信息不同。
服务多机房部署,不同机房的配置信息也不同。
开发、测试以及上线部署的配置信息亦不同。
为了解决以上问题,微博平台对配置做了一次大规模调整,将代码和配置分离,配置按照机房、业务池以及环境拆分,并且存储在本地文件系统中约定的位置。分离之后,各业务池、各机房的配置更加灵活,也为配置向 config service迁移提供了条件。
随着微博平台服务器规模的持续增长,RPC服务和资源的故障和变更已经变为一种常态,在日常维护过程中,经常会遇到以下场景:
某一组memcacheq资源突然流量猛增,需要快速扩容
某一redis资源访问过载,需要立即降级调用它的服务
而现有的解决方案无法解决这些问题,我们迫切需要一个分布式环境下的持久配置系统,提供高效的配置注册获取和及时变更通知服务,于是vintage(config service在微博内部的代号)应运而生。
2.vintage
Vintage是典型的基于pub-sub模型的通讯框架,在业界类似的系统很多,比如淘宝的diamond和软负载中心,zookeeper在某些系统中(如kafka)也扮演着类似的角色。
Vintage 将信息集中管理在云端,并且提供实时的变更通知。Vintage主要应用于两种主要场景:配置管理和命名管理,配置管理主要维护静态配置数据(如服务超时时间、降级开关状态);命名管理主要维护RPC服务地址信息。两种场景看起来极为相似,但是也存在如下差别:
生命周期不同:命名服务需要管理服务的生命周期,实时探测服务的存活状态;配置服务主要管理静态的信息。
数据产生方式不同:命名服务数据来源于服务的注册;配置服务数据来源于OP手动添加。
数据精确度不同:命名服务数据可能会存在一定时间窗口内的误判(后面会提到);配置服务的数据会非常精确。
Vintage在微博平台内部已经获得了很大的推广和使用,RPC service、cache service、分布式trace系统、queue service都在一定程度上依赖vintage,它的重要程度是不言而喻的。 那么如此重要的服务是如何设计的呢?
二.Vintage设计和架构
1. 架构设计
Vintage在设计之初就明确了以下的目标:
高可用:vintage管理着服务的地址和元数据信息,其本身的高可用性决定着系统整体成败。
低延迟:微博平台中每次调用理论上都会与vintage有一次或者多次的交互,因此vintage访问延迟影响着系统整体的性能。
时效性:对于变更及时响应和通知
vintage选择redis作为配置信息的落地存储,结构简单,无单点,具体如下图所示: