乐趣区

关于后端:微信研发体系下的分布式配置系统设计实践

腾小云导读

对很多的开发者而言,解决经营素材重复变更等需要场景不是一件轻松的事。开发者通常须要定制化地进行数据清理、格局转换和工具开发等等。在这个时候,建设分布式配置零碎就显得尤为重要。本文旨在剖析分布式配置零碎的必要性、可行性及其要害束缚,并介绍一个在微信研发体系下的分布式配置零碎研发设计。这个零碎胜利防止了大量的配置数据的工夫耗费,心愿能对宽广开发爱好者有所启发。

目录

1 配置的定义

2 零碎束缚

2.1 数据模型

2.2 拜访模型

2.3 零碎束缚

2.4 平安束缚

3 零碎的演进

3.1 单机配置文件

3.2 集中式配置文件核心

3.3 数据库配置存储

4 计划思考

4.1 物理模型

4.2 平安治理

4.3 配置零碎 SDK

4.4 异步化

4.5 业务插件

4.6 推与拉

4.7 疾速最终统一

4.8 申请枯燥

4.9 灰度公布

4.10 效率晋升

4.11 可用性晋升

5 境外领取配置零碎

01、配置的定义

软件建模的实质是对事实世界(人、事、物及规定)的映射,映射的产出物是编程零碎和配置。配置为开发者 提供了动静批改程序运行时行为的能力,即常说的“零碎运行时航行姿势的动静调整”,究其根源则是“人类无奈掌控和预知所有,映射到软件畛域上,人总是须要对系统的某些性能个性预留出一些管制的线头,以便在将来须要的时候,能够人为地拨弄这些线头从而控制系统的行为特色。”

因而,本文所指的配置特指外部经营人员产生的数据(狭义的零碎经营人员,包含产品、经营、研发等),作为输出参数而作用于编程零碎(包含实时零碎、批跑程序以及数据工作等)。

演绎而言,配置通常蕴含如下三种:

a. 环境配置,定义了利用程序运行时的环境相干参数,如 IP、Port 等;

b. 利用配置,定义了应用程序本身相干的参数或者信息安全管制等,如初始内存调配大小、数据库连接池大小、日志级别、账号密码等;(明码、证书这类事物不要放在配置零碎中,该当走对立加解密服务)

c. 业务配置 ,定义了应用程序所执行的业务行为数据,比方最常见的 性能开关,参加流动的商户名单等。

02、零碎束缚

2.1 数据模型

配置最根本的数据单元是 key=value(即配置项),比方性能开关通常就是最简略的类型,用 boolean 型值来影响程序执行链路(不思考灰度的状况)。然而只有 key-value 类型是有余的,比方 DB 的连贯配置就蕴含了 ip、port、username、password 等字段,在 ini 文件的实现中即是不同配置项来组成,它们在逻辑上是属于同一个配置对象,因而基于面向对象的设计思路,key=object才是更通用的配置模型,在物理实现中能够体现为 json 或者 xml,或者 protobuf message。

object 类型的数据既能够是 平坦的 ,也能够是 多层次 (嵌套)。在理论的业务利用中,平坦 类型的数据有其特殊性,即其通常条目较多,最典型的数据是 白名单,可能多达上万条。

线下,外部经营人员通过 excel 进行这类数据的治理,如果只是毛糙地将其打包成一个对象,那么过大的数据可能会导致系统效率的降落(不是配置的写入效率降落,就是配置读出效率降落),因而需应用 array of plain object 来表白,即 key=table 类型的数据。

2.2 拜访模型

区别于产品用户产生的数据,配置零碎的数据流是单向的,离线零碎与实时零碎联合,而读写拆散的(异步写、实时读)。最终要搭建的分布式配置零碎,它的零碎设计,也必然是建设在这类拜访模型上的。

2.3 零碎束缚

显然,外部经营人员作为生产者,所有的 配置必定都是文本类型的 (Readable),并且 数据量少 (绝对于用户、零碎等生产数据而言),对存储空间需要少, 更新频次低 。换一种说法,在整个配置零碎架构中,输出方就如同键盘绝对于 CPU 而言是超慢速设施,它们对系统的 易用性、易操作性、安全性 要求更高。

用户画像零碎,它满足局部配置零碎的拜访模型,即数据流是单向的,离线零碎负责写入画像数据,而实时零碎负责读数据。然而首先它的数据生产者通常是离线工作,而非经营人员;再次,它波及的数据量是微小的,通常须要定制的存储引擎。所以配置零碎与之相比,不能等量齐观。

相较而言,配置零碎的消费者则是高频的读拜访,对系统的 吞吐量、延时、网络流量、可用性、一致性、申请枯燥性 都有更高的要求。后续会逐个开展进行深刻地探讨。

配置零碎的设计该当充分考虑上述的数据模型、拜访模型以及零碎束缚。

2.4 平安束缚

正因为配置能够轻易地调整零碎运行期行为,因而配置的安全性至关重要。实现平安的必要条件是:让正确的人,以正确的形式,在正确的机会,公布正确的配置 。因而,配置零碎岂但要 反对灰度公布 的根本能力,还要在 权限治理、权限粒度治理、配置变更审核、审计、历史版本 等方面都要增强建设。

03、零碎的演进

3.1 单机配置文件

在单机零碎时代,大家基本上都是应用配置文件来存储配置数据(比方 ini 文件、xml 文件等)。配置文件易于了解、便于实现、可用性高,因而进入分布式集群时代,仍在宽泛应用。

毛病 体现
易用性差 次要体现为表白的数据类型繁多,比方 ini 只能治理配置项,即 key=value 类型数据;而如果应用 xml 文件来治理 key=table 类型数据,那么文件内容的初始化效率就会低下,容易出错,
可操作性差 配置文件根本只能由开发者来进行批改并且公布,产品、经营的惯例业务素材变更工作就不得不卷入其中,由开发执行,对业务的流程效率有重大的影响。
正确性、安全性难以保障 正因为配置文件的易于实现,很多团队忽略了经营零碎的建设,研发人员随便批改、歹意批改配置文件的状况无奈杜绝,细粒度的权限治理、操作的审核、审计就无从谈起。
公布效率低下 配置文件是单机部署的,在集群规模较大的状况下,配置文件的任意变更都须要通过漫长的灰度公布过程公布到全网,如果配置文件是动态加载的,还须要重启二进制,须要耗费研发、运维人员较多的精力。
文件一致性难以保障 在公布配置变更的过程中,如果集群中呈现宕机状况,会导致不同机器间的配置呈现差别,而且没有主动校对的能力,需依赖于人员或者运维零碎的反对,进而导致业务进入未定义的行为。

如果说易用性、可操作性、正确性、安全性能够通过搭建经营零碎来进行改良是长处,而公布效率低下、文件一致性难以保障则是单机配置文件的致命毛病,究其实质,是因为单机配置文件系统是被动的、离散的能够随便承受外界的变更,而没有被动的能力。

3.2 集中式配置文件核心

由此,呈现了集中式的配置文件系统,针对性地解决了上述的问题,开发人员将配置文件存储到独立的第三方服务(典型的由 ZooKeeper 进行治理,也有局部团队自行实现微服务治理),而后由 agent 周期性地将配置拉取到本地进行缓存(拉),或者通过事件的订阅告诉能力来将变更公布到相应集群(推)。

集中式配置文件系统针对性地解决了公布变更效率问题以及配置文件一致性保障问题。然而在一些所知的利用案例中,依然存在如下的问题亟需解决:

  • 一致性粒度粗

集中式配置文件只能确保分布式集群达到最终统一(工夫取决于拉、推的频率及速率),却无奈保障任一时刻,对任一配置,所有过程、线程、协程能看到雷同的数据,这通常会导致呈现无奈预期的业务失败;

  • 无奈保障申请枯燥性

在一次业务申请中,个别心愿用户看到的配置内容是动态的,如果两头产生变更,可能带来业务失败,重大的会导致用户数据状态错乱;基于集中式配置文件系统的配置通常是动静加载的,配置的变更可能随时的反映到实时零碎中,导致一次业务申请先后看到不同的数据状态;

  • 安全性仍无奈彻底保障

尽管集中式配置文件能够批改管制权限,然而在消费者端,技术人员依然能够手动的批改本地配置文件 cache 来影响程序的运行行为;

  • 无奈反对灰度能力

配置文件变更的下发是全量的,如果要反对灰度公布的能力,就须要卷入业务方自行实现;

配置文件系统,无论是单机配置文件,还是集中式配置文件,存在的问题,归根结底,是由配置文件这个载体以及集中式配置文件系统的管道定位决定的,所以进行精细化治理的老本高;

  • 配置文件的可视、可读能力

对生产者而言是很重要的,但对消费者却是无关紧要的,因而全链路都由配置文件作为载体反而会导致 加载效率低下(比方应答千万级黑白名单,或者业务方实时申请链路动静加载);

  • 配置文件难以平安、便当治理元信息

为了实现一致性、枯燥性、安全性,配置须要一些元数据信息管理(下文开展详述),然而配置文件系统没有这种能力,除非业务方应用高老本自行实现。

  • 配置文件的数目与配置的数量非亲非故

随着工夫的倒退,配置文件数目收缩,会带来新的经营问题;

  • 集中式配置文件系统通常只把本人定位成管道

既不了解也不保护配置文件的内容,agent 性能繁多,业务生产方不与零碎间接交互,而是只能看到配置文件,尽管松耦合,能够进步可用性,但也让业务方仍需投入不少的开发成本来解决配置文件。

配置文件只是配置的物理载体,上述毛病并非无奈克服,只是在基于配置文件的配置零碎下,克服上述毛病的老本高,须要更多的应用束缚,以及外围配套。

3.3 数据库配置存储

对结构复杂、类型较多的配置零碎,业务研发者通常不会间接应用配置文件来承载,而是应用数据库(关系型或非关系型)表来存储配置,而后再应用编写工具进行数据的导入。这种存储计划克服了配置文件的局部问题,对配置有更精细化的治理。然而仍存在显著的有余,即高度的定制化,不可复用,反复开发成本高。

因而,须要对此进行欠缺,将配置的存储、读、写、治理等过程提炼共性,通用化、平台化。

04、计划思考

4.1 物理模型

既然配置文件难以精细化治理,且具备易侵入的物理实体个性(本地文件),所以就须要新的数据结构来承载配置。前文探讨过,配置有两种数据模型,别离是 key=object 以及 key=table。对使用者而言,配置必须是可视、可读、易治理的。为了达成这目标,只需在外部经营人员与配置系统核心之间搭一套设计良好的 经营零碎 即可。那么在后端呢?对消费者而言,最重视传输、计算的效率,同时也要与微服务框架的对齐,protobuf message 无疑是最佳的模式。

然而 protobuf 无奈自主解释,在没有 message 定义的状况下,既没方法将文本色的配置转换成 pb 二进制流,也没方法反序列化。因而咱们必须将业务的 message 定义上提到经营零碎,然而 protobuf 却对可视化编辑不太敌对。一个可行的思路是基于 JSON 数据 进行配置的定义、可视化操作、传输及存储,只有达到业务侧才进行数据类型的转换。

4.2 平安治理

搭建一套配置经营零碎,让其成为经营人员治理配置的惟一入口,轻松就能够失去很高的回报。而且还能够基于经营零碎进行各种配置以及平安加固,如配置的变更必须具备相应的权限,只有通过审核能力利用到零碎,所有的操作都要有审计的能力、配置的历史版本疾速可查等。同时灰度、回退等能力也须要基于经营零碎进行操作。

4.3 配置零碎 SDK

上文提及集中式配置文件系统的管道定位,agent 只负责定期的拉取配置而后缓存到本地的文件系统。业务零碎与配置零碎松耦合。个别认为配置文件依然具备较高的开发成本,对业务方而言,最佳的开发模式该当是:

int GetConfig<Message>(const std::string& key, ::google::protobuf::Message& msg);

而不须要再去了解文件内容、模式。

并且有必要为业务方提供一套配置零碎的 SDK,将配置零碎的细节、数据结构等信息都屏蔽起来,让业务方只看到配置的 Protobuf Message 对象。

在 SDK 的根底上,消费者只需轻度染指(业务插件,见下),就能够实现协定转换、配置缓存、过程,线程,协程的疾速最终统一、申请枯燥、灰度公布的能力。

配置零碎 SDK 是精细化治理的根底 ,能够通过保护配置自身内容之外的 配置元数据信息 来实现上述能力。

4.3 异步化

异步化是配置 SDK 的要害。很多本地缓存的更新是周期性由实时链路申请负责,虽易于实现,但效率上仍存在问题,尤其思考到还须要对配置进行配置业务逻辑的解决。因而,最佳计划该当是通过异步过程来进行配置的加载、初始化及其他逻辑解决。

异步带来的问题是异步过程与实时申请的并发问题,即异步过程在进行配置变更中,应如何解决实时链路的读申请,这是一个工程问题,会另文探讨,一个可行的思路是 多版本及援用计数技术。

4.4 业务插件

异步提供的另外一个益处是,业务能够在配置失效的时候进行一些初始化动作,例如进行 配置正确性校验 ,以及 搭建业务适宜的数据结构。例如业务白名单在 pb 中只是一个数组,如果业务进行命中查找,代价比拟高。业务最冀望的形式还是应用 map 来存储。因而配置 SDK 异步化,就为业务插件能力提供了根底。

4.5 推与拉

个别更偏向于配置 SDK 被动拉取配置的更新。推与拉的辩证在于效率和可用性。推比拟高效,不存在无用的网络耗费。然而推又引入了新的零碎依赖(即事件核心)。“如无必要,勿增实体”,基于这样的思维,所以个别由 SDK 周期性被动拉取。至于效率,齐全能够通过各种工程的伎俩加以优化,达到能够承受的水平。

当然这也取决于零碎规模,如果是公司机的配置零碎,而不是局部核心级,那么也要认真地思考“推”或者“推拉”联合的模式。

4.7 疾速最终统一

无论是单机配置文件系统,还是集中配置文件系统,都存在重大的不统一问题。对一次配置变更,基本上都须要很长的工夫能力达到最终统一(即所有并发看到雷同的数据状态)。

一个可行的思路是使 多版本以及定时失效。配置只有在将来的某个工夫(该工夫内 SDK 曾经拉到了最新数据)才对外可见。至于如何确保所有 SDK 都拉到了数据,这波及到可用性的问题,后续会另文探讨。

4.8 申请枯燥

定时失效没方法解决 申请枯燥性 的问题。申请枯燥性是指实时服务解决一次申请,在申请调用栈的过程中,读到的配置内容必须是动态、没有变动的,即便两头有待失效数据变成了失效数据。一个思路是能够通过 线程公有变量(协程公有变量)缓存配置版本。

4.9 灰度公布

在配置 SDK 多版本能力的根底上,实现灰度公布的能力是轻而易举的。灰度公布的能力,不过就是抉择失效配置版本的能力,如果本机、本角色、本申请业务 Key(如用户、商户、订单)等命中灰度范畴,则应用新版本,否则应用原版本。

4.10 效率晋升

效率晋升包含升高网络传输数据量、升高配置存储服务的压力,这些都是具体的工程伎俩,不在本实践篇内探讨。

4.11 可用性晋升

分布式系统的可用性晋升是陈词滥调的话题,为了聚焦于配置零碎独特的能力,本篇不专门进行探讨。

However,尽量减少零碎中的单点,是一个重要的准则。在前节”推与拉“中也有波及。同时为了业务的可用性,第三方配置零碎的经营能力、故障被动发现能力、故障告诉能力、再现及定位能力也十分重要。这是反复造轮子的一个不得已的重要起因,很多团队软件可能做得不错,但服务能力 (次要指经营能力) 却有点不尽人意。

05 境外领取配置零碎

本篇的技术计划目前 已退役两年的工夫,有上百种业务配置,包含性能开关,但更多的是经营素材配置。

举一个例子,在开发配置零碎之前,为了导入一次经营素材配置,须要研发投入 2 天的工夫,数据的审核都是在线下进行(品质可想而知)。目前基于配置零碎,小助手 10 分钟之内实现批量导入、程序主动校验(依赖于业务插件)、审核审批,研发全程无需染指。

同时也为业务方提供了易于应用的配置 SDK,反对多种配置类型,容许业务自定义数据结构,领取定时失效、灰度公布的能力,并且满足申请枯燥性。

以上是本次分享全部内容,欢送大家在评论区分享交换。如果感觉内容有用,欢送转发~

-End-

原创作者|杨安全

技术责编|杨安全

「分布式系统」近年来受到较大关注。有些人认为分布式的劣势在于可靠性,就算是一个十分弱小的单机零碎,在可靠性上也简直无奈与之匹敌。而有局部开发者认为分布式系统虽集成了「个体」的力量、提供了更弱小的数据处理能力,但在人多力量大的同时也引入了更多问题,如数据一致性困扰等等。

你怎么对待分布式系统?它有什么长处和缺点?在什么情境下最实用?欢送在腾讯云开发者公众号评论区分享你的认识。咱们将选取 1 则最有创意的分享,送出腾讯云开发者 - 马克杯 1 个(见下图)。6 月 25 日中午 12 点开奖。

退出移动版