千万级学生管理系统的考试试卷存储方案
数据结构选型
选择 HSET 的 value 存储试卷的 json 数据,key 为日期+上/下午标识,即 202309010 为上午卷,202309011 为下午卷,field 为试卷编号。例 HSET 202309010 20230901234“[{\“xxx\”,\”yyy\”}]”
理由:1.用日期+上下午标识,可以由服务端根据当前服务器时间查找相应的试卷编号返回
2. 服务端可以根据当前时间,决定清空或加载某批试卷到 redis 服务端可直接返回 value 存储的
json 数据给客户端处理,减少读取时仍要序 列化对服务端 CPU 的消耗
存储容量推算
背景:以大学期末考试作为背景
分析:
大学共有 4 个年级,1000 万学生平均到每个年级里是 250 万。每个年级平均有 500 学生,那 250 万/500 可得学校数量为 5000。
每个学生 1 学期平均 20 门课,则每个学校 4 个年级的试卷加起来为 80 套,向上取整为 100 套。
每天考 4 个科目,因此每天的试卷数量为 5000 所学校*4 个年级*4 套试卷=80000 份试卷
每套试卷有共 44 道题,按 50 道计算,每道题占存储空间为 2KB,因此每天存储试卷的空间为 80000*50*2KB≈8GB
考试分为上下午,因此每个时段只需在考试前提前加载一半的试卷,即 40000 份试卷到 redis,所以实际需要的内存空间为 4G 即可
Redis 存储方案
选用 sentinel 方案实现存储高可用,一主处理读写流量,二从处理读流量,实现计算高性能
冗余存储空间,各分配 10G 内存给主机和从机
三台 sentinel 主机各分配 2G 内存
存储架构图如下:
数据读写流程
试卷内容先写到关系型数据库,如 MySQL
试卷内容通过定时器或管理员操作从 MySQL 加载到 redis
定时器在加载试卷前会根据当前时间戳,清理已过考试时间的试卷,根据 HSET 的 key,即日期+上/下午标识清理
客户端发送考生 ID 到考试服务,考试服务查找考生当前的考试编码,再用考试编码请求试卷服务获取试卷
试卷服务会根据当前时间,计算出 HSET key 的值,然后利用考试编码查找相应的试卷内容返回
版权声明: 本文为 InfoQ 作者【kylexy_0817】的原创文章。
原文链接:【http://xie.infoq.cn/article/a8859cb9b18a507f6cfc42395】。文章转载请联系作者。
评论