说明

虽然不想在完成量化系统的构建前再去分叉搞别的东西,但是在批量计算指标时需要频繁的使用MongoAgent,而这个服务只能做成单线程异步的,所以计算60万次指标需要2~3天时间。

考虑到之后可能会有重刷的情况,所以我想还是给MongoAgent"扩容"。

内容

1 分析

部件是稳定的:MongoAgent从上一版本推送之后,可能有大半年或者一整年都没有任何的更新,所以我认为做了不至于会返工。

手动分配端口:目前都在采用2字头的端口,所以约定3字头给到类似nginx的服务。

手动启动多个服务:从目前的需求看,提速10倍比较容易满足需求(2~3天 ⇒ 0.3天 = 2.4小时)。另外我服务器的计算核可以认为有10+个,所以正好。

需要1个nginx容器,以及10个mongoagent容器。比较麻烦的是,需要一个个手动启动容器。

未来(等量化的主体完成了)在继续完善架构时,应该优先把容器管理部分先做掉,这样启动分身什么的比较容易。架构还有一部分是web开发环境,以后再说。

2 MongoAgent

简单看了一下MongoAgent的连接管理,MongoAgent当时设计还是依赖pickle文件工作的。

  • 1 每次需要连接新数据库时需要建立connection_hash
  • 2 接口根据连接的信息计算hash,然后看看有没有在数据库中,如果有那么就跳过,否则就存库(24003),也存pickle,然后保存在本地
  • 3 再之后,每次提交操作时都伴随着connection_hash即可。

这些设计当然不那么完善,当初甚至没有考虑使用Redis,不过问题不大。

最简单的方法,就是让所有的分身都挂载一个文件夹,文件夹下面由一个程序获取某些主机的所有connection_hash。

还有一个在线的笨办法,就是将数据库的配置读出来,然后向服务不断的发起建立连接的试探,这样自动化一些。

在指定了端口后,可以精确的向每个mongo_agent发起连接创建。(虽然麻烦了点,但是比较可靠,先这样吧)

因为MA是无状态的服务,所以可以直接在原项目文件下启动,改个端口号就行。

3 Nginx测试

容器方面已经有了,所以主要看配置。

这个是大致的结构,我就不细看了,全局块和events暂时不管。
Python 全栈系列217 Nginx负载均衡MongoAgent-LMLPHP

主要是在http下进行配置

新的Nginx分配34011端口,测试时可以使用24011和24021两个服务。

先启动一个nginx试一下,镜像随便写一个都行,我只是固定了一个版本放在自己仓库

docker run -it --rm  -p 34011:80 【IMAGE nginx:v1】

内网中发起测试(第二次就不下载index.html了)
Python 全栈系列217 Nginx负载均衡MongoAgent-LMLPHP
nginx启动成功
Python 全栈系列217 Nginx负载均衡MongoAgent-LMLPHP
现在迅速挂载对应的目录和配置,进行负载均衡mongoagent.conf

(似乎也可以不配置http模块,直接配置server)

配置如下

events {
    #设置工作模式为epoll,除此之外还有select,poll,kqueue,rtsig和/dev/poll模式
    use epoll;
    #定义每个进程的最大连接数,受系统进程的最大打开文件数量限制
    worker_connections  1024;
}


http{

    upstream multi_ma {
            # fair;
            server 172.17.0.1:24021 ;
            server 172.17.0.1:24011 ;
        }

    server {
        listen 34011;
        location / {
            proxy_pass http://multi_ma;
        }

    }

}

Python 全栈系列217 Nginx负载均衡MongoAgent-LMLPHP
坑1:挂载nginx的配置文件(会报一些错误[emerg] 1#1: "events" directive is not allowed here in /etc/nginx/conf.d/mongoagent.conf,我一开始没明白)

答案在这,挂载的配置文件不对
Python 全栈系列217 Nginx负载均衡MongoAgent-LMLPHP
坑2:fair要进行第三方安装才能用。所以我先不使用fair(以后有机会再看吧),应该是可以使用了。

Python 全栈系列217 Nginx负载均衡MongoAgent-LMLPHP
之后启动多个MA,然后将端口固定就行。计划使用35000~35009这十个端口服务。

4 启动

先按照端口35000~35009启动10个MA,然后修改nginx,配置改为在这10个MA上进行负载均衡。

因为是在当前的MA(24011)上直接挂载启动的,我发现24011生成的连接字典也被同步挂载过来了。

从一般性使用的角度上,还是要写一个程序来全量刷新连接字典。

拿到库里所有的连接记录

ng_ma = 'http://172.17.0.1:34011/'
query_dict = {'connection_hash':None,'filter_dict':{'is_enable':1},'tier1':'MongoAgent','tier2':'mConnections','limits':1000}
recs = req.post(ng_ma + 'query_recs_v2/',json=query_dict).json()['data']

剔除和数据库连接无关的字段

db_conf_list = []
for rec in recs :
    tem_dict = {}
    for k in rec.keys():
        if not k in ['connection_hash','create_time','is_enable']:
            tem_dict[k] = rec[k]
    db_conf_list.append(tem_dict)

做一个嵌套循环,逐个刷新MA的Shard

for i in range(35000,35010):
    tem_ma = 'http://172.17.0.1:%s/'  % i
    for db_conf in db_conf_list:
        resp = req.post(tem_ma + 'add_a_connection/',json ={**db_conf}).json()
        print(resp)

5 总结

这样就好了,比想象中的简单一些。

未来可以通过服务(docker manager)来实现类似的批量启动分身的方法(再通过前端集成管理),这样就比较完美了。

04-08 13:17