Why is Celery Async Task working slower than Synchronous task?
我正在使用celery异步运行一些任务的Django应用程序上工作。 我尝试使用Apache Bench执行负载测试并检查响应时间。 从结果可以看出,没有celery异步任务,响应时间会更快。
我正在使用:
Django settings.py中的Celery配置:
1 2 3 4 5 6 | BROKER_URL = 'redis://127.0.0.1:6379/1' CELERY_RESULT_BACKEND = 'django-db' # Using django_celery_results CELERY_ACCEPT_CONTENT = ['application/json'] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' CELERY_TIMEZONE = 'Asia/Kolkata' |
以下是我的代码(系统公开的API):
1 2 3 4 5 6 7 8 9 10 11 | class CustomerSearch(APIView): def post(self, request): request_dict = {# Request parameters} # Async Block response = celery_search_customer_task.delay(request_dict) response = response.get() # Synchronous Block (uncomment following to make synchronous call) # api_obj = ApiCall(request=request_dict) # response = api_obj.search_customer() # this makes an API call to return Response(response) |
还有task.py中的celery任务:
1 2 3 4 5 | @app.task(bind=True) def celery_search_customer_task(self, req_data={}): api_obj = ApiCall(request=req_data) response = api_obj.search_customer() # this makes an API call to another system return response |
Apache Bench命令:
1 | ab -p req_data.data -T application/x-www-form-urlencoded -l -r -n 10 -c 10 -k -H"Authorization: Token <my_token>" http://<my_host_name>// |
以下是ab的结果:
没有芹菜异步任务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | Concurrency Level: 10 Time taken for tests: 1.264 seconds Complete requests: 10 Failed requests: 0 Keep-Alive requests: 0 Total transferred: 3960 bytes Total body sent: 3200 HTML transferred: 1760 bytes Requests per second: 7.91 [#/sec] (mean) Time per request: 1264.011 [ms] (mean) Time per request: 126.401 [ms] (mean, across all concurrent requests) Transfer rate: 3.06 [Kbytes/sec] received 2.47 kb/s sent 5.53 kb/s total Connection Times (ms) min mean[+/-sd] median max Connect: 259 270 10.7 266 298 Processing: 875 928 36.9 955 967 Waiting: 875 926 35.3 950 962 Total: 1141 1198 43.4 1224 1263 Percentage of the requests served within a certain time (ms) 50% 1224 66% 1225 75% 1231 80% 1233 90% 1263 95% 1263 98% 1263 99% 1263 100% 1263 (longest request) |
与芹菜异步任务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | Concurrency Level: 10 Time taken for tests: 10.776 seconds Complete requests: 10 Failed requests: 0 Keep-Alive requests: 0 Total transferred: 3960 bytes Total body sent: 3200 HTML transferred: 1760 bytes Requests per second: 0.93 [#/sec] (mean) Time per request: 10775.688 [ms] (mean) Time per request: 1077.569 [ms] (mean, across all concurrent requests) Transfer rate: 0.36 [Kbytes/sec] received 0.29 kb/s sent 0.65 kb/s total Connection Times (ms) min mean[+/-sd] median max Connect: 259 271 9.2 268 284 Processing: 1132 6128 4091.9 8976 10492 Waiting: 1132 6127 4091.3 8975 10491 Total: 1397 6399 4099.3 9244 10775 Percentage of the requests served within a certain time (ms) 50% 9244 66% 9252 75% 10188 80% 10196 90% 10775 95% 10775 98% 10775 99% 10775 100% 10775 (longest request) |
芹菜异步任务不是应该使任务比同步任务更快地工作吗? 我在这里可能会想念什么?
任何帮助,将不胜感激。 谢谢。
同步运行代码是直接在主线程上阻塞代码,而celery则类似于生产者使用者机制。
Celery将任务转发到诸如RabbitMQ或Redis之类的代理消息队列,这在此处增加了额外的处理时间。根据芹菜的运行位置,如果不在本地运行,则可以考虑增加网络延迟。如果您正在调用
所以架构基本上变成了
-
网路
-
经纪人
- 工人
- 结果后端
考虑到大量处理芹菜任务比在主线程上运行慢
我认为您的问题中存在多种误解,应该予以回答。
Isn't celery async task supposed to make tasks work faster than synchronous tasks?
正如@Yugandhar在回答中指出的那样,通过使用诸如Celery之类的东西,您在处理过程中会增加额外的开销。实际上,您不是在执行代码的相同过程,而是在执行以下操作:
- 客户发送消息给经纪人。
- 工人拿起消息并执行它。
- 工人对经纪人的回应。
- 客户获取响应并进行处理。
如您所见,相对于同步执行,使用Celery显然涉及额外的开销。因此,不一定要说"异步任务比同步任务快"。
那么问题是,为什么要使用异步任务?如果它增加了额外的开销并可能减慢执行速度,那么它的好处是什么?好处是您无需等待响应!
让我们以您的
通过在后台异步执行它,调用本身可能需要10.01秒才能执行(由于开销比较慢),但是不必等待这些秒过去,您可以(如果选择)立即将响应返回给用户,并使用户体验更好。
等待结果与回调
您的代码示例的问题在于,同步代码和"异步"代码基本上执行相同的操作。两者都以阻塞的方式等待结果,您并没有真正获得异步执行结果的好处。
通过使用
1 2 | task.delay() # Async, don't await any response. task.delay().get() # Blocks execution until response is returned. |
有时这就是您想要的,但是在其他情况下,您无需等待响应,您可以完成执行HTTP请求,而使用回调处理您触发的任务的响应。