架构实战营模块 4 作业
题目
基于模块 4 第 6 课的估算结果和 Redis sentinel 的初步方案设计,完善考试试卷存储方案,具体包括:
1)完善 Redis 的数据结构设计,明确具体使用哪种 Redis 数据结构
2)设计具体的读写流程(可以文字描述也可以序列图描述,序列图要有文字辅助说明)
3)对照模块 4 第 6 课的性能估算结果,计算 Redis sentinel 集群的服务器数量和性能
题目分析
相关的考试性能评估详情
每秒 5W 的 QPS,这个量级还是比较吓人的,但考虑到几乎全部是读取,单台 redis 完全可以胜任。在考虑高可用,那么 redis sentinel 就可以应对,其实 Redis Cluster 不是更香么。
场景分析
试卷既然放到 Redis 中保存,必然是序列化保存的的,按照应用场景区分为写入和读取。
1)出卷场景分析
老师出卷时是一道一道出的,而且他肯定不想刷新一下界面就把数据都丢了,而且很有可能后面还去修改之前出的某张试卷的某个题目。
ok,梳理一下需求:
可以将整张试卷保存下来
修改某张试卷的试题
以读取之前的某张试卷
2)考试场景分析
学生考试获取试卷都是整张试卷读取的,没有范围查询的需求,因此最好是直接能把试卷的全部题目读取出来。
题目回答
完善 Redis 的数据结构设计
我们知道 Redis 中共有五种常见数据结构: 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets)。
根据我们场景分析结论,进行存储的数据结构涉及。
直接采取字符串的话,直观上可以满足需求,但这需要将正张试卷进行序列化和反序列化,这在保存和读取整张试卷是没有问题的,但在修改上就需要读取整张试卷,然后修改对应部分,再重新序列化并保存,怎么看都不是很合适。但字符串比较适合保存试卷状态,如编辑中或是已发布。
散列:适合于试卷-题目两级存储,但由于存储的数据没有顺序,不太合适保存有顺序属性的题目。
集合:适合于试卷-题目两级存储,但由于存储的数据没有顺序,不太合适保存有顺序属性的题目。
列表:适合于试卷-题目两级存储,其实是比较适合存储试卷的,但由于还想修改指定试卷的指定元素,这需要 O(n)的复杂度,n 为列表长度
有序集合:适合于试卷-题目两级存储,将题目序号作为 score,题目序列化后作为 value 存储。学生考试时获取整张试卷通过 ZRange min max 实现,老师出题时添加或修改题目通过 zadd 序号 题目序列化值实现。
接下来就在于 Key 的设计了,需求也是比较明确的,希望能够直接读取到指定的试卷,那么只需要考虑试卷的一些基本属性,如下所示。
年份(2021)
学校(学校代号)
年级(高三-3)
科目(物理-PHY,化学 CHE)
考试类型(期中-MID,期末-END)
key 的示例如下:
综上所述:
设计具体的读写流程
出试卷场景(试卷写入)
老师再前台编写试卷的题目
前台将题目数据传输到后台
后台将数据序列化为 value
后台组装试卷的 key,index 代表序号
后台通过 ZADD key index value 写入数据
重复 1~5 步直至全部题目保存完毕
前台保存整张试卷
后台组装试卷状态的 key
后台通过 set key 已发布来实现试卷状态的变化。
开始考试场景(试卷读取)
前台读取指定的试卷
后台组装试卷的 key
后台通过 ZRange 1 44 读取全部的题目
将全部数据反序列化为题目数据返回前台
前台根据返回的数据进行渲染
计算集群的服务器数量和性能
试卷存储估算细化
课程里只给出了选择 RedisSentinel 的选型,但估算这块没有详细估计试卷的存储,为了后面服务器估算,因此在这里补充一下对试卷存储的估算,课程中估算的核心数据如下:
1000 万学生
每年考 2 次
20 门课
假设每 200 人一个年级,即一共有 5 万个年级,结合 20 门课和每年 2 次考试,则每年共有大概 200 万不同的试卷。
一份试卷由 20 判断,20 选择,4 道大题组成,这里将所有的图都保存到 CDN,文件另行存储,试卷中大部分为汉字(一个汉字 2 字节)。可以估算 20*100*2+20*(100+40*4)*2+4*400*2=17600 字节,为留出余量,按照 20kb 估算。
【为了验证估算,又找了一个高三的政治月考试卷全部文字加起来不到 4000 字,因此 20kb 大小估算还是留出了相当大余量的。】
则试卷所需的存储共计 2000000*20kb=40GB。
服务器数量和性能
上面计算得到年度全部数据应该不超过 40G,服务器内存 64G 内存就差不多了,Redis Sentinel 使用的必然要组成集群,至少三台服务器,每台服务器部署一个 Sentinel 和一个 Redis 节点。由于 Redis 需要持久化数据因此不可避免的需要频繁访问硬盘,所以硬盘还是配备一个固态比较好。
学习分享
这个模块主要讲的就是数据存储的设计,还是老样子,分为 3 次上 6 个课时。
先后介绍了存储架构的基本概念,复制架构,分片和分区架构,作为基础知识。
紧接着从理论上介绍了如何设计存储架构,简单来说就是先估算性能需求,再选择存储系统,然后设计存储方案这三步,后两步是不断迭代进行的。
然后又介绍了常见存储系统,从技术本质上介绍了 hbase,redis,ClickHouse 以及 HDFS,这个很赞。
最后结合之前的千万级学生管理系统的示例,进行了存储系统设计的实战。
学完了这些课程之后还是一种看上去很简单,但自己干时却是一种找不着方向的感觉,架构确实是比较微妙很吃经验和感觉。
后面只能再把课程多复习几遍,慢慢的找感觉,很多东西不是一朝一夕就能搞定的。
版权声明: 本文为 InfoQ 作者【En wei】的原创文章。
原文链接:【http://xie.infoq.cn/article/8ef6b958c6f4586b2da202052】。文章转载请联系作者。
评论