设计千万级学生管理系统的考试试卷存储方案
一、考试性能估算
假设每门学科每年 2 次考试,每个学生平均一学期 20 门课,考试采取机考的方式,每门考试的答案 20 判断题、20 选择题、4 道大题(答案 200 字以
内),考试结果永久保存,在校学生能够看到自己曾经的考试结果,
则考试结果记录的存储量为:
• 在校学生:1000 万 * 20(课)* 2(考试次数) * 1000(答案)* 2(学期) * 3(只有前三年考试)= 2.4T。
• 离校学生:每年 250 万,存储量为 0.6T。
假设学校的考试都安排在某一个月内,考试的时候请求试卷,提交答案,中间答题过程浏览器本地完成,由于考试集中在上午 4 小时和下午 4 小时,
且请求试卷集中在考试开始的前 1 分钟,提交答案集中在考试结束前的 30 分钟,因此估算如下:
• 请求试卷:1000 万 * 20(课)/ 20(周末不考试) / 4(每天 4 堂考试)/ 1 分钟 = 250 万请求/分钟 ≈ 5 万/每秒。
• 提交试卷: 1000 万 * 20(课)/ 20(周末不考试) / 4(每天 4 堂考试)/ 30 分钟 = 1700/每秒
总结:
在校学生考试结果存储:2.4T;
离校学生考试结果存储:每年增长 0.6T;
试卷请求 QPS:5 万/s;
提交试卷 TPS:1700/s
二、数据结构分析
1.试卷的数据结构分析-Msql
一张试卷一般包括单选题(10)、多选题(20)、判断题(10)、填空题(10)、简答题(4)、分析题(4),平均每道题干和内容 100 汉字,则整个试卷的大小 10*100+20*100+10*100+10*100+4*100+4*100=5800KB,大约 6M,就是一张试卷基本上是 5M 的大小; 20(课)* 2(考试次数)* 2(学期)* 3(只有前三年考试)*2(AB 卷)=480(张试卷),480(张试卷)*6M=2.5G,教师需要组合 480 套试卷,大约 3G,这样的数据量 Mysql 完全可以支持,而且每个试卷中的试题按行去存储,这样有利于老师的对试卷的组合和修改。由于考试时的 QPS 是 5 万/s,提交试卷 TPS 是 1700/s,为了支持考试时的高并发和高可用,需要老师在完全组卷完成后把试卷同步到 Redis,进行数据缓存。
2.试卷缓存的数据结构分析-Redis
一张数据以 JSON 的格式存储在 Redis 中,用 hash 的数据结构
key:schoolCode(学校编码)+department(系院)+courseCode(课程)
field:paperId(试卷 ID)
value:试卷内容(json 格式)
由于试卷是暂存的,为了考试时高并发时的高可用性,在考试完后,试卷就可以删除,所以对不同的 Key 设置过期时间。
3.试卷提交答案的数据结构分析-Redis
由于试卷答案提交时答案是在有限时间内提交,TPS:1700/s,所以提交答案先把数据提交到 Redis,教师批改后,再把答案数据同步到 Hbase,作为永久保存。
试卷的答案保存也是用 Hash 的数据结构
key:schoolCode(学校编码)+department(系院)+studentCode(学生编号)
field:paperId(试卷 ID)
value:答案内容(json 格式)
4.学生试卷永久保存-Hbase
学生成绩永久性保存用 Hbase
数据结构
Key:学校 ID + 学号 ID + 考试 ID。
Column Family:test。
Column:result, score, 其中 result 是 JSON 格式
5.读写流程
试卷读写流程如下:
6.Redis sentinel 集群的服务器数量和性能
学生考试时,开卷的试卷请求 QPS:5 万/s,提交试卷的 TPS:1700/s,在这个性能指标下,Redis sentinel 集群的要求最小要在 5w-15w 之间,因为 Redis 单台服务器理想情况下是 5W-10W(QPS),需要需要至少台服务器提供读取,所以需要做成三从提供服务。如下图:
7.试卷存储架构图
由以上几点分析可以知道,试卷存储的架构图如下:
评论