收集表是腾讯文档的核心品类之一,也是主要的用户增长来源渠道。作为在重大社会事件中承担社会责任的主要功能,收集表既面临着海量规模的压力考验,也在高速发展的业务进程中遇到了遗留技术债的掣肘。 - 核心服务为C++“翻译”过来的 C++ 风格单体非标 tRPC-Go 服务,代码量较大,不利于多人敏捷协作开发,业务快速迭代时期夹带发布风险高,故障爆炸半径大。 - 业务逻辑耦合严重,接口未做轻重分离,稳定性较差,性能存在瓶颈。 - 业务可观测性存在问题。 在这样的技术背景下,腾讯文档团队对收集表后台服务进行了全面的重构,实现了百万级大收集极限业务场景下提供稳定解决方案的业务收益,完善了底层技术基座,优化了产品体验,实现了开着飞机换引擎的重构效果。
腾讯文档作为用户最广泛使用的在线文档,支持 Word、Excel、收集表、PPT、思维导图、脑图/流程图等品类多人协同在线编辑。近两年用户规模上不断突破,保持行业领先,也取得了不错的社会效应和用户认可。
收集表作为腾讯文档核心品类之一,在特殊时间成为文档最主要的用户增长方式,持续发挥信息传递的价值,在各类重大社会事项场景中及时响应推出解决方案,让“救命文档”的标签进一步深化。此外,团队不断提升底层技术能力,支持单收集表百万提交和数据导出与同步。
但另一方面,收集表的后台服务可用性存在一定的历史包袱,接口成功率稳定性差,用户负面反馈时有发生,一定程度制约了业务的良性发展。
因此,从2022年7月起的近1年内,新增需求如周期收集、新名单、导出归档等开始,我们针对收集表后台的新服务进行标准化开发和老服务重构优化。在保证新服务可用性、稳定性、可观测性都达标的前提下,逐步对存量巨石服务进行拆分重构。重点保障:
为加快业务迭代效率和代码可读性,针对老单体非标服务进行了拆分重构,采用大仓通用脚手架生成服务,业务垂直分层为 service logic repo 等,不同分层和函数之间低耦合,模块内部业务逻辑高内聚。
为提高核心接口可用性,我们采取软件工程经典“分治”思想,进行了逻辑和架构分层治理,拆分出读写原子服务,由业务逻辑层调用原子接口;同时,将核心链路中的可异步化逻辑剥离,由消息队列解耦后异步处理,如提交同步表格、发布作业重判等。不仅优化了主链路高耗时问题,也保障了核心链路(提交、发布、查询)接口成功率。
通过有损服务给用户提供柔性降级体验,例如在提交数据同步表格过程中,当提交数过大时,同步至表格侧的数据会发生写放大,单收集表 1w 提交数据在表格侧可能占用数十万甚至上百万单元格,对下游表格中台/编辑中台的压力较大。
因此我们设置了表格侧同步上限,触及同步上限的内容将不再继续增量同步,引导用户通过终端导出本地后查看,既对下游产生保护作用,同时也降级保障了用户的使用体验。
架构范式从过去的紧耦合过渡为松耦合,按照业务模块分为通用逻辑、导出归档、新名单、周期收集、同步表格等19个服务,各个模块可以独立开发、部署、扩展,使业务支持快速迭代,减少部署发布带来的变更风险和心智负担。组织和团队结构可以围绕业务服务去构建,专注于当前业务模块,从而灵活根据业务需求来使用人力,对于协作效率的提升和交付时间的缩短都有重要作用。
系统可观测性作为业务最后一道生命线和云原生成熟的重要衡量标准,为我们观测系统运行时状态提供工具、方法论、基础设施等一系列指导,可观测性驱动开发(ODD,Observability Drive Development)这一研发模式也正在逐步成为云原生分布式系统中最佳实践。
腾讯也在可观测领域持续打磨和沉淀,有如:腾讯云可观测平台、天机阁等成熟的观测产品。腾讯云可观测平台既服务于外部公有云用户,同时也会服务于腾讯集团的内部用户,天机阁目前只服务于腾讯集团内部客户。
腾讯文档在业务实践中大量使用天机阁可观测性平台,在腾讯文档 C 端、企微 Saas 版本、企微私有化、腾讯文档独立私有化等版本中都几乎全量上报天机阁,包括 Traces、Metrics、Logs 等,原始上报量 700+TB/d。收集表也是天机阁重度使用品类,通过 ODD 帮助研发、测试、产品、运营同学通过数据理解业务,达到一切尽在掌握的目的。以下将进行详细说明。
收集表数据同步表格是典型的业务最终一致性场景,其中需要考虑同步速度,数据是否最终一致等问题。在业务实践过程中,经历了以下3个阶段:
极端情况下,热收集表导致有过半 Partition 都积压超过 1w 条数据,也会影响到相同 Partition 内其他收集表的正常同步,需要人工介入手动停止热收集表同步,普通收集表才会恢复。
于是选择将 Kafka 队列做冷热隔离,热收集表的同步数据降级生产到单独热队列,普通小收集表同步数据生产到普通队列。这样可以优先保证现网95%收集表的同步正常,但对热收集表的同步有损较为严重。
同步慢原因
同步失败原因
经调研,热收集表用户通常是高商业化价值人群,如何服务好这类用户对于支撑业务快速发展和产品口碑建设更是至关重要。于是我们针对以上问题启动了新一轮同步重构。
经过仔细复盘分析,热收集表的管理员,对于数据同步实时性要求不敏感,几 w 甚至几十 w 提交的热收集表数据同步有少量延时是完全可以容忍,从宏观上难以洞察局部同步延时。最终决定将数据同步由消息队列异步化重构为流水表中间件记录状态,再由定时任务和消息通知去处理执行,以时间换效率。
2023H1,腾讯文档开始灰度新建 sheet 3.0 并全量现网,收集表关联表格也需要完成同步逻辑切换,针对存量 sheet2.0,smartsheet2.0 保证继续同步表格中台,针对新建关联 sheet3.0,smartsheet3.0 需实现编辑中台同步逻辑。
在新同步链路框架中,上游同步控制服务无需关注具体同步细节,只负责全量任务的发起和增量数据的执行;formtosheet 服务会统一对接下游多个新老数据同步方。服务内部高度内聚,做好自己的工作,同步系统稳定性得到大幅提升。
新同步框架上线前,我们也做了完备的性能压测,在新增 5k 和新增5k+10%修改情况下,模拟对比2.0和3.0同步链路在并发提交场景的性能差异,结果如下,新增同步速度从原来的分钟级提升到秒级,即使在10%修改情况也可以保证秒级同步完成。
收集表支持设置填写成员名单,用于管理填写者信息和行为。老架构只支持通用名单设置,且通用名单实现上比较简单,仅通过 Redis 存储所有名单信息,此时单 Redis 集群会成为系统瓶颈所在,且 Redis 一旦因为故障重启容易导致全量数据丢失。
因为居家期间大量信息收集和学生居家上课作业收集等需求日益增多,产品侧启动对家校名单需求的开发,后台侧也趁机针对原有不稳定架构进行重新设计与实现,重点保障名单数据长期安全存储。
老名单链路通用名单只存储 Redis,在家校名单场景现有技术架构也无法满足产品需求;家长可以帮孩子填写对应收集表,且在多孩多家长场景下,孩子与家长并非简单一对一关系,一个孩子可能有多个家长,一个家长也可能有多个孩子。此时针对学生的信息填写需要进行严格的身份绑定和校验,针对不允许重复填写时需要以学生角度校验是否已被其他家长填写,这其实类似于复杂版本的群组概念和社交关系链。难点转向了业务逻辑复杂度和缓存存储的数据一致性。
收集表顾名思义重在收集,和在线文档、在线表格这类更偏向协作的品类不同,收集表是比较典型的 UGC 场景,用户收集完成表单内容后需要进行数据的整理汇总,将表格和附件导出本地能够很好的协助用户做数据归档,支持自定义附件导出归档文件夹路径,按照单题维度导出等。
导出场景是典型异步任务场景,后台数据需经过导入导出侧格式转换、分类归档、压缩打包后,交由端侧完成下载。在2022.10最初版本导本地时,统一由收集表后台提供用户数据,导入导出侧下载到服务器后完成按规则压缩打包。当附件总大小超过 500MB 时,会分为多个压缩包给到用户,这就带来如下问题:
因此产品规划2023年将收集表导出功能迁移至由桌面端承接,总量 <20MB 的附件仍由发起导出的端侧进行下载,而超限附件将拉起桌面端完成。桌面端导出时跳过导入导出较重的下载打包逻辑,将所有附件列表返回给桌面端,由桌面端按文件列表和导出规则依次下载,不仅以较低成本实现了断点续传,同时可以很好的保护下游导入导出服务防止频繁内存溢出。
可观测性作为现代云原生应用的生命线,通过多维数据模型高度保障线上业务平稳运行可观测。腾讯文档全面接入天机阁可观测性平台,收集表又是示范接入品类和 ODD 重度依赖方。收集表后台新服务全量采用 ODD 可观测性驱动开发模式,从持续规划—>持续构建—>持续交付—>持续运维,覆盖产品研发运维 DevOps 的全生命周期,辐射前端、终端、后台、产品等多种参与角色。
但是目前天机阁不对外服务,大家有企业可观测性建设的需求,可以试用腾讯云可观测平台(TCOP):TCOP包含了云拨测 (CAT),云压测(PTS)、前端/终端性能监控 (RUM)、应用性能监控 (APM)、Prometheus & Grafana 服务以及云产品基础监控等多个子产品,经过往几年产品的打磨与积累,在可观测领域已经形成了相对比较完整的产品矩阵,且积累了丰富的行业客户案例。新客户也有免费 15 天试用期。
体验地址:https://cloud.tencent.com/product/tcop
通过重点理解产品业务需求,了解产品重点关注的除服务基础容器监控、主被调监控、请求链路等之外的核心业务指标,如对于收集表导出本地场景,我们意识到用户导出 Excel 和附件的导出行为占比与导出附件数量分布等指标对于产品未来入口设置和产品功能决策有较大意义。这驱使我们更关注业务对于导出数量上限的要求和能力,提前做好对应兜底方案。
在研发过程中,利用 tRPC 提供的标准 tRPC-Metrics 和社区 Prometheus 原生 API 做好对应指标监控项的初始化;通过面向接口编程的依赖注入,以更优雅方式实现上下文信息透传,将辅助判断用户行为的 tag/attribute 提前设置到分布式链路追踪里,待有告警或用户反馈时有更多信息辅助判断,缩短故障恢复时间。
传统数据上报和数据分析存在时延性较高、无法动态调整上报策略等弊端,而通常产品上线前期的实时数据有更大的分析意义,有助于上线后根据实时数据调整产品逻辑。
如导出归档功能上线后,我们观测到用户导出 Excel 和附件分别占比70%和30%,说明用户对附件导出需求较大,便于产品提前规划后续针对附件导出场景优化;用户导出全量数据和单题占比分别为90%和10%,根据数据可以反哺产品后续对导出按钮的曝光设置等。
对于平稳运行的业务,后台日常监控告警和服务质量优化需要保持长期关注。因此我们配置了天机阁/伽利略等多个告警通知渠道,通过企微群、电话、邮件等方式全面监控服务异常波动。
针对后台质量做长期存储和 SLA 汇总,也制作了相关日报业务看板,由于实时查询 Prometheus 拉前一天的数据,会将整个租户数据全部加载到内存中,查询过缓慢导致 Grafana 加载失败(实测 30s 以上),且极端情况数据过多可能导致 Prometheus 单节点 OOM。
每天凌晨定时从 Prometheus 通过原生 SDK 抓取数据写入到 ClickHouse,通过物化视图实现毫秒级日报数据查询,优势在于,可用 Map 类型,对于报表方便增加字段不需要修改表结构;自带 TTL 功能,当前默认1年。表引擎选择 Distributed,因为买的 ClickHouse 是大存储型,默认没有副本冗余。所以设置每天定时写多份,在查询时做 distinct 去重。
目前该功能已有收集表、账号、权限、文档数据、导入导出等模块启用。方便推动自身及合作方及时进行业务整改和质量优化,同时也在腾讯文档私有化版本中作为前端和后台 SLA 质量数据发挥作用。
持续性能分析,即 Continuous Profiling, 是一种强大的技术, 是更强大的 Profiling 版本,增加了时间维度. 可以从任何环境(包括生产环境)连续收集行级分析性能数据。然后它提供数据可视化,以便开发人员可以分析、排除故障和优化代码。
天机阁持续性能分析系统支持持续的性能分析,并将数据保存在服务端,以供 Profiling UI 近实时的查看、回溯、分析。
使用持续性能分析系统的收益:
随着云原生可观测性行业蓬勃发展,如何利用可观测性数据进行更高维度分析和预测成为下一个核心命题。在参与中国信通院《云上稳定性·根因分析行业标准》制定过程中发现,利用可观测性数据实现系统根因分析是国内外厂商正在聚焦的重点。天机阁5月新灰度智能告警功能,腾讯文档租户第一时间启用并推送至告警群,很快就在业务线上故障排查过程中发挥重要作用。经实践验证,对缩短 MTTR(平均故障恢复时间)有非常明显效果。以下举例说明。
5.22日收集表下游 sheetengine 存储高负载导致瞬间产生大量慢查询超时,引起收集表后台异常率上升。14:56收到群内告警推送和电话告警,迅速到天机阁智能告警群寻找关联信息,发现下游 sheetengine 连接打满导致的超时,立刻联系对应同学处理。
从收到故障发生告警 —> 定位问题所处环节 —> 同步相关责任同学,一共耗时在 1min 内,相比之前可观测性数据排查需由告警—>监控—>具体 Trace—>关联日志,链路较长导致定位问题耗时较长;智能告警可以将可观测性数据上下文打通,把相关信息直观呈现给开发同学,更快速高效定位问题,以更短的 MTTR 恢复用户体验。
对于兔小槽用户渠道反馈,我们也做了完备的数据收集和实时推送,随时掌握一手信息并提前跟进排查,对于咨询类反馈,推动运营同学联系用户协助处理; 对于bug类反馈,拉通前端同学共同跟进解决。秉持以用户价值为依归的责任,做到故障反馈“0”容忍。
经过为期半年多的重构,我们解决了收集表长期可用性较低的问题,有效支撑业务在快速增长期稳定运营,在百万级大收集极限业务场景下提供了稳定解决方案,为产品赢得良好用户口碑。
最后也感谢收集表所有前端、后台、产品和运营同学对相关工作的鼎力支持与通力合作!
-End-
原创作者|张瀚元