一、服务器背景
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的使用


到这里好像任务都执行完了,但是这个好像跟标题没有多大的关系??
上面的只是介绍发现问题的背景,下面的才是正片。 在worker=4的情况下,占满了全部cpu去执行任务,单个任务耗时平均60s。但是60s只是勉强能接受的范围,达不到高效率的执行worker。在测试任务的过程中,只执行一天的任务进行过程分析,也就是2个worker: worker_1 : 20200406,1-450级玩家的聊天记录 worker_2 : 20200406,451-900级玩家的聊天记录 启动worker,依然还是4个进程




既然2,3,4个worker都试了,那1个worker效率怎么样,结果如下


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