微信读书后台架构演进之路

图片

图片

👉目录

1 前言

2 整体架构

3 RPC框架

4 书籍数据中台建设

5 账号系统可用性建设

6 内容召回演进

7 写在最后

今年是微信读书上线10周年,后台架构也伴随着微信读书的成长经历了多次迭代与升级。每一次的组件升级与架构突破,在一个运行了10年的系统上落地都不是一件容易的事情,需要破釜沉舟的决心与胆大心细的业务联动。本文简要概述微信读书后台团队近几年的一些架构迭代以及背后的思考。

关注腾讯云开发者,一手技术干货提前解锁👇

01

前言

今年是微信读书上线10周年,后台架构也伴随着微信读书的成长经历了多次迭代与升级。每一次的组件升级与架构突破,在一个运行了10年的系统上落地都不是一件容易的事情,需要破釜沉舟的决心与胆大心细的业务联动。

微信读书经过了多年的发展,赢得了良好的用户口碑,后台系统的服务质量直接影响着用户的体验。团队多年来始终保持着“小而美”的基因,快速试错与迭代成为常态。后台团队在日常业务开发的同时,需要主动寻求更多架构上的突破,提升后台服务的可用性、扩展性,以不断适应业务与团队的变化。

02

整体架构

微信读书是独立于微信的App,且由于历史原因,开发及运维环境均存在一定的差异与隔离。因此,微信读书的后台服务实现了从接入层到存储层的一整套完整架构。

架构上分解为典型的接入层、逻辑层和存储层:

  1. 接入层按业务划分为多个CGI服务,实现了资源隔离。在CGI层面还实现了如路由、频控、接入层缓存、长连接等

  2. 逻辑层采用WRMesh框架构建了多个微服务,这些微服务按业务场景进行划分,实现了不同模块间的解耦。框架也提供了如RPC、路由发现、过载保护、限流频控、监控上报等能力

  3. 存储层主要采用PaxosStore存储用户数据,分为K-V和K-Table两种类型,具备高可用、强一致的特性,针对String和Table两种类型定制了缓存中间件,以适配某些业务场景下对访问存储的性能要求。BookStore提供书籍的存储服务,满足读书场景下对书籍的拆章、修改、下载等需要。此外,也不同程度地使用了腾讯云的PaaS存储服务,以灵活满足更多场景需要。

具体的业务逻辑不再赘述,下面简单介绍下微信读书近几年在后台架构上的一些演进。

03

RPC框架

微信读书后台微服务源于Hikit框架,采用C++开发。该框架诞生于广研、QQ邮箱年代,在性能、容灾、运维、监控层面都经受了线上的考验,在微信读书上线初期作为主要框架,支撑了后台服务长达数年。

随着微信读书的发展,越来越多异构的系统发展起来,例如推荐算法系统是独立部署在TKE上的容器服务,采用GO语言开发,好处是历史负担少,运维更加方便、开发更加便捷。两套系统同时存在带来的问题是如何做好服务治理,推荐系统需要频繁调用后台基础模块获取用户数据,必须要有一套完善的路由管理、容灾机制,且考虑到是异构服务,开发语言也不相同,如果为每种语言都定制开发一套服务治理框架,代价会非常高。在这个阶段,我们开发了WRMesh框架,采用Sidecar+Business的方式解决这个问题。

Sidecar专注于处理网络层的逻辑,和Business业务层分开为两个进程,由WRMesh脚手架生成代码,上层业务无需感知。Sidecar集成了Hikit框架中用于服务治理的核心逻辑,通过UnixSocket与Business进行通信,代理Business的所有网络读写。当Business进程中需要发起网络请求时,由WRMesh生成的Client代码会自动识别当前是否在mesh环境中,并转发请求给Sidecar,由Sidecar完成接下来的网络处理。因此,Business进程可以由任意语言任意框架开发,只要遵循Sidecar的通信协议,只需要薄薄的一层网络协议转换即可接入到Hikit的服务治理框架中。另外,对于某些有特殊路由逻辑的Client,如KV访问、Batch请求等,代理转发并不能满足要求,因此Sidecar还提供了插件能力集成这些Client逻辑,最大限度为异构Business业务提供原生C++的能力。

随着WXG容器平台P6N的建设越来越完善,许多微信的能力也是基于P6N提供,我们也在思考如何逐步迁移到P6N。由于微信读书后台运维目前依赖于企微团队,有独立于P6N的一套运维体系,我们负责业务和架构开发。如果要一刀切把所有后台服务迁移至P6N,将会面临几个问题:

  1. 框架代码需要重新适配,开发环境和现网环境都有巨大的改造成本

  2. 迁移不是一蹴而就,后台上百个服务在迁移过程中,会存在新旧服务互调的问题,由于运维环境不互通,微服务之间无法完成服务治理,这种互相调用最终只能通过Proxy来转发,不仅增加了网络的失败率,时延增加,最关键的是这个过程会让容灾体系大打折扣

  3. 存储模块的迁移成本和风险巨大,如果不迁移存储模块只迁移了逻辑模块,那势必又会存在2中的问题,这个过程很难收尾

考虑到人力成本及投入性价比,我们最终采用了折衷的方案。一方面我们保留了依赖于企微的运维环境,保障绝大多数现成服务的稳定运行。另一方面,对于微信P6N中的服务,我们搭建了比较完善的Proxy层,例如Svrkit代理、WQueue代理等,两套架构可以方便进行互通,最大限度的在原有基础上接入微信的新能力。目前,微信读书已顺利接入如WQueue、FKVOL、SimOL、TFCC等众多微信的能力。

04

书籍数据中台建设

书籍是微信读书的内容根基,书籍数量的多少、书籍质量的好坏,很大程度上决定了用户是否选择微信读书作为阅读App。过去,我们依托阅文集团提供电子书资源,免去了书籍上架前繁琐的处理流程,包括排版、审校、元信息管理、更新管理等,后台服务只需要对接阅文API即可方便获取书籍数据,我们只需要关注书籍在平台的存储管理和分发流转即可。

近几年,电子书行业的大环境发生变化,一方面,用户对书籍品类多样性、内容质量有更高的诉求,另一方面,平台对成本、版权等行业因素也更为敏感。因此,我们也在积极探索自签版权,甚至是自出品的模式,尝试走更多不一样的道路。从后台角度而言,从过去单一依赖阅文集团API的模式,慢慢转为开放更多的书籍管理接口,形成书籍数据中台模式,为上层运营同学搭建内容管理平台,让更多人可以方便参与到电子书的制作、排版、上下架、运营管理当中。

以EPUB为例,从内容产出到上架到微信读书,大致经历以下阶段:

  1. 排版审校。这个阶段多为人工或者部分机器自动化介入

  2. 上架预处理。这个阶段需要创建书籍信息,配置各种运营策略,当这本书是重排版上架时,内容发生改变,由于现网已经存在用户的划线笔记、进度等数据,需要有完善指标评估是否适合覆盖上架,当上架时,需要对用户数据进行修复,避免发生错位情况,严重影响用户体验

  3. EPUB解析。当书籍上架后,由于EPUB是单一文件,不适合解析和管理分发,因此后台会把源文件解析成自有格式,包括EPUB拆章、图文分离、样式分离、按章生成离线包等等

  4. 生成BookInfo和BookData并落盘。EPUB文件经过解析后,BookInfo和BookData会存储到自建的StoreSvr服务上,StoreSvr针对书籍存储、下载等场景进行了很多优化,具备高可用、低时延的特点,提供了书籍信息获取、按章下载等核心接口。

回到最初的目标,我们希望把更多的书籍管理能力开放出来,对上层屏蔽电子书底层的后台逻辑,让运营同学可以更专注于书籍的管理。因此,我们构建了如下书籍数据中台:

后台服务拆分开StoreAPI和StoreSvr,StoreAPI提供书籍管理的接口,由运营同学搭建的内容平台与StoreAPI交互,完成书籍的管理工作。StoreSvr一方面接受StoreAPI的请求,更新书籍数据,另一方面为现网用户提供高可用的服务。StoreAPI提供了如下接口能力:

  1. 书籍id分配、上下架

  2. 书籍信息创建、修改

  3. 书籍内容修改、连载更新、订阅推送

  4. 运营策略管理

此外,如上所述,划线位置和阅读进度等核心UGC数据由于是按文件偏移记录,当书籍文件替换后,这些数据会发生错位,如果不能及时修复,将对用户体验造成巨大影响。尤其在一些热门书籍里,单本书里与位置相关的UGC数据往往能达到亿级别,由于文件替换后位置的偏移具有随机性,并不能采用简单的映射方式解决,在过去,我们开发了专门的修复服务来完成这个事情,针对每一个UGC内容,采用全文模糊查找的方式重新计算新的偏移,并更新的UGC正排、书籍倒排等多个存储中。但随着用户数据越来越多,书籍替换频率越来越频繁,修复不及时或者失败的问题逐渐暴露出来:

  1. 修复量大导致修复不及时。过去的修复服务虽然是多机部署,但处理单本书仍只是集中在一台机器上,单机性能有限。

  2. 修复任务缺乏落盘管理,修复服务一旦重启,任务丢失。

针对上面的问题,我们重新设计了修复服务,目标是最大限度缩短修复时间,并且让整个过程是可靠的。为此,我们先首手考虑业务流程,我们发现在书籍上架前,运营同学本来就需要依赖UGC的修复情况做前置判断是否覆盖上架,这个过程中虽然是对UGC抽样评估,如果能对这个修复映射结果进行缓存,在正式替换文件后,也能一定程度提升修复速度。在核心修复流程中,我们进行了较大的重构,把单本书的修复任务拆解成多个子任务,存储在Chubby上,多机器抢锁共同消费这些任务,由于任务有落盘,在服务上线重启过程中,也能马上恢复。修复过程涉及大量的KV写入,并发太高时容易命中单key的限频或者版本冲突,我们为此开发了针对K-Str和K-Table的写入中间件,可以在内存中聚合一批请求进行批量合并写入,缓解KV层面的失败。

目前,微信读书已通过内容平台完成了多家版权方自签,并在探索自出品等内容创作新形式。

05

账号系统可用性建设

账号是微信读书后台系统的基石,承担了登录、会话密钥生成与派发、用户资料管理等核心功能,所有的用户请求都需经过账号系统进行鉴权验证用户身份,但凡有一点系统抖动都会影响到整个App的正常使用,严重者还会导致账号被踢出无法再次登录。

账号系统的架构在微信读书诞生之初便一直沿用,同一个号段的账号服务AccountSvr和MySQL部署在同一台机器上,备机采用主从同步的方式获取数据,当主机不可用时,备机承担了所有读请求。在某些场景下,为了能使访问备机时也具备一定的写入能力,曾经魔改过主备逻辑,但一切都显得治标不治本,且引入了更复杂的系统特性,整个架构略显混乱。在机器裁撤、数据扩容过程中,曾造成过几次严重故障,导致App不可用,严重影响用户体验。究其原因,是因为当时基础设施还不完善,缺少高性能高可靠的强一致存储,MySQL也是手动搭建的,运维成本和风险都非常高。

为了彻底解决这个历史包袱,我们在2024下定决心对其进行重构。重构就意味着要抛弃现有MySQL这套臃肿的存储方案,把数据迁移到新的存储组件上,这里涉及到的挑战点如下:

  1. 账号鉴权服务访问量巨大,迁移过程须尽量不增加系统负担,且必须是在不停机的情况下进行

  2. 迁移过程中一旦有数据丢失或者错误,会导致用户资料受损,用户登录态丢失,App无法使用

  3. 账号系统还涉及用户id分配和回收逻辑,在切换存储时如何保证数据的一致性,不重复分配号码

背水一战,没有退路可言。在经历了多次论证后,我们决定采用Paxosmemkv作为新的存储组件,全内存、多副本、强一致的特性,很适合作为账号系统的底层存储。同时,我们为整个迁移过程制定了周密的方案,把每一步进行了分解,且要求每个环节可灰度可回退,同时要做好数据的一致性检查。在完成数据迁移后,我们还需要对AccountSvr进行重构,抛弃按号段的账号分配、路由、缓存逻辑,以全新的视角设计更简洁的架构。

06

内容召回演进

以往微信读书的搜索仅限于基于书名、作者等维度的文本召回,通过自建的全内存索引服务实现书籍的检索。全文检索则基于ES搭建,采用规则分段的方式建立索引,能满足读书大部分场景的需要。

在大语言模型迅速发展的近两年,微信读书作为一个庞大的内容知识库,具有大量的书籍原文资源,同时,用户在微信读书也留下了大量的文字内容,如书评、想法等,这些内容构成了AI问书的内容基石,也是AI问书区别于其它问答工具的核心优势。基于微信读书构建RAG召回系统,核心挑战如下:

  1. 基于书籍原文构建全文检索,为了达到最好的效果,往往需要支持按语义进行段落切分,在此基础上构建embedding进行语义召回。微信读书拥有百万级书籍原文数据,此外,对于用户导入书,更是达到亿级别规模。现有架构无论从成本还是耗时上都无法解决。

  2. 为了支持更多维度的召回,需要对UGC内容进行召回,部分UGC内容属于私密信息,并不向全网公开,只需要满足用户个人检索即可。此时如果用常规的检索系统构建常驻索引,访问率太低,成本难以收敛。

为此,我们针对微信读书不同的RAG使用场景,设计了如下召回架构:

我们把数据划分成两类:全局公开可搜以及用户个人可搜。

对于全局公开可搜索的数据,如库内电子书的全文、书籍大纲、书评、人工知识库等,我们构建了一套入库流程,能对源信息进行语义分段、生成正排倒排,语义分段基于开源的chunk模型进行微调,正排基于fkv,倒排则基于ES构建,ES提供了DiskANN方案,通过设置合理的缓存和分片,能在存储成本和召回效率之间取得不错的平衡。对于 App 内主搜等低时延场景,为了满足多种定制化检索需求,我们自建了基于内存索引的Searchsvr服务,支持索引落盘,可以在毫秒级返回电子书搜索结果。

对于用户个人数据,如导入书全文、个人想法等,特点是数据量大但使用频率不高,不需要针对全网用户进行检索,如果采用上述方案,会带来成本灾难,性价比极低。为此,我们按用户及物料的维度,基于USearch、Xapian等方案构建了向量及文本索引,这些组件的优势在于可以把单个索引存储成文件的形式,便于落盘,配合一些量化的方法,可以把大大压缩索引大小。在构建索引阶段,按用户+类型构建出不同的索引,并存储在低成本的COS上,当用户需要检索召回时,采用读时加载的方式实时进行召回,结合CFS进行预热可以大大提升检索速度。当检索完成后,定时淘汰策略会把长期不用的索引从CFS中清理,降低存储成本。

07

写在最后

虽然微信读书已经发展了十个年头,但我们的脚步从未停止。

在日常业务开发之余,我们也从未停止思考如何让系统能走得更远、更稳健,抓住每一个可能的优化点,随时做好准备,迎接下一个精彩的十年。

-End-

原创作者|罗国佳

感谢你读到这里,不如关注一下?👇

图片

📢📢来领开发者专属福利!点击下方图片直达👇

图片

图片

你在实际项目中遇到过哪些系统架构演进的挑战?欢迎评论留言补充。我们将选取1则优质的评论,送出腾讯云定制文件袋套装1个(见下图)。6月13日中午12点开奖。

图片

图片

图片

图片

图片

图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值