写点什么

Facebook 如何使用 Haskell 处理垃圾邮件

  • 2015-08-10
  • 本文字数:2122 字

    阅读完需:约 7 分钟

Facebook 使用一个名为 Sigma 的系统打击垃圾邮件、恶意软件及其它恶意行为。该系统的任务是主动发现这些行为,并自动删除检测到的不良内容,避免它们在用户的动态消息中显示。最近,他们完成了为期两年的 Sigma 重新设计工作,用 Haskell 取代了仅在 Facebook 内部使用的 FXL 语言。现在,基于 Haskell 的 Sigma 系统已经应用于生产环境,每秒为 100 多万请求提供服务。对于像 Sigma 这样的大型生产系统而言,Haskell 不是一个常用的选项。Simon Marlow 是一名 Facebook 软件工程师,同时也是 Haskell 社区的领军人物。近日,他撰文解释了他们做出这种选择的原因,并分享了经验。

Sigma 是一个规则引擎,就是说它运行一组规则,Facebook 称之为策略。Sigma 会用那些规则评估 Facebook 上的每次交互,以便识别和阻止恶意交互,防止它们影响 Facebook 用户。策略是持续部署的,任何时候,代码库中的源代码都是 Sigma 中运行的代码。这样,它们可以对新出现的恶意行为作出快速响应。同时,这也要求他们用于编写策略的语言是安全的。

起初,他们使用自己设计的 FXL 语言编写策略,但随着扩展性需求和复杂性的增加,FXL 不再是理想的选择。它缺少一些抽象机制,比如用户定义类型和模块,而且它的实现是以一个解释器为基础,速度不够快。因此,他们希望选用一种现有的语言。下面是他们重点考虑的几个因素:

  1. 纯函数式强类型语言:确保策略不会在无意间相互交互,可以单独测试,并且不会导致 Sigma 系统崩溃;强类型有助于在策略部署到生产环境之前减少许多 Bug;
  2. 自动批处理和并发获取数据:策略通常需要从 Facebook 的其它系统获取数据,为了提高效率,他们希望系统默认使用并发,即隐式并发;
  3. 在几分钟内将修改后的代码推送到生产环境,即他们可以快速部署或更新策略;
  4. 性能:FXL 性能较差,他们需要使用 C++ 开发一些对性能要求较高的功能,增加了变更发布时间;
  5. 支持交互式开发:开发人员可以交互地试验和测试策略代码并立即看到结果。

Haskell 非常适合:它是强类型的纯函数式语言,有成熟的优化编译器和交互式环境(GHCi),并且有他们需要的抽象机制。此外,它还有丰富的库和活跃的开发者社区。因此,上述列表中还有两项特性有待处理:

  • 自动批处理和并发:在 Haskell 中,现有所有的并发抽象都是显式的,就是说需要用户自己指出什么应该并发。但他们希望有一个编程模型,使系统在可以并发的时候自动并发。为此,他们开发了 Haxl 框架。它可以使多个数据获取操作自动批处理和并发执行。感兴趣的读者可以阅读他们先前发表的博文论文以及查看其 GitHub 页面。此外,他们还在 GHC 中实现了 Applicative do-notation
  • 已编译代码的热切换:他们希望任何提交到策略库的新代码尽快在每台机器的 Sigma fleet 上运行。他们希望动态地在运行中的 Sigma 进程中更新已编译的规则。修改正在运行的程序代码非常困难,但他们的情况相对简单:向 Sigma 发起的请求很短暂,所以他们不需要将一个正在运行的请求切换到新代码,而是等待现有的请求结束,然后用新代码为新请求提供服务。目前,他们使用 GHC 内置的运行时链接器加载和卸载代码,而卸载旧版本代码还要用到垃圾收集器

Haskell 位于 Sigma 中两个 C++ 层之间。上面一层是 C++ thrift 服务器。其实,这里也可以用 Haskell 作为 thrift 服务器,但 C++ thrift 服务器更成熟,性能更好,功能更丰富,并且可以与下面的 Haskell 层无缝集成,因为他们可以从 C++ 调用 Haskell。最底层是与外围服务交互的 C++ 客户端代码。他们使用 Haskell 的外部函数接口(FFI)将 C++ 客户端封装成一个 Haxl 数据源,那样,他们就可以从 Haskell 使用它。

他们对 Sigma 所服务的 25 种常见类型的请求进行了测试。结果表明,对于特定的请求,Haskell 的性能是 FXL 的 3 倍。Haskell 的吞吐量整体上比 FXL 高 20% 到 30%。为了,他们做了大量艰苦的工作,优化 Haskell 代码,确定和解决性能瓶颈,其中包括修改 GHC 的堆管理方式修复 Haskell JSON 解析框架 aeson 的一个性能缺陷等。

此外,Simon 还介绍了其它几项重要的工作,包括:

  • 资源限制:为了确保单个请求不因占用过多资源而导致其它请求的响应速度降低,他们在 GHC 中实现了资源分配限制,设定一个线程在被动终止之前可以获得的内存上限。
  • 交互式开发:为了实现交互式开发,他们需要将 GHCi 环境与他们的整个技术栈集成,包括从命令行向其它后台服务发送请求。为此,他们必须让构建系统将代码的所有 C++ 依赖都链接到一个 GHCi 可以加载的共享目录。此外,他们还定制了 GHCi 前端,实现了部分自有命令,简化了工作流程。
  • 打包和构建系统:他们发现,托管在 Hackage 上的 Haskell 开源包变化非常快,而且并不是所有包组合都可以很好地工作。因此,使用这些包意味着更多繁琐的工作。于是,他们切换到了 Stackage 。Stackage 提供了已知可用的包的版本组合。

要了解更多信息,可以查看 Protect the Graph 页面,或者观看他们最近的反垃圾邮件@Scale 活动视频。


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-08-10 19:373496
用户头像

发布了 1008 篇内容, 共 393.0 次阅读, 收获喜欢 344 次。

关注

评论

发布
暂无评论
发现更多内容

工业互联网数据处理架构

刘旭东

kafka IoT 工业互联网

聊聊hashmap

急需上岸的小谢

11月月更

聊聊ThreadLocal

急需上岸的小谢

11月月更

部署代码质量检测服务 sonarqube,基于命令、shell 脚本和 pipline 实现代码质量检测

忙着长大#

jenkins

聊聊Go里面的闭包

秦怀杂货店

Go 函数式编程 闭包

第九期 - 模块七

wuli洋

Dockerfile 常用命令

蜗牛也是牛

2022-11-20:小团生日收到妈妈送的两个一模一样的数列作为礼物! 他很开心的把玩,不过不小心没拿稳将数列摔坏了! 现在他手上的两个数列分别为A和B,长度分别为n和m。 小团很想再次让这两个数列变

福大大架构师每日一题

算法 rust 福大大

Java中的System类

共饮一杯无

Java 11月月更 system类

制订需求分析框架和分析计划

穿过生命散发芬芳

需求分析 11月月更

【愚公系列】2022年11月 微信小程序-场景值

愚公搬代码

11月月更

iMazing2022免费试用版ios设备管理器

茶色酒

imazing imazing2023

极客时间运维进阶训练营第四周作业

chenmin

Docker部署flink备忘

程序员欣宸

Docker flink 11月月更

计算机网络:PPP协议与HDLC协议

timerring

计算机网络 11月月更

开发H5都会喜欢这个Vite插件

小鑫同学

前端 插件 11月月更

极客时间运维进阶训练营第四周作业

老曹

MongoDB源码学习:Mongo中的OpRunner

云里有只猫

mongodb 源码学习

SpringCloud相关组件

急需上岸的小谢

11月月更

kitti数据集在3D目标检测中的入门

Studying_swz

3D点云 11月月更

【web 开发基础】PHP 的函数工作原理 (28)

迷彩

函数 web开发基础 11月月更 结构化编程 函数的工作原理

其实你的下班时间,被 Excel 预定了

叶小鍵

支持向量机-支持向量机分类器原理

烧灯续昼2002

Python 机器学习 算法 sklearn 11月月更

jenkins pipline 基本语法

忙着长大#

RESTful API类渗透测试的特点

阿泽🧸

RESTful API 11月月更

CleanMyMac2023注册机mac系统清理工具

茶色酒

CleanMyMacX CleanMyMac X

主成分分析PCA与奇异值分解SVD-PCA对手写数据集的降维 & 用PCA做噪音过滤

烧灯续昼2002

Python 机器学习 算法 sklearn 11月月更

企业级业务架构设计笔记三:设计起点与设计过程

程序员架构进阶

架构 业务架构 11月日更 11月月更

AST 初探深浅,代码还能这样玩?!

蔡农曰

前端 后端 代码

[力扣] 剑指 Offer 第四天 - 0~n-1中缺失的数字

陈明勇

Go 数据结构与算法 力扣 11月月更

主成分分析PCA与奇异值分解SVD-降维后的矩阵components_ & inverse_transform

烧灯续昼2002

Python 机器学习 算法 sklearn 11月月更

Facebook如何使用Haskell处理垃圾邮件_Meta_谢丽_InfoQ精选文章