写点什么

Nextdoor 分布式任务队列系统的演进

  • 2014-08-21
  • 本文字数:1637 字

    阅读完需:约 5 分钟

近日,私密社交网络 Nextdoor 在其官方博客发表了一篇文章,介绍其分布式任务队列系统的演进过程。该系统每天要处理数以百万计的异步任务,包括向数以百万计的邻居发送内容通知、创建搜索索引、以及其它应该从交互式Web 和移动应用程序解耦的耗时的处理过程。它由两部分组成:消息代理(队列)和一组任务工作进程。像其它许多系统一样,他们使用 RabbitMQ 作为消息代理,使用 Celery 作为任务工作进程。在公司规模较小的时候,这些开源项目提供了很大的帮助。但随着用户数的增多,不久前,他们在 Celery 的稳定性方面遇到了问题。即使得到了 Celery 创建者 Ask Solem 本人的支持,但他们仍然会遇到一些问题。最终,他们决定用他们自己开发的项目 Taskworker 替换 Celery。同时,为了减少运维开销,他们用 Amazon SQS 替换了 RabbitMQ。他们的理由是,Amazon SQS 容易理解,具有高可扩展性,而且完全由 Amazon 管理。

文章首先列出了他们在使用 Celery 时面临的三个主要问题:

  1. Celery 工作进程在他们系统的现有规模下不稳定。工作进程经常莫名其妙地宕掉,而且由于其代码库很复杂,很难进行故障排除。
  2. Celery 工作进程无法有效利用系统的计算资源。由于 Celery 不支持优先级队列,所以许多工作进程节点要么未充分利用,要么出现了过载。
  3. Celery 工作进程处理任务的延时经常非常高。

由于上述问题的存在,他们为 Taskworker 设定了三个目标:

  1. 简单:故障排除要简单。
  2. 高效:计算资源的利用要尽可能的高效。
  3. 可扩展:系统应该是完全分布式的,并可横向扩展。

文章接下来详细介绍了 Taskworker 设计及应用到生产环境过程中的一些关键点。

设计决策

基于上述三个目标,他们提出了一种很简单的设计,用 Python 伪代码表示(不包括错误处理和重试逻辑)如下:

复制代码
def run_taskworker():
while True:
queue = select_queue()
tasks = queue.get_tasks()
for task in tasks:
task.run()

在底层,他们会在每个工作进程节点上运行一组 Taskworker 进程,每个进程都运行上面所示的循环。所有进程都是完全独立的。select_queue()函数根据队列的优先级决定从哪个队列获取任务。它既要能优先处理高优先级队列的任务,又要能避免低优先级队列挨饿。

在通过模拟生产负载进行了十多次基准测试后,他们最终选用了一个彩票算法的变体,如下所示:

复制代码
def select_queue():
candidate_queues = get_all_queues()
while not candidate_queues.empty():
queue = run_lottery(candidate_queues)
if queue.empty():
candidate_queues.remove(queue)
else:
return queue
return run_lottery(get_all_queues())

文中还提到,他们要管理十几个或更多不同种类的队列,每个队列包含的任务具有相同的优先级和相似的运行时间。他们在队列层面进行配置设定,包括优先级、SQS 可见性超时以及一次任务处理循环获取的任务数。另外,SQS 在向工作进程发送任务时遵循“至少一次”的语义,这就需要任务必须是幂等的。

应用到生产环境

在这一部分,文章介绍了以下三个方面:

  1. 发布过程:为了保持兼容,SQS 队列和 Taskworker 的版本总是相同。
  2. 能力计划:他们使用 Taskworker 模拟生产负载,以决定在一天中的不同时段如何设置工作进程的能力。
  3. 任务迁移:他们基于每个任务增加了自己开发的开关功能,用于决定是将任务发布到 RabbitMQ 还是 SQS。当开始迁移的时候,他们只需要简单地、一个任务接一个任务地开启开关功能。

结论

截止博文发表时,Taskworker 已经在生产环境中运行了三个多月。他们没有再遇到稳定性问题。在运行相同数量的工作进程节点的情况下, Celery 系统队列中的任务忙时平均延时是 Taskworker 系统的 40 倍。

文章最后指出,Taskworker 还有许多可以改进的地方,而且正在准备开源。


感谢郭蕾对本文的审校。

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

2014-08-21 08:293058
用户头像

发布了 256 篇内容, 共 99.1 次阅读, 收获喜欢 12 次。

关注

评论

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

iVX 研发基座技术与多厂商协作框架深度解析

代码制造者

构架 全栈低代码

PySide vs PyQt:Python GUI开发史诗级对决,谁才是王者?

程序员晚枫

Python 开源 qt GUI

手把手教你如何利用CodeBuddy编写属于自己的AI助手

芯动大师

CodeBuddy首席试玩官

等保测评、黑龙江等保。等保测评公司

黑龙江陆陆信息测评部

Arthas perfcounter(查看当前 JVM 的 Perf Counter 信息)

刘大猫

JVM 监控 Arthas 监控工具 perfcounter

LLM“力大砖飞”的时代,OCR专有模型还有意义吗?

合合技术团队

算法 OCR 大模型 #人工智能

征程 6 yolov5s-rgb-nhwc量化指南

地平线开发者

自动驾驶; 算法工具链 地平线征程6

使用 Databend 全新体验!一文看懂 Databend 可视化管控平台 BendDeploy

Databend

Apache Seatunnel & Amazon Bedrock 助力生成式 AI 应用规模化生产实践

亚马逊云科技 (Amazon Web Services)

【HarmonyOS next】ArkUI-X休闲益智猜字谜【基础】

RunkBear

iOS Developer HarmonyOS NEXT ArkUI框架

哈尔滨等保测评、等保测评公司、机构怎么选

黑龙江陆陆信息测评部

得物自研DSearch3.0搜索核心引擎升级之路

得物技术

搜索引擎

Playwright和Selenium,深度解析两大测试框架的“王者之争”

测试人

软件测试 playwright selenium

HarmonyOS 如何实现传输中的数据加密

网罗开发

鸿蒙 HarmonyOS HarmonyOS NEXT

一键三连不求人!用 CodeBuddy 写个浏览器插件自动点赞、评论、收藏

不惑

CodeBuddy首席试玩官

AIGC 创作者必备!梦精灵提示词管理器让创作效率起飞​

龙正哲

Note16新机594元起,魅族要“逆天”?

趣解商业

科技 汽车 魅族 数码

MCP 协议为何不如你想象的安全?从技术专家视角解读

Baihai IDP

程序员 AI LLM AI Agent MCP协议

《算法导论(第4版)》阅读笔记:p49-p58

codists

算法

INFINI Console 纳管 Elasticsearch 9(一):指标监控、数据管理、DSL 语句执行

极限实验室

elasticsearch console

2个小时!我自己搭建了一套安全管理系统!

中烟创新

2025杭州国际安防产品展会(杭州安博会)团队走进石家庄宣传

AIOTE智博会

安防展 安博会 浙江安博会 杭州安博会

Easysearch 时序数据的基于时间范围的合并策略

极限实验室

Performance merge easysearch

《算法导论(第4版)》阅读笔记:p39-p48

codists

算法

Uniapp开发鸿蒙购物项目实战教程:实现首页轮播图

幽蓝计划

鸿蒙跨平台开发

在Oracle到GreatSQL迁移中排序规则改变引发的乱码问题分析及解决

GreatSQL

联想百应智能体新升级,卡位AI战局的“锁钥之地”

脑极体

AI

HarmonyOS NEXT 跑马灯组件详解

巴库一郎

鸿蒙 HarmonyOS HarmonyOS NEXT 实践分享

中国版 Cursor---腾讯云 CodeBuddy | 从安装VSCode到数独小游戏问世

六月的雨在InfoQ

MCP CodeBuddy首席试玩官 MCP Server MCP头号玩家

Nextdoor分布式任务队列系统的演进_语言 & 开发_马德奎_InfoQ精选文章