我还真做过教务系统。首先抢课是肯定要先开设课程的,然后每个课程就是有限定选课学生数量。 也就是 课程 id ,课程余额 实际业务不单止会判断学生数量而已。 按照判断条件的先后排列的话,我们需要判断这些条件 1. 面向的选课学生范围(一门课首先要设置上课学生的年级、专业范围) 2. 课程类型是否满足(公选课、专业选修课) 3. 是否设置了课程类型的学分上限?(例如专业选修课本次选课只能选 5 个学分的) 4. 上课时间是否冲突?(要判断已经排好的专业课、本次选课的其它课程、实习周、军训时间) 5. 最后才是容量问题 所以针对这种场景,前东家是这么做的 1. 选课需要缓存好各类数据(就上面的那些判断条件,数据量大、硬件差的学校需要缓存一二十分钟的) 2. 选课的相关条件都从缓存取(避免大 key ,redis 多部署几个节点做集群) 3. 打开选课界面的时候,获取的可选课程也是从缓存取 4. 选择课程提交的时候,把课程 id 用 redisson 锁起来,然后进行条件判断 5. 如果成功之后就把选课的相关数据写进数据库 6. 缓存里的数量-1 ,释放锁 这一套下来,几千人抢课还是可以的。 但是实际上我当初提过用消息队列去缓解压力,leader 没用过,不敢用。怕消息队列崩了 当时选课真的一团糟,包括不限于数据库锁表了,jvm oom 了,redis 超时了 因为当时判断条件,真就硬从 Oracle 里面查询啊
第一问,实际上是在问你系统设计问题 而你只是直接回答了其中很小的一个点(做法),也不能说不对,只能说不完全对。 尝试从下面几个步骤回答下: 1. 多问 - 学校总的有多少学生需要抢课 - 学校大概总的有多少非常热门的课程 - 平均到每门热门课程大概有多少学生会同一时刻抢 - 给出一些人数,然后是否可以估算出 QPS 假设:需要抢课的学生 1000 人, 假设查询课程 QPS 粗略估算:1000QPS ,峰值*2 ,算 2000QPS - 其他开放性问题,是否有其他要求 2.初步方案 分为两部来进行涉及: 1. 查询课程(查询并发最大) 设计一个高效的索引和缓存机制,以应对高并发查询需求。方案有:缓存、读写分离等 2. 提交抢课 设计一个分布式锁机制,确保同一时间只有一个学生可以成功抢课。方案有:Redis 、ZK 分布式锁、消息队列等 3.详细方案 - 开始抢课之前,提前将课程-课程余额缓存到 Redis 中 - 使用读写分离,分散查询课程和抢课程写结果时数据库的压力 - 使用 Redis 进行扣减余额 - 扣减成功,记录抢课结果(学生-课程) 4.总结 - 缓存、锁、读写分离、其他方案
线上 Redis 内存满了,应该如何处理? 思路: 1. 解决线上问题,快速恢复线上功能正常访问 - Redis 扩容 - 手动清理不必要的缓存数据,释放内存 线上功能恢复后再做 2. 找出为什么满问题 - 分析 Redis key ,是否是热点数据访问量暴增? - 是否是 缓存 key 设计不合理 - Redis 配置参数不合理,导致内存使用效率低下 3. 避免为什么满问题 - 针对 2 进行优化,增加监控告警等措施