Skip to content

Latest commit

 

History

History
175 lines (155 loc) · 5.15 KB

overview.md

File metadata and controls

175 lines (155 loc) · 5.15 KB

Overview

设计原则

  • 权限最小化
    • Web 服务器是较为可信的
      • Web 服务器可以访问所有重要资源
      • Web 服务器不能直接处理用户上传的文件,而应该交给调度机
    • 调度机在中间
      • 调度机不能访问主数据库,但是可以随意访问 s3
    • 评测机是不可信环境
      • 评测机只能访问传给它的 URL 里的文件
      • 评测机执行外部命令必须经过沙箱
  • 评测并行化
    • 评测任务细分
    • 每次只评测一个最小单元而不是一整道题
  • 评测可中断
    • 防止长时间评测任务 (e.g. 火车票) 无法打断造成资源浪费
  • 合理使用数据服务
    • 文件存 s3,数据存 SQL,临时数据存 Redis
    • 大文件直接传 (Signed) URL
    • 管理员上传/下载题目 zip 不经过 web,直接传 s3
    • 代码也存在 s3 上面,以后可以让用户把代码直接传到 s3,不经过 Web
      • Use case: 提答题

总体架构图

graph TD
    subgraph Web
      WS[Web server]
    end
    subgraph Scheduler
      SC[scheduler2 server]
    end
    subgraph Runner 1
      J1[judger2 instance 1]
    end
    subgraph Runner 2
      J2[judger2 instance 2]
    end
    subgraph Data Services
      MY[(MariaDB)]
      R0[(Web Redis)]
      R1[(Judger Redis)]
      S3[(S3 Storage)]
    end
    SC --- S3
    J1 --- S3
    J2 --- S3
    User --- WS
    User --- S3
    WS --- S3
    WS --- MY
    WS --- R0
    SC --- R1
    J1 --- R1
    J2 --- R1
    WS --- SC
Loading
  • Web 模块: 处理所有用户操作, 并交给对应模块 (参见 Web 文档);
  • Scheduler 模块: 规划评测相关事务 (参见 Scheduler 文档);
  • Judger 模块: 执行评测任务 (参见 Judger 文档);
  • Redis: 用于辅助各模块间的通信, 充当缓存数据库 (参见 Redis 文档);
  • S3: 用于存储各模块间的数据, 充当文件服务器 (参见 S3 文档);

评测流程

sequenceDiagram
participant Admin
participant User
participant S3
participant Web
participant Scheduler
participant Redis
participant Judger1
participant Judger2

break Initialization
Judger1 ->> Redis: Listen for tasks.
Judger2 ->> Redis: Listen for tasks.
end

break Data upload
Admin ->> Web: Gimme zip upload URL for 1001.
Web ->> Admin: OK, https://acm.sjtu.edu.cn/oj-problems/1001.zip?signature=xxx
Admin -> S3: PUT /oj-problems/1001.zip?signature=xxx
Admin ->> Web: Let's update judge plan for 1001.
Web ->> Scheduler: Update judge plan for 1001.
Scheduler -> S3: GET /oj-problems/1001.zip
Scheduler -> S3: PUT /oj-problems/plan/1001.json
Scheduler -> S3: PUT /oj-problems/1001/1.in
Scheduler -> S3: PUT /oj-problems/1001/1.ans
Scheduler ->> Web: OK.
Web ->> Admin: OK.
end

break Submit code
User ->> Web: Submit code for 1001.
Web -> S3: PUT /oj-submissions/1926.code
Web ->> Scheduler: Schedule submission 1926.
Scheduler -> S3: GET /oj-problems/plan/1001.json
Scheduler ->> Redis: Put task 84d1d91d.
Scheduler ->> Redis: Listen task 84d1d91d.
Scheduler ->> Web: Scheduled.
Web ->> User: OK.
end

break Judge
Redis ->> Judger1: Task 84d1d91d.
Judger1 -> S3: GET /oj-submissions/1926.code
break If abort
User ->> Web: Abort 1926.
Web ->> Scheduler: Abort 1926.
Scheduler ->> Redis: Abort 84d1d91d.
Redis ->> Judger1: Abort 84d1d91d.
end
Judger1 -> S3: PUT /oj-artifacts/1926/a.out
Judger1 ->> Redis: Task 84d1d91d done.
User ->> Web: What's the status of 1926?
Judger1 ->> Redis: Listen for tasks.
Web ->> Scheduler: What's the status of 1926?
Scheduler ->> Web: It's compiling.
Redis ->> Scheduler: Task 84d1d91d done.
Scheduler ->> Redis: Put task 1c1e11d0.
Scheduler ->> Redis: Listen task 1c1e11d0.
Redis ->> Judger2: Task 1c1e11d0.
Judger2 -> S3: GET /oj-artifacts/1926/a.out
Judger2 -> S3: GET /oj-problems/1001/1.in
Judger2 -> S3: GET /oj-problems/1001/1.ans
Web ->> User: It's compiling.
User -> S3: GET /oj-submissions/1926.code?signature=xxx
Judger2 ->> Redis: Task 1c1e11d0 done.
Judger2 ->> Redis: Listen for tasks.
Redis ->> Scheduler: Task 1c1e11d0 done.
Scheduler -> S3: DELETE /oj-artifacts/1926/a.out
Scheduler ->> Web: 1926 done.
end

break Query result
User ->> Web: What's the status of 1926?
Web ->> User: It's accepted.
User -> S3: GET /oj-submissions/1926.code?signature=xxx
end

Loading

公网可访问组件

  • Web server
  • s3
    • s3 需要可以通过内外网两个接口访问
    • 外网接口的用途
      • 查看代码
      • 上传/下载题目 zip
      • 上传/查看图床图片

调度机和评测机的配置

调度机和评测机都有两个和配置相关的文件, 分别是 {scheduler,runner}.ymlconfig.py. yml 文件是不纳入 git 版本管理的, 是每台调度机/评测机独有的配置, 更改网络结构时, 从设计上来说应该只更改 yml 文件即可, 不用更改代码; 而 py 文件的作用是读入 yml 文件, 以及记录业务逻辑上的常量 (如 heartbeat 间隔时间、任务超时时间等) 等每台调度/评测机相同的参数, 或者应该纳入版本控制的参数, 但不应记录密钥、密码、access key 等敏感内容.

另请参见