说明
其实这块是对于ADBS运维的一个补充,目的是尽量使用分布式、多核的优势加速计算。在默认的ADBS中,是以串行的方式分别运行sniffer、app、worker、stat等模块的。正常来说,由于worker每个批次处理一万条数据,这个效率也够了;在量化计算中,因为需要在每个周期进行回顾计算,所以每条数据实际上变成了任务。
从计算的角度上,最快的当然还是读成一个dataframe,用pandas rolling一下;但是考虑到长期运行和通用性的问题,还是以服务的方式运行比较好。
所以,我们看看怎么样拓展Worker分身。本质上,这是属于AFunc体系设计部分,这里碰到问题了提前解决一下。
内容
1 分身拓展方式
我发现这个和租用云服务一样,可以按照流量或者带宽的方式来分
流量方式主要是应对突发的、大量的需求,worker在执行一定次数后自动销毁,比较轻;带宽方式则是启动一个无限循环的定时worker(当然也可以限定截止时间),从而从根本上拓展worker的处理能力。
本例采用流量方式,修改起来也很简单(难怪现在云服务上都喜欢卖流量…,划算)
2 调用方式
调用方式也分为两类,手动方式与接口方式。
直接修改,完成后进行手动的执行,是常用的方式,也是手动方式。这种执行方法要求每启动一个容器都要自己拷贝,粘贴一个。
手动方式优点是简单,缺点是慢,而且繁琐。
还有一种方式是通过接口方式,或者更进一步来说,是通过前端来配置。
从长久来说,应该是采用前端+接口的方式,之前已经完成了接口服务,后来还是因为用接口调用的方式还是比较不方便,容易忘。所以之后把前端做好之后,再对接口做少量(甚至不必做修改),再由portal和接口进行对接既可以。
3 本次解决方法
先做一下命名区分
流量类的worker: CNT_worker
带宽类的worker: BandWidth_worker
CNT_worker.py
import os
cnt_limit = 100000
print('>>>work is Running ')
for _ in range(cnt_limit):
runcode =''
for some_app in ['worker01_ETL.py']:
runcode += str(os.system('python3 %s' % some_app))
print('>>>work RunCode :%s ' % runcode)
运行时将CNT_worker.py
挂载到镜像中,然后执行就可以了(-d --rm, 后台执行,执行完毕后删除)。
先开了3个worker, 每个worker处理10万。本质上这个操作实际上是IO密集的,主要看Mongo服务能处理的每秒请求,所以基本上开到100个worker应该是可以的。
4 Future
- 1 分身的命名为类别和编号,编号用时间戳比较方便
- 2 针对性的统计也要做适应性调整,按照类别命名统计分身个数
- 3 CNT类Worker启动和维护都很简单,但是要批量启动还是需要通过前端才好
- 4 BandWidth类Worker最好还是加上时间限制(如果是对外的)
- 5 大量的固定配置,还是需要通过前端来配置(默认配置)比较好
- 可以想象,每个行作为一个独立的item编辑,初期甚至可以考虑itables,这样节约开发时间
- 前端的启动要按照check项逐步反馈(例如必要配置完毕、命令检查完毕、命令执行成功、容器运行状态正常等
跑起来总体是符合预期的,启动到15个worker也没有问题,瓶颈是在MongoAgent上(单核),之后如果用nginx就可以解决掉这个瓶颈
大概只需要2~3个小时就可以算完,和rolling的速度没法比,但是胜在持久。