架构训练营 - 模块四作业
前言
本文是千万级学生管理系统的考试存储架构的架构设计文档,主要用于指导考试存储架构的部署与运维实施。
词汇表
redis:Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache, and message broker。Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。是最受欢迎的 NoSQL 数据库之一。
redis sentinel:官方文档定义:Redis Sentinel provides high availability for Redis. In practical terms this means that using Sentinel you can create a Redis deployment that resists without human intervention certain kinds of failures。即 Redis 哨兵(Sentinel)模式,通过哨兵监控多台 redis 服务器运行状态,实现故障自动切换的高可用模式。
MySQL:是一个数据库管理系统,也是一个关系数据库。
MongoDB:是一个基于分布式文件存储、面向文档的 NoSQL 数据库,由 C++编写,旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系型数据库的,它支持的数据结构非常松散,是一种类似 json 的 BSON 格式。
负载均衡:是高可用网络基础架构的关键组件,通常用于将工作负载分布到多个服务器来提高网站、应用、数据库或其他服务的性能和可靠性
主备机制:一种数据同步备份机制,通常主机支持读写操作,备机只进行读操作,且在主机发生故障时,备机可以切换为主机,实现主机的读写操作功能。
1. 业务背景
在千万学生管理系统存储架构设计中,学生数量的量级为 1000 万,在考试场景中,学生的试卷的读取量是主要的性能要求,估算同时系统同时读取试卷的请求量为 QPS=10 万/s,同时写试卷内容的请求量为 QTS=1 万/s,因此采用 RedisSentinel 的存储架构进行设计。
2. 约束和限制
1)开发语言选择 java
2)成本限制在 XXX 元以内
3)开发周期在 XX 年 XX 月 XX 日完成发布上线
4)缓存数据库限制使用 Reidis
5)开发方式采用敏捷开发方式推进
6)系统数据不能丢失,可用性为 99.99%
7)支持瞬时最高读写请求分别为 QPS>=10 万/s 和 QPS>=1 万/s。
3. 总体架构
3.1 架构分析
3.1.1 高可用
对于学生的考试试卷管理系统来说,学生考试的试卷是不能出现数据丢失或者无法使用的情况,否则会严重影响学生的学业统计的,因此系统要有高可用的要求,高可用度为 99.99%。
3.1.2 高性能
系统对同时读取试卷的指标假定为 QPS=10 万/s,因此对读性能要求要求极高,同时要要保证 QPS=1 万/s 的写性能要求,因此系统偏向于高性能要求。
3.1.3 可扩展
考试试卷存储系统在可扩展方面,没有过多的需求,当前系统架构即可支持上千量的学生使用,如果后续要扩展直接进行服务器的升级即可。
综合来看,学生管理系统需要高可用性和高性能读写请求,且主要是高性能读的要求。
3.2 总体架构
1)对于系统请求,系统通过 Router 路由动态分配的方式来实现系统的负载均衡。将请求按具体的路由算法分配对不同的试卷服务器上,降低当点系统的读写压力,保证系统的可靠性。
2)对于考试业务,试卷查询服务通过 Redis sentinel 访问 Redis 存储查询试卷信息对于机考业务,存储方案采用一主多备,集群选举模式,保证系统的高可用和防单点故障。
3)对于考试后的试卷进行归档的业务,试卷查询服务通过访问 Redis 分片,到指定的 db 查询试卷信息对与归档试卷存储,系统采用一主一备的模式,每个分片备份一个副本。可以根据存储的试卷量增长,逐年递增存储设备。
3.3 关键设计
1)考试试卷存储方式
使用 sharding 算法,将当期(一个考试周内)的试卷根据 uuid 均匀分布到 redis 的 10 个 db 中。根据 3.1 的分析,考试周期间,系统需要提供 57 万分试卷,每秒 5 万次的高可用查询读取。每个 db 存储约 6w 条试卷信息。
key 格式: HashTable,生成全局试卷唯一编号
存储内容:试卷信息,包括试卷内的题目信息,完整存储。其它系统在请求获取试卷信息时,直接将整条试卷信息完整返回即可,不需分步查询。
存储格式:使用 proto 定义存储格式。考虑到考试时,流量也会成为系统的瓶颈,因此选用占用字节流小的存储格式。
2)归档试卷存储
结束考试后,试卷归档到低频访问的 redis 集群中。考虑到 Redis 的读写特点,试卷以考试年份为单位进行存储,同一个年份的数据,必须在同一个 db 中,通过 key 里的学校 id 识别属于哪个学校。由存储系统维护年份和 db 的对应关系。如果归档的存储的数据预期新的一年会超过 redis 的承载量,就增加新的 db。如果因为运营变化,需要切换年份对应的 db,需要将历史数据统一导入到新的 db 中。
老师在导入试卷时,同时触发归档试卷备份。即归档备份,在试卷导入系统时已完成。
key 格式: String, 学校 id + 考试年份 + 唯一编号
存储内容:同考试试卷存储,存储完整信息
存储格式:同上
3)试卷查询
试卷查询主要通过其它系统触发。试卷的全局唯一编号冗余在老师系统和学生系统中。
客户端获得试卷数据后,通过预定义好的 proto 解析内容格式。
评论