架构实战营作业 M04
已知存储性能需求:
请求试卷:5w/s
提交试卷:1700/s
已知:Redis 数据模型包含下面几种
String
Hashtable
Linked List
Set
Sorted Set
前提:
这里选择题默认都是单选题,如果有多选的场景,额外拆分出一个类目”多选题“,和其他题目类型同级别处理
考卷存储结构
因为是机考,所以出试卷的方式有多种策略:
所有学生试卷一致
学生试卷题目固定几种,如 AB 卷
学生试卷题目完全随机
且可以设置每类题目出现顺序是否一致
然后因为需要支撑多种学科、多门课程的试题,所以需要考虑到题库之间的数据隔离。因为学科、课程种类繁多,虽然 Redis 支持多 DataBase,但是显然是不能够满足一类考试一个 DataBase 的。所以将所有题库都放在一个 DataBase 中,通过 Key 的 Pattern 来区分开类别。
1. 所有学生考卷一致
如果考卷内容完全一致,那么其实只需要老师在他的教师端系统编辑好考卷,然后在 Redis 中存储一份试卷内容即可。Redis 中 Key 满足下面格式:
course_id 为其他存储(系统)中,科目、课程对应的主键,为方便下面描述,这里统一选取 course_id = 0 进行描述
其中 fixed 为考卷策略的缩写,为了和下面几种不同策略保持整体 Pattern 的一个一致性而保留。Redis 中的 Value 为实际的题目内容,可以使用 JSON 格式进行保存。整体格式形如:
这里需要考虑到题目出现顺序的可配置,但是同类题目顺序的随机化其实没有必要在 Redis 上进行操作,完全可以学生请求试卷时,后端程序根据配置使用代码进行顺序的随机化。这样在 Redis 上实际存储内容无需变动。个人感觉更加方便。
请求试卷流程:直接获取对应 Key 的考题内容,按照是否需要”题目顺序随机化“需求,生成考卷内容,返回前端
2. 学生试卷题目固定几种
和上面的存储类似,不过是老师在制作试卷的时候需要制作多套而已。实际 Value 的存储设计也可以和上面的策略保持一致。Key 需要区分出场景,满足下面的 Pattern
其中 multi 是固定字面量,用于标识出这个 K,V 放的都是 AB 卷这种形式的卷子内容
当学生在获取试卷时,后端程序先按照一定算法(如 A、B、C 卷随机)指定一套卷子,然后用同策略 1 一样的方式获取试卷内容即可。
请求试卷流程:直接获取对应 Key 的考题内容,按照是否需要”题目顺序随机化“需求,生成考卷内容,返回前端
3. 考试题目完全随机
和上面 2 种策略不同,试题随机处理起来相对复杂。因为题目随机,所以需要引申出”题库“的概念。学生请求试卷时,需要后端程序能够动态的从题库中提取出指定数量的题目,生成试卷。Key 我们和上面保持类似的 Pattern:
其中 rand-tk 标识这是试卷内容的题库,question_type 用来区分是哪类型的题目
为了方面描述,做下面的定义:
判断题:question_type 固定为 panduan
选择题:question_type 固定为 xuanze
大题(问答题):question_type 固定为 wenda
所有类型题目都使用 Set 进行存储,因为涉及到题目的随机化,这部分逻辑如果放在后端程序进行实现,需要拉取整体题库,然后随机化。这样操作对网络、Redis 性能影响可能都比较大,且如果在后端进行局部缓存的方式来提升性能,那 Redis 的意义又不太明显。所以考虑将随机化动作放在 Redis 侧,利用 Redis 的 srandmemeber 命令来从集合中获取随机内容。
Redis 中 Value 为实际题目的内容,因为在 Key 层已经区分了 question_type,所以 Value 可以用下面的格式进行存储:
ps:因为考题在一开始已经随机化,所以试题出现顺序的随机化这个动作没有什么实际意义了
请求试卷流程:后端程序分别从 3 类 question_type 的 K,V 中 srandmemeber <key> [count]出指定数量的题目,然后生成考试试卷,返回给考试系统即可。
学生试卷答案
经评估,考生提交试卷的 TPS 要求约为 1700,量级不大,这部分逻辑如果放在 Redis 的话,可以使用 Map 进行存储,其中 Key 为上面提到的题目 id,Value 为实际的答案,比如判断 T/F、选择题存 A/B/C/D、大题直接存学生填入的内容
这样存储结构比较简单,也可以满足实际需求。
服务器数量评估
经评估,Redis 集群化方案使用 Redis Sentinel。单机 Redis 的 TPS 为 5~10 万。那么按照性能需求的 5w 来计算,最好能够保证 2 台 Slave 来处理读请求,Master 负责 Cover 提交的场景。整体评估如下:
总共 Redis 需要 3 台机器,其中 1 台作为 Master、2 台作为 Slave
Slave 单机负责 Cover 约 2.5w 的 TPS,Master 负责 Cover1700 的提交 TPS
版权声明: 本文为 InfoQ 作者【Shawn Liu】的原创文章。
原文链接:【http://xie.infoq.cn/article/767823939adcc8344307b44ba】。未经作者许可,禁止转载。
评论