架构实战 4- 千万学生试卷存储方案
1、用户量预估
根据题目,确定学生用户量为 1000 万。
2、用户行为建模和性能估算
前提
用 UTF-8 对试卷进行编码,在 UTF-8 编码中,一个英文为一个字节,一个中文为三个字节。
每门考试的内容为:20 道判断题、20 道选择题、4 道大题。
性能估算
试卷大小分析
判断题只有题干,假设题干有 50 个汉字,UTF-8 编码后,有 50 x 3 = 150Bytes,20 道题总大小为:20 x 150Bytes = 3KB。
选择题包括题干+选项,共 200 个汉字, UTF-8 编码后, 有 200 x 3 = 600Bytes, 20 道题总大小为:20 x 600Bytes = 12KB。
每道简答题只有题干,假设题干有 200 汉字, UTF-8 编码后, 有 200 x 3 = 600Bytes, 4 道题总大小为:4 x 600Bytes = 2.4KB,取整约为 3KB。
所以每张题目试卷占用 (3 + 12 + 3)= 18KB, 考虑有一些题目有图片, 图片以 URL 进行存储,图片 URL 平均每条 100 Bytes, 假设每张试卷有 20 张图片, 需要 20 x 100Bytes = 2KB, 再考虑 2KB 的冗余,则每张试卷计为 22KB。
试卷样数分析
根据网上资料查询可得,平均高校人数在 5 万人左右(本科生 + 研究生),1000 万人数平均分布在 200 所高校中,假设高校平均专业数为 100,每专业平均一学期有 20 门课,则 Redis 中需要存储 200 x 100 x 20 = 40 万份不同的试卷内容。
总容量
每份试卷 22KB, 共有 40 万份不同的试卷, 则总的存储空间为:40 万 x 22KB = 8.8GB, 取整约为:10GB
结论
考虑到 Redis 自身的内存运行机制,(主要是 rdb 持久化/AOF 重写/内存剔除策略等),同时又考虑到 Redis 本身维护数据结构也要占用一定空间等情况,选择使用 32G 的机器来跑 Redis。
又因为试卷请求的 QPS:5 万/s,提交试卷的 TPS:1700/s,读性能要求较高,所以 Redis 采用一主两从的结构,进行读写分离;同时为了保证高可用,在发生故障时,要保证能够自动切换,所以采用 Sentinel 进行自动切换。
3、数据结构设计
试卷存储方案
【数据结构设计】
Key: 学校 ID + 考试 ID 。
Value:考试内容,采用 Json 字符串形式的 String 结构。
【读写分析】
老师可在考试前几天,将试卷上传到 Redis 中。
学生集中在考试开始的前 1 分钟请求试卷,用 学校 ID + 考试 ID 向 Redis 进行请求。
Redis 根据不同的 Key 值返回相应的考试内容,并存储在本地的缓冲中。
如果第一次请求试卷失败,可进行二次读取。
学生考试结果(Hbase)
【数据结构设计】
Key:学校 ID + 学号 ID + 考试 ID。
Column Family:test。
Column:esult, score, 其中 result 是 JSON 格式。
【读写分析】
学生提交考试结果,直接按照 key 保存 result;
老师改卷后,直接写入 score;
学生查看自己的成绩,按照 key 读取 result 和 score,可以看到得分和具体错在哪里。
从 Hbase 中,将数据同步到 MySql,方便老师进行分析。
版权声明: 本文为 InfoQ 作者【源】的原创文章。
原文链接:【http://xie.infoq.cn/article/f62fcf651eef111486167b5f0】。文章转载请联系作者。
评论