OnlineJudge
OnlineJudge copied to clipboard
借助消息队列实现评测的负载均衡
现在的评测虽然是基于消息队列做的,但是在负载均衡这块只是用 django select 简单加了个锁,找一台比较“空闲”的机器然后用它评测。
我觉得在 OJ 这个场景下,是不是可以把“判断空闲”这个事情让评测机自己来做,往消息队列里塞评测任务之前取消"加锁选机器"这个环节,把这个事情交给 broker 和 worker 来做,毕竟每个评测任务消耗的资源也不是完全一样的,还能省得用 Django 重复实现 worker 的选择?
如果按照我的想法修改以后,OnlineJudge 需要增加几个接口
- 评测机主动获取任务后,更新管理后台中自己的状态
- 评测机评测结束后,更新 Submission 的结果
- ...
p.s. 我还没有实际尝试,暂时不能确定这个方案的性能如何,先讨论一下
之前是认为不需要这么复杂的状态管理,这样感觉复杂度太高了,而且没有带来太多的好处?
当前其实挺够用了,只不过我觉得在 web(django) server 这边的 worker 里发评测请求并等待,和评测机的功能有些耦合。 举个例子来说,如果部署了 1 台 django server(2 个 dramatiq worker),1 台评测机,临时有需求需要扩容,加了 2 台评测机,但其实还不够,因为只有 2 个 worker,django server 这边就成了吞吐量的瓶颈,部署的时候得花点心思。希望我正确理解了当前的实现。
Update: 压测后发现,在简单场景下 worker 的数量基本没有影响,反而是前端并发的结果查询操作会给 gunicorn 这边带来很大的压力,换用 bjoern 这类 C++ 内核的 WSGI Server 之后提升明显,不过一般还是 gunicorn 比较稳定,所以这边可以考虑用 WS 来规避不必要的并发问题。其次的话,就是加评测机了。