架构实战营模块四作业
设计千万级学生管理系统的考试试卷存储方案
【作业要求】
基于模块 4 第 6 课的估算结果和 Redis sentinel 的初步方案设计,完善考试试卷存储方案,具体包括:
• 完善 Redis 的数据结构设计,明确具体使用哪种 Redis 数据结构。
• 设计具体的读写流程(可以文字描述也可以序列图描述,序列图要有文字辅助说明)。
• 对照模块 4 第 6 课的性能估算结果,计算 Redis sentinel 集群的服务器数量和性能。
【提示】
1. 性能可以有一定冗余。2. 如果对 Redissentinel 不熟悉,请参考官方文档:https://redis.io/topics/sentinel。
行为建模+性能估算
试题保存的场景,一般是大学老师出题,假设每个科目每次试题都不一样。
试卷记录大小:20 判断题、20 选择题、4 道大题从题干来看,没有图片的情况下假设一道判断题 50 字,选择题加上选项 100 字,大题一道 200 字,则一条试卷大小大约是 50*20+100*20+200+4 ≈ 3000 字*2 字节 = 6KB。
每年试卷数量:假设每门课学生 100 人的考试题目相同,则全年应该有试卷 1000 万人 * 20(课)/ 100 人每课 = 200 万份/年
试卷存储大小:永久存储,200 万 * 6KB ≈ 12 GB/年
试卷写入频率:假设老师在考试月内工作日上传试卷 200 万 / 20 天 / 8 小时 / 3600 秒 ≈ 4 TPS;试卷有存储需求
试卷读取频率:5 万/每秒(热数据);实际上除了考试时,应该还有考生查看答案、老师重新查看并编辑试卷等,这里由于相对于考试时的请求过少,所以并发不会很高,可忽略不计;当前被请求的试题应该是热点数据,而已经过期的试题信息并不是热点数据,需要还考虑如何存储和读取冷数据,以处理每年的存储增量。
数据结构设计
redis
key:试卷 ID
value:试题 json string
mysql
cloumn:自增 ID、试卷 ID、试卷内容
读写分析
上传试卷:老师编辑好试卷, 生成试卷内容并上传 redis,上传完试卷由服务器生成试卷 ID,4TPS
考试读试卷:读取试卷时按照 ID 直接查找即可,5W QPS,且单条数据量不大
至于如果有批量查看试卷列表的需求,包括按学校、学科、出题人、时间元数据等来批量查询的情况,则还需另行生成一条 MySQL 记录来存储元数据,以便后续定制查询,在此不详细讨论。
考试试卷数据有明显的冷热数据区别,可以考虑将近期的数据存在 Redis 中,过往的冷数据迁移至 MySQL 数据库中。
冷数据读试卷:做一个配置,试卷 ID 自增,每年迁移以后配置一下哨兵试卷 ID,大于此则从 redis 查,否则从 MySQL 库查。
热数据存 Redis sentinel
单机是否能存储所有数据:是
单机是否可以支撑写性能:是
单机是否可以支撑读性能:单机 5-10W TPS,比较危险,所以考虑
是否需要自动切换:需要
最终选型:主从切换,一主一从。
冷数据迁移至 MySQL
单机是否能存储所有数据:否
是否需要分区部署:否
最终选型:分片架构,可以随时间平滑扩展,N 台服务器
题外——————————————————————————————————
考试结果记录的存储量为:
在校学生 = 2.4T。
离校学生 = 每年 0.6T,永久保存
请求试卷 ≈ 5 万/每秒。
提交试卷 = 1700/每秒。
数据估算有个 BUG 就是中国汉字应该是 2 字节一个字,则考试结果记录大小,在大题处 800 字应该大概要大一倍,即考试结果记录的存储量为:
在校学生 = 4T。
离校学生 = 每年 1T,永久保存
请求试卷 ≈ 5 万/每秒。
提交试卷 = 1700/每秒。
评论