架构训练营 -- 模块四
1. 业务背景
存储支撑千万学生的考试存储系统,支撑考试周的试卷存储以及快速读取,历史试卷的归档以及读取
系统示例如下,试卷存储系统需要存储热点试卷以及历史归档试卷
2. 约束和限制
热点试卷需要支持快速读取(学生考试需求)
历史归档试卷读取速度可适当放宽要求
热点试卷支持高可用,历史归档试卷支持可恢复
热点试卷采用 Redis sentinel 存储,历史归档试卷采用 HBase 存储
3. 总体架构
历史试卷需要支持海量存储,同时读取请求的需求不高,读取方式基本都是等值查询,或者按学科或年份进行范围查询,因此采用 HBase 进行存储,设计 row key 为 <年份+学科> 或 <学科+年份>,column 可以设置为 shared disk 的具体文件路径或者二进制存储的试卷内容,前者需要涉及额外的 disk io,读取效率不高,后者会重复存储相同数据,浪费存储空间,需要进行一定的平衡
Hbase 可以通过 timestamp 进行上传试卷的版本控制
热点试卷需要进行快速读取,可以通过 Redis 的 hash 结构进行存储,可以以课程 id 为 key,二进制试卷内容为 value 进行试卷存储,由于同一考试期间内都是同一年的试卷内容,所以不需要包含年份信息,每个课程 id 仅会存储一份试卷内容
Redis 采用 sentinel 保证高可用性
4. 详细设计
4.1 核心功能
1)试卷上传
教师发起试卷上传请求
试卷存储服务分别请求将试卷上传至 Redis 及 Hbase 进行存储
2)热点试卷读取(当前考试试卷)
热点试卷读取流程比较简单,考虑到热点试卷读取的发起为考试系统,因此可以设定考试系统发起的读取通过 Redis 进行支持,因为正常情况下考试系统不应该发起往年考试的试卷读取请求,除非的考试练习等,正常情况下考试系统都会发起读取当前学年某一学科的考试需求
试卷存储服务将考试系统的试卷读取请求转发给 Redis 集群进行试卷内容的查询及读取
3)往年试卷读取
往年试卷的读取与热点试卷读取非常相似,不同之处在于往年试卷读取一般通过图书馆系统发起,往年试卷的数据量大,同时也不存在保密等需求
试卷存储服务将往年试卷的读取请求转发至 HBase 进行试卷内容的查询及读取
4.2 关键设计
Redis 存储
key 格式: HashTable,通过业务主键进行存储,譬如 course_id 等
存储内容:试卷内容,包括题目等
存储格式:使用二进制存储格式
HBase 归档存储
key 格式: String, 学校 id + 考试年份 + course_id
存储内容:同考试试卷存储,存储完整信息,利用 timestamp 的版本控制功能,可以存储多份试卷,按照业务需求加以利用
存储格式:可以存储二进制字节或通过 object store 存储的试卷存储路径,后者需要进行一次额外读写,但是可以避免支持不同查询请求时相同试卷内容的重复存储,可以节约一定的存储空间
评论