写点什么

学生管理系统 - 考试试卷存储方案

用户头像
紫云
关注
发布于: 2 小时前

前言

  本文是学生管理系统的考试试卷存储架构的详细设计文档,用于指导考试试卷存储的后续开发、测试和运维。

1. 业务背景

  学生管理系统需要对学校提供机考考试业务的支持。考试业务需要能够支持上千万考生同时在线获取考试内容,保存作答内容,限制考生的作答时间。并能够在考试结束后,提供完整的试卷信息和作答信息,给相关的批改老师,用于试卷批改。

  为了保证上千万级的学生在线考试的稳定性和可行性,需要设计一个试卷存储系统,用于支撑大量数据的读取和存储。

综上所述,系统黑盒图结构描述如下:


2. 约束和限制

1. 系统需要支持动态扩缩容:上千万考生同时在线考试,只会发生在期末考试,或者联考等大型考试场景。平时机考的使用频率不高。设计需要考虑平时的运营维护成本。

2. 存储采用 Redis sentinel

3. 总体架构


根据需要提供的业务,试卷存储系统以下三个部分,存储查询服务(对外简称存储系统),机考存储,归档存储。白盒图结构描述如下:

  • 存储查询服务:对外提供试卷导入、试卷查询的功能。对内管理试卷的存储方式、存储位置

  • 机考存储:用于存储当前考试周的考试试卷信息,需要提供高性能高可用读服务

  • 归档存储:用于存储所有的考试试卷。需要支撑海量存储


3.1 架构分析

试卷存储系统的主要业务有两个: 存储试卷内容、提供试卷信息。


根据需求分析,系统有 1000 万名学生,参考 2019 年高校数据,平均每个学校 1.5w 学生,推算系统大约需要服务 700 所学校,师生平均比例为 1:17.5,教师用户数 57 万人。


假设 1:老师需要在考试前一个星期内,将试卷上传到系统里,按每个老师需要负责出一份考试卷。老师上传试卷的时间为工作日的工作时间。试卷的题目量较大,老师不可能一次编辑完成,平均每个老师要修改 3 次完成试卷内容

存储试卷 TPS = 57 万 * 3 / 5 (天) / 8 (小时) / 3600 = 12


假设 2:1000 万学生,每个学生平均 20 门课,考试采用机考,试卷和试题的信息存储在系统内。考试集中在上午 4 小时和下午 4 小时,且请求试卷集中在考试开始的前 1 分钟,周末不考试。则考试周时:

考卷信息 QPS = 1000 万 * 20(课)/ 20(周末不考试) / 4(每天 4 堂考试)/ 1 分钟 = 250 万请求/分钟 ≈ 5 万/每秒


假设 3:老师在批改试卷时,主要是需要调取学生的作答数据,老师熟悉自己出的卷子,在批改过程中不需要频繁调阅试卷信息。因此批改时对试卷的读取性能在这里不做分析


综上所诉,试卷存储系统的主要复杂度,来自千万数量级的学生同时在线考试时,对试卷信息的读取。需要做到高性能高可用。考试有时间限制,而且所有学生同时开始考试,系统需要支持至少 5 万/每秒的试卷查询,同时也需要保证,在整个考试过程中,试卷信息是可访问的。


假设 4:一次考试周,产生 57 万张试卷,每年 2 次考试周,一年产生 114 万试卷。如果系统使用 10 年,则大约有 1k 万条试卷数据。每张试卷的信息按 1M 算,大约 1 年 1T 的数据。根据适当原则,存储在几年内都不会是系统的瓶颈。

3.2 总体架构


  • 系统通过路由动态分配来实现负载均衡。Router 将请求均匀分配到试卷查询服务器。

  • 对于机考业务,试卷查询服务通过 Redis sentinel 访问 Redis 存储查询试卷信息

  • 对于机考业务,选用一主多备,集群选举模式。

  • 对于归档试卷业务,试卷查询服务通过访问 Redis 分片,到指定的 db 查询试卷信息

  • 对与归档试卷存储,选用一主一备的模式,每个分片备份一个副本。可以根据存储的试卷量增长 ,逐年递增存储设备。

4. 详细设计

4.1 核心功能

1)试卷导入流程


涉及角色与规则:

  • 老师:老师时导入流程的操作用户,将试卷信息上传到教师系统

  • 教师系统:处理老师上传的试卷,试卷存储系统返回的试卷 uuid。通过教师系统,将 uuid 和对应的老师、考试关联起来。

  • 存储系统:管理机考存储、归档存储。根据试卷的归属,分配试卷到对应的存储分片。

  • 机考存储:机考时,考试系统通过存储,访问机考存储获得试卷信息。在考试结束后,机考存储的信息会被清空。

  • 归档存储:所有的试卷,按考试年份分配到归档存储的分片中。


2) 机考试卷读取流程

涉及角色与规则:

  • 学生:机考业务的操作用户,通过考试系统,请求开始考试

  • 机考系统:根据学生找到课程系统里,学生当前对应的考试信息,通过 uuid 向存储系统获取考试试卷

  • 存储系统:根据试卷的 uuid,sharding 计算对应的机考存储 db,查找试卷

  • 机考存储:使用 redis,用 uuid 为 hashtable 的 key 存储试卷信息


3)归档试卷读取流程

以老师访问已结束的考试试卷为例,学生的访问流程类似

涉及角色与规则:

  • 老师:课程系统的用户,通过课程系统,查询已结束的考试。

  • 课程系统:根据老师指定要查看的考试,从课程系统的数据库内,找到对应试卷的基础信息,如:学校、考试年份、考试 uuid。并向试卷存储系统发起获取归档试卷信息的请求

  • 存储系统:试卷存储系统,根据请求的试卷基本信息,根据年份查找对应 db,然后根据请求数据里试卷的基本信息,拼接 key(学校+考试年份+uuid),根据拼接的 key 查找信息并返回

  • 归档存储:redis 存储,用 string 格式的 key,归档存储试卷信息


4.2 关键设计

1)考试试卷存储方式

  • 使用 sharding 算法,将当期(一个考试周内)的试卷根据 uuid 均匀分布到 redis 的 10 个 db 中。根据 3.1 的分析,考试周期间,系统需要提供 57 万分试卷,每秒 5 万次的高可用查询读取。每个 db 存储约 6w 条试卷信息。

  • key 格式: HashTable,生成全局试卷唯一编号

  • 存储内容:试卷信息,包括试卷内的题目信息,完整存储。其它系统在请求获取试卷信息时,直接将整条试卷信息完整返回即可,不需分步查询。

  • 存储格式:使用 proto 定义存储格式。考虑到考试时,流量也会成为系统的瓶颈,因此选用占用字节流小的存储格式

2)归档试卷存储

  • 结束考试后,试卷归档到低频访问的 redis 集群中。考虑到 Redis 的读写特点,试卷以考试年份为单位进行存储,同一个年份的数据,必须在同一个 db 中通过 key 里的学校 id 识别属于哪个学校。由存储系统维护年份和 db 的对应关系。如果归档的存储的数据预期新的一年会超过 redis 的承载量,就增加新的 db。如果因为运营变化,需要切换年份对应的 db,需要将历史数据统一导入到新的 db 中。

  • 老师在导入试卷时,同时触发归档试卷备份。即归档备份,在试卷导入系统时已完成。

  • key 格式: String学校 id + 考试年份 + 唯一编号

  • 存储内容:同考试试卷存储,存储完整信息

  • 存储格式:同上

3)试卷查询

  • 试卷查询主要通过其它系统触发。试卷的全局唯一编号冗余在老师系统和学生系统中。

  • 客户端获得试卷数据后,通过预定义好的 proto 解析内容格式。

用户头像

紫云

关注

还未添加个人签名 2019.05.25 加入

被迫做运维的开发

评论

发布
暂无评论
学生管理系统 - 考试试卷存储方案