千万级学生管理系统的考试试卷存储方案
前言
本文是学生管理系统的考试试卷存储方案设计文档,用于指导考试试卷存储方案的落地和具体细节,预估会有 300 所学校,1000 万的学生使用。
存储空间
假设学校平均有 30 个专业,每个专业每学期平均考 20 门课程,学校之间同专业的试卷也不一样
每年的试卷数:
300 所学校 * 30 个专业 * 20 门 * 2 次 = 360000
每年的答卷数:
1000 万人 * 20 门 * 2 次 = 4 千万
存储空间:
假设一张试卷 20 个判断题,20 个选择题,4 个解答题。判断题每题平均 50 个汉字,选择题题干加选项每题平均 150 个汉字,解答题题干平均 100 个汉字,试卷中还有可能存在图片,假设平均 5 张图一张图的 url 长度为 100,使用 utf8 编码保存,那一张试卷的平均大小为:
20 * 50 * 3 + 20 * 150 * 3 + 4 * 200 * 3 + 5 * 100 ≈ 15KB
那一年需要的空间大小为:
15KB * 360000 ≈ 5.1G
每年的答案数据空间大小:
4 千万 * 1000(主要是解答题占空间)* 3 ≈ 112G
QPS & TPS
假设考试集中一个月内的周一到周五一个算 20 天,一天 4 次考试,而且考试时间也会比较集中。
读取试卷信息会集中在考试前一分钟左右
QPS = 1000 万 * 20 门 / 20 天 / 4 次 / 1 分钟 ≈ 5w/s
提交试卷会集中在考试结束的前半个小时,有人块有人慢
TPS = 1000 万 * 20 门 / 20 天 / 4 次 / 30 分钟 ≈ 1700/s
网络带宽
5w/s * 15KB ≈ 732MB
考试信息存储分析
试卷信息和学生答题信息需要永久保存,而且这些信息的访问就集中在考试的那段试卷,之后很少会访问,所以选择存储到 HBase 集群中,考试时间的试卷信息可以缓存到 Redis 中已做到快速访问
Redis
因为在考试期间,试卷信息会被频繁访问,所以需要提前将试卷缓存到 redis 中,等考试结束后自动过期。也就是 Redis 中同时只要存储一天的试卷信息就够了,15KB 每张 * 180000 张 / 20 天 ≈ 132M。使用字符串类型保存,键为学校 id:课程编号,值为试卷信息。访问时经过考试系统的归并回源每种类型的试卷同一时间只要请求一次 redis,这样打到 redis 的 qps ≈ 180000 张 / 20 天 / 4 堂 / 1 分钟 ≈ 37 次/s,进过服务的归并回源操作加上服务的本地缓存到 redis 的浏览就很少了,主要考虑 redis 服务的可用性可部署一主一从使用哨兵做自动切换。
网络优化
即时做了缓存,服务器到客户端发送的试卷信息的流量还是不会减少,从上面的预计是 732MB,我们需要优化已减少传输的数据,这里我们将试卷分批加载,试卷分判断题、选择题和解答题,考试前一分钟只加载第一部分判断题部分,由客户端在学生答题期间触发加载第二部分和第三部分,触发规则是随机保证在学生答完完加载好下一部分,而且学生的答题速度不一样加上随机分散加载,流量自然也就错开了,所有最终的网络带宽只要考虑前一分钟加载的第一部分就可以了,大概是 150MB,这样通过临时增加考试系统服务节点,临时增加网络带宽就能应对考试场景
评论