Meta降本增效大招之:自动清理死代码

b3ef62949efdf3b3c64140cbd41b5c0f.jpeg

这是一个系列博客。介绍的是Meta如何通过弃用产品、清理代码、删除数据以实现降本增效。这对于效能平台的建设非常具有指导意义。

上一篇介绍的是如何自动弃用产品,本篇介绍的是Meta是如何实现自动清理死代码。

请关注我,我会连载这个系列。下一篇将介绍如何自动化删除数据。

文章最后有原文链接和我个人的总结。懒的同学,可以翻到文章最后。

译文:

在我们关于自动弃用产品的最后一篇博客中,我们谈到了弃用产品的复杂性,以及Meta构建的名为“系统代码和资产清理框架(SCARF)”的解决方案。以“Moments”为例,这是Meta于2015年推出的照片分享应用程序,最终于2019年关闭。我们探讨了SCARF如何通过其工作流管理功能在弃用过程中提供帮助。我们讨论了SCARF如何通过识别清理产品的正确任务顺序来节省工程时间,以及在存在跨系统依赖关系时如何阻止自动清理。这自然引出了一个问题:当存在引用资产的代码时,我们如何自动解除SCARF的阻塞?

SCARF中的死代码清理系统

SCARF 包含一个子系统,可通过静态、运行时和应用分析组合自动识别死代码。它利用这种分析来提交更改请求(Change Request),以便从我们的系统中删除这些代码。这种自动删除无效代码的方法提高了系统的质量,当无效代码中包含的数据资产引用阻碍了自动数据清理时,还能解除 SCARF 中未使用数据删除的阻塞。

代码分析

SCARF的代码分析子系统从各种来源收集信息。首先,通过Glean从我们的编译器中提取每种语言的代码依赖图。然后,通过操作日志获得的API端点的使用情况对其进行了增强,以确定端点是否在运行时被使用。比如以下特定领域的代码分析的案例:

  • • 内部开发工具和系统管理命令的脚本调用。

  • • 用于在Instagram Django后台动态呈现页面的模板钩子以及URI处理程序和路由。

  • • Async的动态引用调度方法(Meta的延迟作业执行服务)。

除了静态依赖关系图之外,SCARF 还必须能够检测任何和所有类型的动态使用情况,以便准确判断一段代码是否真的可以安全删除。SCARF 将这些信息结合起来,形成一个增强的依赖关系图。

f6cb92f97382f980be16504e212d6a68.png

SCARF支持多种编程语言。这一点非常重要,因为Meta产品的客户端代码可能是用Java、Objective-C和JavaScript编写的,服务器代码是用Hack编写的,还有一些后端基础架构是用 Python 编写的。所有这些代码都应删除,因为它们通过API和其他已知形式的动态和跨语言引用关联在一起,从而形成了相同的依赖关系图。

SCARF在符号级而非文件级运行,因此可以进行更精细的分析和清理。例如,函数中未使用的单个变量将有自己的完全限定符号,这样就可以进行比文件级更精细的清理。

垃圾回收

SCARF会分析增强的依赖关系图,找出无法到达的节点和可以删除的子图,并自动生成代码更改请求,每天删除相应的代码。分析完整图的一个主要好处是,我们可以检测并删除代码库不同部分相互依赖的循环。删除整个子图可以加快删除死代码的速度,并为利用这种自动化进行废弃处理的工程师提供更好的体验。

图形包含增强信息非常重要,因为仅靠静态分析可能无法揭示通过动态引用或运行时语言特性创建的组件之间的联系。但这需要权衡利弊,因为用动态使用信息来增强图表需要对索引代码进行全面处理,还需要后续的数据分析管道来提供指标。这就增加了整个过程的端到端持续时间,从而使新特性或功能的原型开发变得更加困难。

SCARF 的早期版本通过采取不同的方法避免了这种前期成本。它单独分析每个可发现的符号,并在运行时运行查询静态和动态引用的分类器,以便找到死根节点 - 没有入站依赖项的代码片段。这不需要预先构建完整的依赖关系图,并简化了在代码库的小子集上运行系统的过程。因此,在不需要耗时的索引或数据分析的情况下,构建新的分类器原型来识别潜在的动态引用是微不足道的。

然而,更长的端到端开发周期导致覆盖范围显着提高。从分析单个符号到分析整个图表的转变导致从 Meta 最大的代码库之一中删除的死代码增加了近 50%。新方法提高了对代码库状态的可见性:有多少是活着的,有多少是死的,以及我们在 SCARF 的任何给定通道中删除了多少。

调依赖关系图

我们使用 Glean 索引的许多依赖关系都是代码调用模式,并不一定会阻止代码的删除。例如,假设我们有一个 PhotoRenderer 类,它的唯一依赖关系在如下代码中:

if isinstance(renderer, PhotoRenderer):
    return renderer.render_photo()
else:
    return renderer.render_generic()

在这种情况下,可以删除对PhotoRenderer和render_photo()的引用,并将代码更改为:

return renderer.render_generic()

在这个例子中,PhotoRenderer 类是根据 Python 语义中的一条规则内联的:如果没有任何地方实例化了 PhotoRenderer 类,我们就可以确信这段代码不可能使用第一个分支,因此它是死的。

在某些情况下,我们根据应用程序语义而不是语言语义来推导这些规则。想象一下这段代码

uri_dispatch = {
  '/home/': HomeController,
  '/photos/': PhotosController,
  ...
}

如果我们只分析语言级的依赖关系图,就不可能确定 PhotosController 是否被引用过,因为它可以通过 URI 调度机制调用。但是,如果我们从应用程序分析中得知"/photos/"端点在生产中从未收到过任何请求,那么我们就可以从字典中删除相应的条目。

鉴于 Python 的语言语义,我们没有固有的方法来推断这一点,但我们的特定领域日志和图增强允许我们告知 SCARF 此操作是安全的。

自动代码更改

在Meta,我们大量自动化代码更改。我们构建了一个内部服务,称为CodemodService,它使工程师能够部署配置以自动批量更改代码。SCARF是Meta首次在全公司范围内实现全自动代码更改的实例,它是与CodemodService携手打造的。如今,CodemodService还为Meta的数百种其他类型的自动代码更改提供了支持,包括自动格式化代码、自动删除已完成的实验、支持大规模API迁移,以及提高Python和Hack等部分类型语言的强类型覆盖率。

大规模死代码清理

SCARF 使用CodemodService创建代码变更请求,供工程师审查。这些更改请求包含人类可读的描述,告知工程师确定目标代码已证明无效的分析结果。

7cb1f337b77e59cebf24c8a1ba51b501.png

SCARF已经发展到分析数亿行代码;五年来,它已经自动删除了超过1亿行代码,涉及超过37万个更改请求。在代码审查中由工程师捕获的假阳性被分类并用于改进SCARF的分析,通常反映了我们的增强图必须考虑的新的动态使用来源。有时,这些被误解的动态引用可能导致代码错误的删除,并且这些删除可能会进入生产环境。Meta还有其他机制来捕获这些问题,我们非常重视这类事件。

在某些语言中,我们对我们的分析有如此高的信心,以至于可以自动接受和合并更改请求,而无需人工干预,以更好地利用工程师宝贵的时间。

死代码清理足够吗?

SCARF的自动死代码清理加速了关闭和删除废弃产品的代码和数据的过程,但并没有完全解决。除了由互连性引起的问题外,我们不断改进我们跨所有语言、系统和框架的整合能力。准确覆盖启用系统确定什么是真正的死亡的每一种代码和数据的用途是困难的。

我们的系统也倾向于慎重行事,通过我们的BigGrep系统搜索对代码和数据的文本引用,而不仅仅依赖于Glean和我们的动态使用增强产生的精心策划的图。这是一个后备安全机制,有助于避免在其他语言中以名称引用的MySQL表被意外删除,并防止在Hack、Python和JavaScript等语言中调用代码通过字符串引用或使用eval。这种方法可能导致假阴性,但避免了假阳性。在自动删除死代码时,这些是一个更严重的问题。

正如我们在本系列的第一篇博客中提到的,SCARF提供与死代码子系统共同运作的工作流管理功能,为完全弃用产品和功能提供了一致的体验。至关重要的是,我们的工程师可以比我们的自动化更快地迭代代码更改!如果工程师了解更改已使代码的一个分支(因此整个子图)不可访问,他们可以轻松地将该删除合并到其更改中,而无需等待我们的基础设施索引新代码,分析它,最终提交其自动更改。有时,工程师发现手动删除东西比等待自动系统稍后清理更有效率。

在本系列的下一篇也是最后一篇博客中,我们将讨论SCARF的未使用数据类型子系统,该子系统与死代码子系统一起,通过自动删除死和未使用的资产,增强了Meta的数据最小化能力。

译文完

原文链接:https://engineering.fb.com/2023/10/24/data-infrastructure/automating-dead-code-cleanup/

个人总结

  • • 截止2023年,SCARF已经发展5年,自动清理了超过1亿行代码,涉及超过37万个Change Request。

  • • SCARF的核心是代码依赖图。

  • • 死代码的判断依据:

    • • 没有到达的节点或子图;

    • • 一段时间(没有规定)内没有流量的代码。

  • • 代码依赖图需要

    • • 支持多语言及跨语言引用;

    • • 不仅要支持文件级别,还要支持符号级别级别;

    • • 支持从API端点到函数级别

    • • 依赖图是可以被工程师进行微调的

  • • 构建代码依赖图的方式:

    • • 静态分析:通过Glean(https://glean.software/)

    • • 动态分析:通过运行时日志与代码进行关联;也就是说分析该API是否有外部请求。

  • • 工程方面:

    • • 在Meta,CodemodService服务负责大量自动化代码更改、格式化、删除已经完成的实验等。它是与SCARF一同构建的。

    • • SCARF每天分析依赖图,识别死代码,并使用CodemodService发起Change Request。

    • • 工程师可以对Change Request进行“假阳性”误删判断,并将其反馈给SCARF,以改进SCARF分析。

    • • 通过BigGrep系统对代码和数据的文本引用,排除一些特殊的case,如在Glean不支持的语言中引用了某个MySQL表名。

本文完

往期好文推荐:

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码
应用背景为变电站电力巡检,基于YOLO v4算法模型对常见电力巡检目标进行检测,并充分利用Ascend310提供的DVPP等硬件支持能力来完成流媒体的传输、处理等任务,并对系统性能做出一定的优化。.zip深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值