celery 原理 分布式任务队列
Celery - 分布式任务队列 — Celery 3.1.7 文档 https://docs.jinkan.org/docs/celery/index.html
Celery - 分布式任务队列
Celery 是一个简单、灵活且可靠的,处理大量消息的分布式系统,并且提供维护这样一个系统的必需工具。
它是一个专注于实时处理的任务队列,同时也支持任务调度。
任务注册
Only one of these is important, and that is the main module name, let’s look at why that is.
When you send a task message in Celery, that message will not contain any source code, but only the name of the task you want to execute. This works similarly to how host names works on the internet: every worker maintains a mapping of task names to their actual functions, called the task registry.
Application — Celery 3.1.7 文档 https://docs.jinkan.org/docs/celery/userguide/application.html
任务幂等 断电
Tasks — Celery 3.1.7 文档 https://docs.jinkan.org/docs/celery/userguide/tasks.html
retry() can be used to re-execute the task, for example in the event of recoverable errors.
When you call retry it will send a new message, using the same task-id, and it will take care to make sure the message is delivered to the same queue as the originating task.
When a task is retried this is also recorded as a task state, so that you can track the progress of the task using the result instance (see States).
任务重试
The retry() call will raise an exception so any code after the retry will not be reached. This is the Retry exception, it is not handled as an error but rather as a semi-predicate to signify to the worker that the task is to be retried, so that it can store the correct state when a result backend is enabled.
Tasks are the building blocks of Celery applications.
A task is a class that can be created out of any callable. It performs dual roles in that it defines both what happens when a task is called (sends a message), and what happens when a worker receives that message.
Every task class has a unique name, and this name is referenced in messages so that the worker can find the right function to execute.
A task message does not disappear until the message has been acknowledged by a worker. A worker can reserve many messages in advance and even if the worker is killed – caused by power failure or otherwise – the message will be redelivered to another worker.
Ideally task functions should be idempotent, which means that the function will not cause unintented effects even if called multiple times with the same arguments. Since the worker cannot detect if your tasks are idempotent, the default behavior is to acknowledge the message in advance, before it’s executed, so that a task that has already been started is never executed again..
https://mp.weixin.qq.com/s/FzvZHQpF5mhV9t_HBzlcwg
Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery, 举几个实例场景中可用的例子:
-
异步任务:将耗时的操作任务提交给Celery去异步执行,比如发送短信/邮件、消息推送、音频处理等等
-
做一个定时任务,比如每天定时执行爬虫爬取指定内容
-
还可以使用celery实现简单的分布式爬虫系统等等
Celery 分布式任务队列快速入门 - 金角大王 - 博客园 https://www.cnblogs.com/alex3714/p/6351797.html
Celery + Redis 的探究(工作过程!!!)_数据库_myli_binbin的博客-CSDN博客 https://blog.csdn.net/myli_binbin/article/details/90374873
结论,由此可以推测出 celery 和 redis 之间交互的基本原理:
1、当发起一个 task 时,会向 redis 的 celery key 中插入一条记录。
2、如果这时有正在待命的空闲 worker,这个 task 会立即被 worker 领取。
3、如果这时没有空闲的 worker,这个 task 的记录会保留在 celery key 中。
4、这时会将这个 task 的记录从 key celery 中移除,并添加相关信息到 unacked 和 unacked_index 中。
5、worker 根据 task 设定的期望执行时间执行任务,如果接到的不是延时任务或者已经超过了期望时间,则立刻执行。
6、worker 开始执行任务时,通知 redis。(如果设置了 CELERY_ACKS_LATE = True 那么会在任务执行结束时再通知)
7、redis 接到通知后,将 unacked 和 unacked_index 中相关记录移除。
8、如果在接到通知前,worker 中断了,这时 redis 中的 unacked 和 unacked_index 记录会重新回到 celery key 中。(这个回写的操作是由 worker 在 “临死” 前自己完成的,所以在关闭 worker 时为防止任务丢失,请务必使用正确的方法停止它,如: celery multi stop w1 -A proj1)
9、在 celery key 中的 task 可以再次重复上述 2 以下的流程。
题外话:
1、启动 celery worker 时可以加上 -B 参数使得 schedule 定时任务生效,但要注意如果为同一个项目启动多个 worker 时,只需要其中一个启动命令中加上 -B,否则 schedule 会被多次执行。
2、上面的 1 同时也说明了 schedule task 的执行是由 celery 发起的。也就是说,如果在 django 中使用了 CELERYBEAT_SCHEDULE,那么只要 celery worker -B 启动了,即使 django web 服务没有启动,定时任务也一样会被发起。
3、使用 flower 时,在上述的 “worker 领取任务后突然遇到问题退出了然后又重新启动执行” 这种情况下可能会出现显示不正常的问题,这个是否是 flower 的 bug 还是有其他原因,可能下篇再探究。
Celery的底层原理_Python_michael_xwb的博客-CSDN博客 https://blog.csdn.net/michael_xwb/article/details/96180906
Celery是基于Python实现的一个异步任务调度工具,同时也是一个任务队列。
Celery架构由三个模块组成:消息中间件(message broker),任务执行单元(worker)和任务执行结果存储(task result store)组成。
消息中间件(Broker): 消息中间人,是任务调度队列,是一个独立的服务,是一个生产者消费者模式,生产者把任务放入队列中,消费者(worker)从任务队列中取出任务执行,任务的执行可以按照顺序依次执行也可以按照计划时间进行。但是Broker本身不提供队列服务,所以要集成第三方队列,推荐使用RatbbitMQ或Redis.
任务执行单元(worker):即执行任务的程序,可以有多个并发。它实时监控消息队列,获取队列中调度的任务,并执行它。
任务执行结果存储(task result store):由于任务的执行同主程序分开,如果主程序想获取任务执行的结果,就必须通过中间件存储。同消息中间人一样,存储也可以使用RabbitMQ、Redis;另外,假如不需要保存执行的结果也可以不配置这个模块。