中文 EN

系统设计 Lab

Online Judge 的扩展主要是 worker 经济学,而不是 API 流量。

把滑块从一个玩具 judge 推到接近 LeetCode 的工作负载。当 compilation 和 sandbox 执行成为主导时,设计就变了:异步提交、把活儿排进 queue、预热 container、缓存不可变的结果,并把重型 submit 和轻量 run-code 流量拆开。

分步讲解

一步一步把它想清楚

常规演进场景

从左到右点击,就是预设的演示路径。每张卡片都会改变 workload 输入。

Workload

这些是输入,不是预设好的架构阶段。

推荐形态

当前架构路径
Online Judge 架构图 白板风格的架构图,展示异步代码提交、queueing、sandbox worker、result cache 和持久化的 submission metadata。 客户端 API Queueing 执行 存储 + 结果 用户 submit + poll API server 202 token + 状态 Submission DB append metadata Queue backpressure Scheduler priority + fairness Worker pool compile + run Warm runner 按语言 Result cache 不可变 verdict Object store 代码 + 测试
客户端
用户 提交代码,并轮询不可变的 verdict
API
API server 校验请求、存 metadata,并返回一个 token
Queueing
Queue 吸收尖峰,并给 worker 一个 pull-based 的 backlog
执行
Scheduler 施加 fairness、priority 和 queue 选择
Worker pool CPU 和内存吃重的 compilation 与执行
Warm runner 按语言划分的 sandbox container
存储 + 结果
Submission DB durable 的 append-only verdict 历史
Result cache 带 TTL 的廉价轮询读取
Object store 大块的源码、题目和 testcase blob

瓶颈

Worker 容量

Queue 压力

Result lookup

Sandbox pool

Submission 存储

为什么会变

    决策权衡

    异步 API

    Message queue

    预热 runner

    Sandbox 隔离

    Result cache

    Run / submit 拆分

    有出处支撑的规则

    这些是模型背后那些经得起时间考验的 system design 论断。而 slider 的具体阈值,则被刻意标注为教学用的假设。

    已验证的规则

    container 的 resource limit 是执行 TLE 和 MLE 的单位

    CPU 和内存 limit 给 worker 基础设施一个具体手段,去中止那些超出题目约束的 submission。

    Docker Docs
    已验证的规则

    Seccomp 缩小了不可信代码的 syscall 攻击面

    sandbox 应该拦截危险的 system call,而不是仅仅信任语言 runtime 或进程权限。

    Docker Docs
    已验证的规则

    queue 把 submit 流量和 worker 执行解耦

    queue 吸收突发流量,让 worker 按自己的节奏消费,这正好契合异步判题。

    AWS SQS Docs
    已验证的规则

    带 TTL 的 key-value 结果让轮询很廉价

    最终 verdict 是不可变的,所以短轮询可以一直读一个小的缓存对象,直到这个 key 过期。

    Redis Docs

    教学用假设

    • worker slot 的阈值是教学阈值;真实容量取决于语言组合、testcase 大小、CPU 型号和隔离开销。
    • result cache 存的是最终或进行中的 verdict 对象,不是源码 blob。
    • 这里故意不要求 Kafka,除非设计需要 replay、分析 fanout 或多个 consumer。