Python分布式系统Celery,根据CPU核数探讨最优worker数 《案例:jieba分词玩家热点追踪》

一、服务器背景

1台4核服务器

二、jieba分词问题探究

在本例中,主要针对的是对玩家每天的聊天记录进行一个热点追踪,技术层面不难,无非就是对玩家的语句进行清洗,分词,然后做主题提取等一些常规的流程。但是难点在保证查询效率的同时,怎么把庞大的玩家聊天记录数据存储下来以及进行条件式筛选。

三、Celery异步任务

1、什么是Celery
Celery是一个简单、灵活且可靠的,处理大量消息的分布式系统,专注于实时处理的异步任务队列,
同时也支持任务调度,Celery一个worker就是一个守护进程。
2、Celery由什么组成
Celery的架构由三部分组成,消息中间件,任务执行单元和任务执行结果存储组成。
本人使用的架构是 Celery+Redis。
Celery使用到了工作流模式(group+chord)
Redis用来存储消息任务参数以及工作流的数据存储。

四、Celery任务构建

1、由于聊天记录比较大,在单个进程任务中jieba.lcut耗时较长,因此考虑对任务进行分割。分割的方式有多种,在这里仅介绍案例中使用的,首先是以天为分割点,然后再以玩家的等级进行二次分割。

例如:总任务是查 玩家在20200406跟20200407这两天的玩家聊天记录的热点排名,在本次切割下会将天数跟玩家等级进行切割,分割成4个worker,
worker_1 : 20200406,1-450级玩家的聊天记录
worker_2 : 20200406,451-900级玩家的聊天记录
worker_3 : 20200407,1-450级玩家的聊天记录
worker_4 : 20200407,451-900级玩家的聊天记录

2、使用Celery.group将这四个任务并发执行

group([worker_1 ,worker_2 ,worker_3 ,worker_4])

3、使用Celery.chord进行工作流任务

chord(group([worker_1 ,worker_2 ,worker_3 ,worker_4]))
这一步的主要目的是将各天各个等级段的切割数据汇总,再最终进行计算,热点排名。

注:在使用工作流模式的时候要注意工作流模式会将前一步的数据传递给下一步,这里前一步返回的数据要控制好,太多会影响整体任务的执行效率

五、执行任务

1、启动worker

由于测试机只有4个核,jieba分词主要占用cpu消耗,因此直接将worker数拉满。启动4个worker,队列名称为 celery_test
celery -A main worker -n celery_test -c 4 -l info -Q celery_test

2、任务执行结果

在任务执行过程,4个worker拉满了cpu的使用
Python分布式系统Celery,根据CPU核数探讨最优worker数 《案例:jieba分词玩家热点追踪》_第1张图片
任务执行结果如下
在这里插入图片描述
4个worker执行的总耗时大致在60s左右,jieba_analyse是主要进行切割的函数,对这个函数进行了超时监控,在整个worker执行过程中,主要耗时就是在jieba_analyse这个函数里,4个worker的数据量长度大概都在1300w左右,数据量相差不大,因此总体的执行效率也相差不大。

到这里好像任务都执行完了,但是这个好像跟标题没有多大的关系??

上面的只是介绍发现问题的背景,下面的才是正片。
在worker=4的情况下,占满了全部cpu去执行任务,单个任务耗时平均60s。但是60s只是勉强能接受的范围,达不到高效率的执行worker。在测试任务的过程中,只执行一天的任务进行过程分析,也就是2个worker:
worker_1 : 20200406,1-450级玩家的聊天记录
worker_2 : 20200406,451-900级玩家的聊天记录
启动worker,依然还是4个进程
在这里插入图片描述
在这2个worker中可以明显看到,在数据量没有变化的情况下,jieba分词耗时只需要30s,将近4个worker同时执行的一半,为什么会差别这么大,一开始以为是2个worker的执行的时候也会将cpu的使用率拉满。于是又执行了一遍任务,观察服务器的cpu消耗,结果如下
在这里插入图片描述
看到结果并不是想象的,一个worker只占用了一个核的计算资源。因此2个worker执行跟4个worker执行耗时应该差不多,虽然还有其他的资源在消耗cpu,但也不应该比2个worker的时候慢那么多。
为了进一步探索,打开3个worker测试。
打开top可以看到,结果跟前面分析的一样,3个worker只占用3个核进行计算。
在这里插入图片描述
3个worker执行耗时如下
在这里插入图片描述
3个worker平均耗时45s,虽然比4个worker的时候快了,但是还是比2个worker慢,而且耗时都是在jieba_analyse这个函数里,但是观察cpu又没有被进程占满,还留有个1核的计算资源。

既然2,3,4个worker都试了,那1个worker效率怎么样,结果如下
在这里插入图片描述
在这里插入图片描述
在执行单worker的时候,耗时平均30s。
1个worker 耗时 30s
2个worker 耗时 30s
3个worker 耗时 45s
4个worker 耗时 60s

结论

在资源比较有限的情况下,Celery的worker数应该怎么选择最优,在追求单个worker最优的情况下,应该不超过服务器的核数的一半,当然如果在一些不怎么消耗cpu的任务,worker数越多并发数越高。具体的worker要结合业务情况再去调节,节省资源节省时间。

注:具体为什么worker超过一半会导致单个worker效率降低的这么明显暂时原因还没找到,后续找到会跟大家分享的,如果哪位大佬知道的话麻烦指导一下。

你可能感兴趣的:(python,cpu,分布式计算)