说明

其实这块是对于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的速度没法比,但是胜在持久。