Meta降本增效大招之:弃用产品
今晚无意间进入去哪儿技术沙龙的直播间,听到他们要删除50%的代码和停掉50%的服务。我就想起Meta公司最近写的这篇博客:Automating product deprecation。
这篇博客对于效能平台的建设非常具有指导意义。文章最后有原文链接和我个人的总结。
这是一个系列博客。请关注我,我会连载这个系列。
译文:
在Meta,我们通过构建和交付许多不同的产品不断进行创新和尝试,这些产品包含了成千上万的独立功能。作为健康的技术生命周期的一部分,一些产品或功能将不可避免地被弃用。比如,我们在2015年推出了一款叫“Moments”的照片分享应用,后来在2019年停止服务。那么,我们该如何高效、安全地删除与Moments相关的所有代码和数据,而不对Meta的其他产品和服务造成不良影响?
在这个三部分组成的博客系列中,我们将讨论从复杂的产品组合中删除产品时涉及的复杂性,以及Meta为驱动这个过程而构建的框架,即我们的系统代码和资产删除框架(SCARF)。SCARF对Meta产生了重要影响。去年,它删除了存储在21个不同数据系统中1280万种不同数据类型的PB级未使用数据。在过去五年中,它删除了超过1亿行代码。
第一篇文章将介绍在大型组织安全地弃用产品时面临的复杂性,以及我们开发的内部工作流程工具。第二篇文章将解释SCARF如何自动删除死代码以及支持其的基础设施。第三篇文章将讨论SCARF的编排,以安全地识别和删除各种数据系统中的未使用数据类型。
失败模式
如果没有详细的指南来确定何时以及如何删除产品或功能,可能会出现一些失败模式。想象一下,为了某个每隔几年举办一次的大型活动而启动具体时限的功能。将所有相关的代码和数据保留到下一次大型活动是否有意义?大多数情况下,与其多年维护未使用的代码,不如在下次大型活动时重新开发。
尝试清理的工程师可能会发现这是一项非常耗时的工作。正确识别与产品相关的所有代码和数据,并仅针对这些特定的代码和数据进行删除是一个费力的过程。仍在使用的表或共享用例仍需要的代码可能会被错误地包含在删除范围内。例如,某些表可能在产品之间共享。假设在成为独立应用之前,Moments可能是作为Facebook照片功能的扩展而诞生的。
最重要的是,任何清理工作只能删除已经停用或完全未使用的内容,这一点至关重要。删除正在生产中使用的内容可能会给用户糟糕的体验。像Facebook这样大型产品中功能的高度互相关联性使这种情况成为一个非常现实的可能。
我们是如何解决这个问题的?
Meta开发了一些手册来描述如何安全地弃用产品。这些手册阐述了如何通知用户并给他们时间下载数据、如何安全地禁用产品以及何时最终删除底层代码和数据。它们描述了如何以及何时执行产品或功能的弃用,但实际上删除产品或功能的代码和数据是工程问题的工程解决方案。我们构建的工程解决方案并不是要取代这些指南,而是使工程师能够更安全、更高效地完成产品弃用流程。
在这篇文章中,我们将描述Meta的SCARF以及它如何指导工程师完成此清理过程。在后续文章中,我们将讨论它的局限性以及如何通过我们的自动死代码和数据删除平台来缓解这些局限性。首先,我们介绍Meta的内部工具套件,这些工具是为了协调这两个系统而开发的,以指导工程师删除具有复杂依赖关系的大型产品。
引入工作流程管理
为了简化删除产品的任务,Meta在SCARF中内置了产品弃用工作流管理工具,帮助工程师安全高效地删除产品的死代码和未使用数据。该工具让工程师了解并拆分他们在弃用期间将经历的步骤,并协调SCARF的操作,使自动化符合工程师的指导。
确定弃用范围
了解产品的其他组件何时使用一段代码或数据非常重要,而检测其他产品代码中何时引用资产对于安全弃用(区分内部和外部依赖)至关重要。比如,我们不想在两个不同的产品之间留下无效的网络链接,因为这可能导致糟糕的用户体验。弃用产品的工程师必须仔细考虑产品外部边界中的每一个此类依赖。
为了避免这些复杂性,工程师通过确定项目范围、递归添加应该删除的任何资产以及标记应该切断的依赖关系来启动弃用。比如,如果Moments与Facebook应用的共享功能集成,则必须断开这种依赖,因为Facebook共享功能本身可能不在删除范围内。

但是,如果共享功能是Moments独有的,那么这将改变删除的范围,因为我们也想删除该组件。随着项目的进展,将新资产添加到项目范围中需要进一步分析以发现内部和外部依赖关系的新边界。当工程师发现需要删除的额外组件时,这些依赖关系预计会随着时间的推移而变化。或者,我们可以识别实际上是共享组件且不应该删除的代码。试图从一开始就确定这个边界是非常困难的,因此我们允许开发者随着弃用的进展重新定义边界,以反映这种不断增长的理解。
在大型产品中,组件图、其内部和外部依赖以及相关数据资产可能非常复杂。SCARF简化了这个问题,只要求工程师在边界做出“标记依赖”或“添加到项目”的决定。然后,它在内部计算项目内所有内容的正确删除顺序。

创建删除路线图
一旦确定了要删除的未使用资产集合,SCARF将分析内部和外部依赖性并创建删除路线图,概述安全删除所有内容的正确步骤顺序。路线图每天都会随着变更而刷新,无论是删除目标资产还是通过“标记”和“添加”操作修改组件图。该路线图是工作流管理工具最重要的功能之一。
如果没有指导,工程师可能会尝试通过删除整个代码目录来一次性删除所有内容,而不考虑外部系统的依赖,而外部系统的依赖无法以原子方式提交。另一个例子包括在读取和写入数据的代码之前删除数据,这可能导致创建必须再次清理的新数据。弃用必须交错进行,以适应这些不同的要求,这意味着每次弃用都必须以协调的、多步骤的过程执行。
关键的实现细节是业务逻辑的编码,使产品和应用程序能够在Meta的系统中运行。通过对用户如何与产品互动以及这些产品如何与其他Meta服务通信进行编码,我们可以确保上游资产总是在其依赖项之前被删除。例如,通常一个产品将包含跨多个存储库的多种不同语言的代码。工程师需要删除他们的移动代码(Java、Objective-C),以便释放和删除他们的服务器端GraphQL定义。删除这些GraphQL定义就可以删除业务逻辑;删除业务逻辑可以删除数据模式定义,从而可以删除未使用的数据。
下图是一个假设示例,展示了在工程师的删除路线图中呈现的信息类型。

这个顺序一开始并不明显!这些系统边界之间的联系通常比同一语言中的两个类之间的联系更弱;并且该联系通常只能由工程师在对其代码变更请求进行连续测试期间发现。SCARF对这些系统间边界的编码支持删除路线图,从而使工程师能够安全地错开他们的删除操作。
为分析提供动力
SCARF的工作流管理工具由静态和动态分析相结合的详细指标提供支持。关于代码的信息是从SCARF的统一代码依赖关系图中收集的,关于数据的信息是从SCARF的数据资产使用分析中收集的。这些机制将在我们后续的博客文章中有更详细的讨论。
这些指标为工作流管理工具提供了一个非常重要的属性:如果可以找到资产的指标,则该资产正在使用中,并且应该阻止自动删除。相应地,任何没有可用指标的资产都可以自动删除。有了这些指标,SCARF就可以向工程师准确解释到底是什么阻碍了自动化,以及他们必须手动执行哪些步骤才能使自动化继续进行。
这种完整性属性允许SCARF自动开始删除未使用的代码和数据,同时向工程师展示哪些事情必须手动处理。在该过程的每一步中,工程师和自动化都会共同努力完成弃用。
一旦工程师根据这些信息采取行动并根据删除路线图删除了更多死代码和未使用数据,SCARF的持续索引和分析将检测这些更改并自动触发它可以进行的任何代码/数据清理。最后,工作流管理工具将更新其删除路线图,以识别下一组需要手动干预的项目,并重复该过程。

自动化就足够了吗?
SCARF强调的一些使用信号(例如仍在接收流量的API端点)如果被忽略,并不一定会导致编译错误,对于是否应该停止自动删除更主观。如果产品的某个端点每天收到一个请求,我们是否应该立即删除它?我们已经确定该端点属于我们要删除的产品,因此我们知道它最终应该被删除,但何时正确删除它的答案最终取决于业务决策。此外,我们知道错误是可能发生的,自动化也不会100% 完美。因此,SCARF需要谨慎行事,因为错误的删除可能导致不可恢复的错误或数据丢失。
相应地,SCARF提供了覆盖阻止自动化采取行动的信号的功能。在上面的例子中,工程师可能会决定我们希望继续删除API端点,尽管流量很小。这在清理内部产品、工具和服务时非常有价值。内部工具的构建和弃用的节奏通常比外部产品快得多,SCARF可以帮助确定每个内部用户工具,需要询问他们是否同意删除该工具。
此功能在工程师和自动化之间创建了反馈循环。我们的自动化会突出显示使用信号;然后,工程师对这些使用信号进行分类(通过修改代码来删除它们,或者如果适用,将信号标记为不足以阻止删除);那么我们的自动化就可以继续推进SCARF项目了。
为了进一步加快工程师手动更改的速度,SCARF还提供了即时代码更改功能。SCARF提出了一种通过有针对性的代码更改来断开依赖关系的方法,工程师可以从一组预定义的可选方法中选择一个来断开依赖。更改可以立即预览,并可以立即生成更改请求以供其他工程师审核。
在工程师完成大部分删除路线图并删除入口点、客户端代码、服务器代码和范围内的任何其他资产后,他们将留下未使用的数据表,这些数据表现在可以由SCARF自动清理。我们将在未来的博客文章中更详细地解释这种自动化。
与 Meta 上的其他工具集成
SCARF的用途不仅仅是产品弃用。当通知工程师关于单个资产的日常维护或升级工作时,我们会提供弃用作为一个选项。例如,当要求开发者迁移旧的内部API时,我们可以为他们提供一个选项,将调用方或受影响的产品弃用并导入SCARF。在许多情况下,弃用某些东西可能比执行简单的升级需要更多工作,但弃用意味着将来不需要进行维护。一旦移除某些内容,未来的维护成本就会为零。
译完
原文链接:https://engineering.fb.com/2023/10/17/data-infrastructure/automating-product-deprecation-meta/
我的总结:
1. 弃用产品是降本增效的一种手段。
2. 如何以及何时执行弃用,是一个产品运营问题。
3. 如何让工程师能够更安全、更高效地完成产品弃用流程是一个工程问题。SCARF框架就是为了解决此问题。其实放在国内,可能是效能平台的一个功能。
4. 工程师在弃用产品的过程中可能会出现的问题:
1. 工程师无法轻松地确定弃用的范围;
2. 弃用的步骤可能取决于业务代码的逻辑,也就是弃用步骤是视情况而定的。
5. 弃用产品的内容包括:代码、数据。
6. 这个框架的内容如下:
1. 打弃用标记:工程师可以通过工具,或者在平台上对要进行删除的资产(代码、文档等等)和要断开的依赖关系进行标记;
2. 分析依赖关系以确定弃用范围:SCARF通过分析依赖关系,确认弃用范围;
3. 输出弃用路线图:SCARF将分析内部和外部依赖性并自动创建删除路线图,概述安全删除所有内容的正确步骤顺序。其中可能有些步骤必须手动执行。路线图不是静态的,它会随外部条件变化而变化。
4. 在工程师删除代码后,未使用的数据表,可以由SCARF自动清理。
下一篇将介绍如何自动删除无用代码。请记得关注我。
相关文章:
Meta降本增效大招之:弃用产品
今晚无意间进入去哪儿技术沙龙的直播间,听到他们要删除50%的代码和停掉50%的服务。我就想起Meta公司最近写的这篇博客:Automating product deprecation。 这篇博客对于效能平台的建设非常具有指导意义。文章最后有原文链接和我个人的总结。 这是一个系列…...
Adobe Illustrator——原创设计的宝藏软件
今天,我们来谈谈一款在Adobe系列中曾经多次给大家都提到的原创性极强的设计理念丰富的矢量图形编辑软件——Adobe Illustrator。 Adobe Illustrator,其定位是一款与Photoshop相类似对矢量图形进行编辑的软件。 Adobe Illustrator,作为全球最著…...
LEEDCODE 220 存在重复元素3
class Solution { public:int getId(int a, int valuediff){// 值// return a/(valuediff1);return a < 0 ? (a ) -) / (valuediff 1) - 1 : a / (valuediff 1);}public: unordered_map<int, int> bucket;bool containsNearbyAlmostDuplicate(vector<int>&am…...
从内网到公网:使用Axure RP和内网穿透技术发布静态web页面的完整指南
文章目录 前言1.在AxureRP中生成HTML文件2.配置IIS服务3.添加防火墙安全策略4.使用cpolar内网穿透实现公网访问4.1 登录cpolar web ui管理界面4.2 启动website隧道4.3 获取公网URL地址4.4. 公网远程访问内网web站点4.5 配置固定二级子域名公网访问内网web站点4.5.1创建一条固定…...
第三天课程 RabbitMQ
RabbitMQ 1.初识MQ 1.1.同步和异步通讯 微服务间通讯有同步和异步两种方式: 同步通讯:就像打电话,需要实时响应。 异步通讯:就像发邮件,不需要马上回复。 两种方式各有优劣,打电话可以立即得到响应&am…...
Ubuntu18.04编译OpenCV时遇到无法下载ADE的问题
安装OpenCV过程中编译时出现下载ADE失败的问题 报错如下: -- ADE: Downloading v0.1.2a.zip from https://github.com/opencv/ade/archive/v0.1.2a.zip -- Try 1 failed CMake Warning at cmake/OpenCVDownload.cmake:248 (message):ADE: Download failed: 28;&quo…...
基于JavaWeb+SSM+社区居家养老服务平台—颐养者端微信小程序系统的设计和实现
基于JavaWebSSM社区居家养老服务平台—颐养者端微信小程序系统的设计和实现 源码获取入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 前言 在复杂社会化网络中,灵活运用社会生活产生的大数据&am…...
算法实战:亲自写红黑树之五 删除erase的平衡
本文承接自: 算法实战:亲自写红黑树之一-CSDN博客 算法实战:亲自写红黑树之二 完整代码-CSDN博客 算法实战:亲自写红黑树之三 算法详解-CSDN博客 算法实战:亲自写红黑树之四 插入insert的平衡-CSDN博客 目录 一、入口…...
春秋云境靶场CVE-2021-41402漏洞复现(任意代码执行漏洞)
文章目录 前言一、CVE-2021-41402描述二、CVE-2021-41402漏洞复现1、信息收集1、方法一弱口令bp爆破2、方法二7kb扫路径,后弱口令爆破 2、找可能可以进行任意php代码执行的地方3、漏洞利用找flag 总结 前言 此文章只用于学习和反思巩固渗透测试知识,禁止…...
12 Go的接口
概述 在上一节的内容中,我们介绍了Go的作用域,包括:局部作用域、全局作用域、命名空间作用域等。在本节中,我们将介绍Go的接口。Go语言中的接口是一种类型,它定义了一组函数的集合。接口是一种抽象的描述,它…...
Python编程-----并行处理应用程序
目录 一.进程 二.线程 三.Python标准库中并行处理的相关模块 Threading模块 (1)使用Thread对象创建线程 (2)自定义派生于Thread的对象 (3)线程加入join() (4)用户线程和daemon线程 (5)Timer线程 线…...
kubernetes集群编排——istio
官网:https://istio.io/latest/zh/about/service-mesh/ 部署 [rootk8s2 ~]# tar zxf istio-1.19.3-linux-amd64.tar.gz [rootk8s2 ~]# cd istio-1.19.3/[rootk8s2 istio-1.19.3]# export PATH$PWD/bin:$PATH demo专为测试准备的功能集合 [rootk8s2 istio-1.19.3]# i…...
mfc140u.dll丢失的解决方法,以及mfc140u.dll解决方法的优缺点
在使用电脑过程中,有时会遇到一些与动态链接库文件(DLL)相关的错误。其中,mfc140u.dll丢失的错误是较为常见的一种。当这个关键的mfc140u.dll文件丢失或损坏时,可能会导致某些应用程序无法正常运行。在本文中ÿ…...
2源码安装网络协议
2.2源码安装/网络协议 一、源码包应用场景 有时我们所用的内核版本太旧,系统自带的库(如libstdc.so.6)版本低或者依赖的其他软件版 本较低,导致无法安装目标软件。 软件/库其实是对机器汇编指令集的封装,在X86体系下…...
未来服务器操作系统的趋势与展望
摘要: 随着云计算、大数据和人工智能不断的发展,服务器操作系统也需要随之进行新一轮的升级。本文通过分析当前服务器操作系统的现状,探讨了未来服务器操作系统的趋势和展望,并针对一些关键问题提出了解决方案。 一、引言 服务器…...
VB.net WebBrowser网页元素抓取分析方法
在用WebBrowser编程实现网页操作自动化时,常要分析网页Html,例如网页在加载数据时,常会显示“系统处理中,请稍候..”,我们需要在数据加载完成后才能继续下一步操作,如何抓取这个信息的网页html元素变化&…...
自建ES6.2.4切阿里云商业版ES(7.10)整体方案
一、切换目的&阿里云商业版ES版本选择 1.1 升级切换阿里云商业版7.10目的 自建的Elasticsearch服务运维难度高,操作复杂,需要手动调整资源,遇到性能瓶颈时优化难度相对云上Elasticsearch较大。使用阿里云提供的ES服务,提高系统稳定性使用云服务es,易于备份,数据恢复…...
Vue实现封装自定义指令
目录 一、什么是自定义指令? 二、自定义指令的使用 Vue中的自定义指令使用Vue.directive函数进行定义。该函数接受两个参数,第一个是指令名称,第二个是指令选项对象。 上述代码中,我们定义了一个名为my-directive的自定义指令…...
<MySQL> 查询数据进阶操作 -- 聚合查询
目录 一、聚合查询概述 二、聚合函数查询 2.1 常用函数 2.2 使用函数演示 2.3 聚合函数参数为*或列名的查询区别 2.4 字符串不能参与数学运算 2.5 具有误导性的结果集 三、分组查询 group by 四、分组后条件表达式查询 五、MySQL 中各个关键字的执行顺序 一、聚合查询…...
arm开发板
一个简单的hello world程序 minicom用来和开发板之间交互并且可以向开发板传输文件。打印hello world字符串。在linux虚拟机上编译我的代码,使用的交叉编译工具是arm-linux-gnueabihf-gcc (hard float) 可以使用 readelf -h libc.so.6 查看开发板是不是(…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
