Celery: 建议弃用 Redis 作为代理支持。 [拒绝了]

创建于 2016-06-24  ·  54评论  ·  资料来源: celery/celery

如果我们取消对 Redis 的支持,我们就可以将时间集中在 RabbitMQ 或 Kafka/nsq 上。
在 Python 3 中移植到 asyncio 也是一项艰巨的任务。

我认为应该认真考虑这一点。 如果我们是为了好玩而做这件事,那么交通工具的受欢迎程度应该无关紧要。

最后我会选择我有能力做的事情,但至少你可以在这里表达你的担忧。

Project Governance

最有用的评论

你好。 我在 Redis Labs 工作,直到最近我还是 celery 用户。 @thedrow引起了我的注意,我们已经在内部讨论了这个问题。 我们愿意帮助你们,我们认为将 redis 作为 celery 的一部分很重要。 我还不确定我是亲自还是其他人来做这件事,但让我们讨论一下需要做的事情。

所有54条评论

现在存在芹菜的替代品,例如hueyrq明确专注于支持 redis 作为代理。 当 celery 发布时,什么都没有。

@ask你对放弃 sql broker 支持有什么看法? 我怀疑有很多人在生产中使用 sql 数据库。 即使他们这样做了,他们实际上也不应该这样做。
我们还有 docker,这意味着部署 rabbitmq 只需一个命令。 这不再_那_难了。

我刚刚放弃了对 SQL 作为代理的支持,包括除 RabbitMQ / Redis / SQS / Qpid 之外的所有其他代理 :)

(复制)

我与 celery 社区并没有那么紧密的联系。 不管我的 0.02 美元:

  • Redis 真的很受欢迎 - 如果您认为 Google Trends 具有代表性,那么它与所有其他受支持的 Broker _combined_ 一样受欢迎
  • 它能够成为一个非常好的代理 _and_ 后端(虽然 RabbitMQ 也是如此)
  • 它由大型云供应商独家提供,作为完全托管的服务
  • 我们经常使用Redis!

我可以理解您对维护问题的看法,这种行动是迈向可持续发展的一步。 但是你还能做其他“截肢”吗?

在等式的“供应”方面,您有什么想法为什么社区没有对 celery 做出更多贡献?
粗略地看一下提交和 PR 表明 celery 主要是一个人的工作,与我贡献的几个开源库相比

@MaximilianR仅代表我自己:

  1. 这是一个相当大的代码库
  2. 特别是如果你不是昆布和 ayncio 的专家
  3. 而且您对所报告问题的深度没有直觉

也就是说,我确实使用芹菜,所以如果有什么方法可以帮到我,我很乐意提供帮助。

@MaximilianR ,有很多贡献者,但我确实做了很多工作。 项目发展得太快了,在某些时候我不得不在 IRC/email/StackOverflow 等上修复错误或支持用户之间做出选择。尤其是像多处理池死锁问题这样的事情花了 6 个月的专注编码,而我本应该这样做的指导人。 那时我们的下载量几乎和 RabbitMQ 一样大,但在他们有 8 人全职工作的情况下,我是唯一一个。

可能还有其他东西需要截肢,但我认为没有什么比 Redis 更耗时。

将 amqp/kombu 移植到完整的 asyncio 的工作也是一个主要的时间消耗,但对于解决许多问题是必要的。 虽然它从未完成。

@ask你上面的消息是否意味着你仍然有兴趣为 SQS 付出努力? 我注意到这里只有一张打开的 SQS 票,但我仍然在文档中看到“实验”警告。 您能否就 SQS 的当前状态和未来需求提供建议?

我们将在生产中使用 Celery + SQS,所以我可能会为此做出一些努力,但如果 SQS 不是您项目长期计划的一部分,我真的不想陷入这种情况。

@ask感谢您在上面分享。 我可以理解你来自哪里。 我希望通过这种/其他方法 celery 可以更容易地维护并继续它的成功......

肯定会为您的项目做最好的事情,但如果放弃 Redis 支持,我肯定会在内部推动摆脱 Celery。 如果你真的想知道我们为什么不使用 RabbitMQ,我会私下详细说明,但我真的不想公开抨击其他项目。

相关:暗示这是一个命令,因为这就是您在 Docker 上开发的方式,可能对您有用,但这不一定是我们其他人的部署方式。

@nicksloan SQS 现在在主文档中列为受支持的传输: http : //docs.celeryproject.org/en/master/getting-started/brokers/index.html

将 SQS 传输重写为使用异步 I/O 的工作获得了 1000 多美元的赞助。

@scoates Redis 传输处于更糟糕的情况,因为它确实被黑客攻击在一起以使用异步 I/O 来读取消息,但发布仍然是同步的。 Python redis 库是同步的,因此即使在读取消息方面仍然存在多种挑战,并且其工作方式存在很多不确定性。 错误很容易隐藏在那里,当我们以非正统的方式使用它时,对 redis-py 库的任何更改都可能产生剧烈的影响。

我想支持Redis,我真的支持。 当我在 RabbitMQ/Pivotal 工作时,我一直在争取它,因为我觉得我们需要一个 Python 中的通用解决方案来解决 Celery 实现的模式。 但是,如果社区和使用它的公司不投资以保持它的正常运行,那么我将不得不灭火,最糟糕的是现在无法解决导致人们批评该项目的交通严重问题。 这让我的生活更加悲惨,士气低落。

鉴于 celery 的历史,这可能过于激进,但是您是否考虑过只保留 Redis 而不是 RabbitMQ?

@MaximilianR我已经考虑过了,但我的热情在于消息传递和构建正确的分布式系统。 Redis 尚未为我们提供用于实现消息确认的 BRPOPLPUSH 的实现,并且随着无法接受在分布式系统中不可能依赖挂钟时间这一基本事实的启示,我更加谨慎。 RabbitMQ 至少是在认真地攻击问题空间,还有像 Kafka 和 NSQ 这样的其他玩家。 许多库将任务队列视为简单的列表操作,但我拒绝 Celery 成为其中之一:)

@scoates :我不是在谈论我的发展方式或其他什么。 我是说在 2016 年说“rabbitmq 很难部署”是无稽之谈。 即使您对在某处部署某些东西一无所知,docker 确实很有帮助。 请不要做出错误的假设。

感谢@ask与我们联系。 Celery 是一款很棒的产品,鉴于您(和社区)拥有的资源有限,我认为专注于核心产品是最好的决定。 我可以想象尝试使用许多不同的不兼容系统来提供相同的强大功能是多么困难。 从消费者的角度来看,我认为有这么多的选择增加了产品的复杂性。 我相信这可能会让您的一些用户感到不安,但我认为坚持使用较少的经纪人是为产品做的正确的事情。 我希望看到对 AMQP 的关注,因为它是标准的、被广泛接受的协议,我认为 rabbitmq 是它的一个很好的实现。

令人遗憾的是,确实没有那么多工作要做,但是当您将所有传输和功能的所有工作加在一起时,每周仅工作几个小时是不可持续的。

由于 Redis 协议如此简单,将传输重写为完全异步并不一定那么困难。 我制作了一个层,使 Celery 能够支持任何 Tornado 库,同样可以为 asyncio 和 Twisted 制作,所以我们甚至可能有可以重用的客户端。

Python 正在随着 stdlib 中的 asyncio 发生巨大变化。 我们需要新的 Web 框架、新的网络库以及几乎整个生态系统都需要适应。 它使我们的工作变得更容易一些,因为我们不必再继续维护我们自己的事件循环,但是转换需要一些工作。

我还想用 Go 或类似的语言编写一个新的工作程序,因为我们有一个支持多种语言的新消息协议。 Redis 不是消息互操作性的最佳匹配,因为它没有实现消息头、属性等。 AMQP 协议在那里肯定占上风,因为它是原始用例之一。

@ask我的方法是尝试让公司维护他们的经纪人。 因此,让我们尝试与 Redis 实验室的某个人交谈,看看我们是否有任何吸引力。
MongoDB 和其他服务也是如此。
至于 SQL 代理,我认为它们不是一个好主意,我们不应该支持它们。
我们可以提取代码而不是删除它,然后找人来维护它。 如果没有足够的兴趣,那么就没有必要。
唯一可以充当代理的 SQL 数据库是 Postgres,因为它具有 Pub/Sub 功能,但目前还没有实现。

我认为我们可以弃用它,看看会发生什么。 也许有人通过接管维护或赞助来加强它。 如果没有,我们有一个人们需要但没有人愿意支持的产品,此时可能总共有 18 票。 我认为这不会单独影响 Redis Labs :)

但是,如果社区和使用它的公司不投资以保持它的正常运行,那么我将不得不灭火,最糟糕的是现在无法解决导致人们批评该项目的交通严重问题。 这让我的生活更加悲惨,士气低落。

我们在多个项目中使用 celery 和 redis 代理并依赖它,但我非常同意这种观点。 如果你不能保持它的高质量,它只会给 celery 带来坏名声,让每个人都不开心——你_和_用户。

你好。 我在 Redis Labs 工作,直到最近我还是 celery 用户。 @thedrow引起了我的注意,我们已经在内部讨论了这个问题。 我们愿意帮助你们,我们认为将 redis 作为 celery 的一部分很重要。 我还不确定我是亲自还是其他人来做这件事,但让我们讨论一下需要做的事情。

@dvirsky一样,我对 Redis 的工作完全由 Redis Labs 赞助,如果我们能够帮助这个后端(希望是),我将参与帮助找到 Redis 方面的最佳解决方案,甚至可能扩展 Redis 消息传递支持以促进实现中的某些事情。 我们还可以强调后端在某个时候使用 Sentinel / Redis Cluster 的能力,以便获得 HA-ready 体验。 我希望我们能尽快得到好消息,目前正在评估所需的工作。

这真是个好消息! 我完全理解你想在承诺之前了解所涉及的工作:)

现在是凌晨 3 点,我还没有收集问题列表,但这里有一些简短的说明:

Celery 没有定义一组通过 Redis 接口实现的特性,而是
它使用 AMQP API 以通用方式使用消息传递。 名称到队列消息传递、发布/订阅和主题路由。 主题路由不是一个严格的要求,但其余的对于 Celery 的主要功能至关重要:1) 处理任务消息,2) 发送/接收监控事件,以及 3) 向工作人员广播消息以管理它们(例如关闭/增加并发等)。 )。

1) 需要是异步的,所以它不会阻止工作人员进行任何操作

当前版本使用的是 redis-py 库,它是同步的。 我已经破解了这个
它以异步方式使用消息,但我怀疑那里仍然存在错误,因为我们不知道客户端到底发生了什么。 可能已经有异步 redis 客户端可用于
我们可以使用 Tornado/asyncio,或者最坏的情况,因为我们不需要做太多原始操作
太棘手了。

2) 连接管理

我们有一个连接消耗任务,一个连接执行发布订阅,然后是一个池
执行带外操作的连接数,例如确认消息或恢复未确认的消息。 这里的错误处理有些混乱,我们可能不会在使用后关闭所有连接。

3) 消息确认

消息仅在被确认后才从服务器中删除,并且我们有一个可见性超时,所有消息使用者都尝试恢复消息。 好吧,这是一团糟,
稍后我可以更详细地描述这一点。

谢谢@ask ,关于“1”点,直接实现我们需要的最小异步Redis支持可能是有意义的,我们需要直接在代理内部发送的少数命令,而不是依赖于外部库。

请注意,只有 2 个,可能还有其他一些小问题需要尽快解决。 它在很大程度上是有效的,但在某些情况下,由于消息确认可能会丢失消息,但这是一个愿望清单项目,因为在 ack 模拟之前情况要糟糕得多。 worker 可能被同步 Redis 客户端阻塞,这会导致性能下降,并且在极少数情况下会挂起 worker。

1) 需要是异步的,所以它不会阻止工作人员进行任何操作

最后我检查过,异步 redis 客户端并不完美(龙卷风有几个)。 我在这些情况下所做的很多次是使用线程池执行程序和期货来使 redis-py 表现得像一个异步客户端。 只要您没有太多并发任务并且几个线程就可以完成,它就比异步客户端工作得更好。

编辑:我还没有直接使用过 python 的 asyncio,但从我所见,它与龙卷风非常相似,所以这种模式可能很容易做到。

@dvirsky我们不允许使用线程,因为我们也在使用fork 。 Python 不支持这种情况,即使为 cpython 生成了补丁,我们也必须小心地修补现有的 Python 库,至少是 C 扩展,以确保安全。 前段时间在 Python 错误跟踪器上实现了这一点,这就是我们一直在迁移到异步 I/O 的原因。 我们还需要在一般情况下移动到那里,因为它是 Python 的未来,现在具有核心异步 I/O 支持。

@antirez 回复

关于点“1”,对于我们直接在代理内部发送的少数命令,直接实现我们所需的最小异步 Redis 支持可能是有意义的,而不是依赖于外部库。

我不会那样做。 redis-py 的大部分代码都围绕着网络和连接管理,而不是围绕着实现命令......

@dvirsky我们有连接管理泛型可以完美地工作,所以不应该是任何时间下沉。 我们没有太多的网络,但我认为大多数是解析协议,我们已经接近手动或连接到现有的 redis 类。

@ask是的,hiredis 是用于解析 redis 协议的专用 C 扩展,IIRC 它也可以与异步客户端一起使用。 到目前为止,您在使 redis 异步方面选择了什么策略?

无论如何,我需要看看最近异步客户端发生了什么,在过去的一年半里我没有做太多的 Python 工作。 我看到https://github.com/leporo/tornado-redis不是很活跃。

没有太多的策略,我们将套接字添加到事件循环并同步发送例如 BRPOP,然后我们等待套接字可读并同步读取响应;)

由于我们无法在解析响应的过程中重新启动

@dvirsky如果我们将hiredis 用于协议解析以外的任何其他用途,我们将遇到与gevent/eventlet 的兼容性问题(当使用它而不是多处理时),并且如果Celery 在PyPy 上运行,它也会使hiredis 成为强制性问题。

@dvirsky此外,py-hiredis 目前不公开协议解析以外的任何功能。

我相信 Python 在某个时候将需要一个像样的异步 redis 客户端,所以开始一些正确的事情并不是一个坏主意。 比如重构redis-py中的一些协议解析代码。

你现在正在使用 gevent 吗?

@dvirsky我们通过异步 I/O 支持 gevent、eventlet 和多处理(prefork)。 但如果你支持其中一个,你通常会拥有其他的。

是的,有时 gevent 更适合任务。 例如,当任务只是写入数据库或执行 HTTP 请求时。
在 gevent 中公开和注册 FD 很容易,但这需要在 py-hiredis 中进一步工作。

@dvirsky这是一个如何使用 PyCurl 完成的示例。 https://gist.github.com/GuoJing/5875326
您需要公开 FD 才能与 gevent 协作。

我最近了解了有关 celery 对 Redis 支持的问题,虽然我还没有完成彻底的分析,但我可以说用 asyncio 编写/升级 python redis 客户端听起来是个好主意,但从最近的基准测试来看,这是最好的在 asyncio+libuv 之上实现,以尽可能提高性能。

参考资料见

反对这个立场——或者让事情复杂化,我会注意到,根据我自己对 Redis 客户端的经验,作为开发人员和用户,完全依赖 libuv 实际上会阻止客户端实现最大性能,为此,hiredis 是必须的。 在 libuv 的底层有很多东西在某些情况下实际上会降低 io 的速度,ioredis 通过 Node 完成它并且它并不是真正的高性能。

所以我设想的解决方案有一个混合的hiredis-async 实现。 (换句话说,需要通过大量的挑选和基准测试来尝试一系列替代方案)

@merl-dev 问题仍然是 PyPy,其中hiredis+cffi 在解析 redis 协议时比纯 python 协议解析器实现慢。
至少我的版本也有一些 redis-py 测试失败。 见https://github.com/redis/hiredis-py/pull/46

完全可以将hiredis 客户端编写为CPython 扩展。 我仍然不是 100% 确定 CFFI。

我们去取得它

@thedrow这让我想起了 - 你看过新的 redis 流功能吗? 它可以用作比当前的东西更强大的消息代理。 马上就要 GA 了。

我们没有。 我们目前没有能力重构 redis 代理。
我们希望你们有一些备用的手来这样做。

@thedrow我们可能……没有任何承诺,但我们可能会投入更多资源来主动支持 redis 生态系统。

@dvirsky你的意思是这个提议,对吧? 因此,您可以使用TAPPEND入队, TREAD + TACK出队、处理和确认。

@georgepsarakis它不再是一个提案,它正在工作,前缀是 X,即 XADD。 见https://www.youtube.com/watch?v=ELDzy9lCFHQ

那么支持redis broker的最终决定是什么? 会很快被弃用吗?

现在不行。

我不知道社区倾向于哪种方式,但我们正在开始一个新项目,由于考虑弃用它,我很犹豫要不要使用 Redis 作为代理。 想法?

可以安全地假设 redis 代理将在可预见的未来留下来。 太多人转发了。

一直以来#301 / 601都变得陈旧了。

@ermik尝试帮助解决相关问题。

此页面是否有帮助?
0 / 5 - 0 等级