昨天面试的几个 MySQL 和 Redis 的题目,来请教一下

236 天前
 dumbbell5kg

1.MySQL 里的记录有这么两个字段:
课程 id课程余额
同时间大量学生抢同一门课,如何设计这个功能?

2.线上 Redis 内存满了,应该如何处理?

3.你认为解决高并发问题的本质是什么?

求大佬赐教 orz

8136 次点击
所在节点    数据库
63 条回复
hoythan
236 天前
不如你先说说你怎么回答的。
BiChengfei
236 天前
缓存 异步 分区
dumbbell5kg
236 天前
@hoythan
1.我:我说这是一个热点行数据争用锁的问题,可以把一行课程数据分成多行,减少行锁争用
面试官:这样增加编程复杂度,而且性能也不会高
我:可以把课程数据放到 Redis 里,用 lua 脚本来做,lua 脚本里判断课程余额,减少余额

我说完就问下一题了,但是我觉得是不是有更好的方案?这个问题就用 Redis 感觉问的价值不高呀

2.完全没思路

3.
我:大部分系统瓶颈都在数据库 IO 上,一般可以 NIO 这类技术避免 IO 等待
他没怎么说话,我感觉也不是这个答案
zhoujx
236 天前
1.感觉是秒杀库存问题
2.人工删除一些业务废弃的 key ,统计一些可以清理的先清理掉。
3.锁、如何优化锁、什么条件下可以不用锁
zhoujx
236 天前
@zhoujx 第三点范围很大,不好说
c3de3f21
236 天前
有没有可能有的点没放出来就是在等你聊?等你一步一步和他确认出问题?

- 比如什么业务场景下 redis 内存满了?是跑起来就满了还是突然就满了?
- 比如什么情况下的高并发?是类似抢课造成的并发?还是中台或者什么情况下造成的高并发?
- 不同的业务场景给他不同的回答
Orlion
236 天前
2. 先扩容保证服务可用,根据业务选择合适的缓存淘汰策略,如果是上线后引起的,能回滚先回滚,然后排查代码看下是否是正常内存占用(过期时间设计是否合理等等)
3. 个人认为是性能与事务(一致性)的 tradeoff
guisheng
236 天前
第一个直接弄一个 key ,decr 做减法不就好了么,还是我想的简单了
第二个内存满了,可以停机和不可停机有不同的处理方法,最简单的删除一些内容,这里面有个专业术语 淘汰策略,事后扩容或者集群
第三个 在高效率的情况下避免程序出现问题
qping
236 天前
@BiChengfei 这是回答的哪个?
dobelee
236 天前
1. 秒杀问题(队列)
2. 检查 key 补上过期时间(监控告警、扩容)
3. 高性能的同时保证并发安全(锁、幂等)
qxdo1234
236 天前
1 可以参考我这个问题,差不太多,有大佬回答了个还算靠谱的答案
Rache1
236 天前
1 、乐观、悲观锁都行?
2 、第二个肯定是先扩容,然后再排查,可以先拉 bigkey 看看人工清理一些,如果近期有新功能上线涉及到了,就先回退。
LieEar
236 天前
我来斗胆回答一下,麻烦各位大佬指正:

抢课是谁先到先得模式,还是先报名再摇号方式?考虑到学校的硬件性能不会太好,先开启限流,比如 nginx ,就让 1 秒钟只有 500 个请求,避免系统崩溃。抢课过程:
第一种,可以开启事务,开启事务->扣减课程余额->给学生添加课程信息->结束事务;
第二种,先在内存中记录下课程 id 和对应的学生学号。比如限制一天内报名,到期后,随机抽取 n 个学生。然后余额=0 ,给学生添加课程信息。可以使用 redis ,或者本地 cache

redis 满了,看是不是某些超大的 key 没有设置过期时间,可以优先把这种忘记设置过期时间的临时 key 删除掉。如果 key 都在使用中,而且数据都有意义,只能加内存。开启内存淘汰机制,LRU

解决高并发的本质是什么?
资源是有限制的,对于远超资源的流量,如何处理。比如抢课,只有 50 个名额,但是有 500 个学生要来抢课;或者说我的服务器硬件不行,无法处理那么多请求,大量流量下如何不宕机。首先要限流,不让系统被大流量打崩溃。到了具体的数据要加锁处理。数据修改完了,后续的其他操作(比如给学生添加课程信息),异步解耦还是跟着同步操作。
WashFreshFresh
236 天前
1 、告诉学生余量很多,放心,不用抢,有空上去选就行。学生嘛,好忽悠。
2 、flushdb
3 、本质是资源不足、生产力不足,加机器只能缓解,不能解决实际问题。
kenneth104
236 天前
1 ,只从 MySQL 看,那用乐观锁或悲观锁,分库分表。。
2 ,如果硬件暂时无法拓展,缩短过期时间,让压力分担到后端,同时考虑其他方案拓展这个 Redis,例如分布式等等
3 ,解决高并发的本质是,解决资源争用。需要对资源管理,对资源的横向纵向扩展,解决队列和熔断,等等
fzzff
236 天前
本菜鸡的主观回答:
1. 考察互斥锁吧, 这种抢课的场景加个悲观锁就完全 ok, 再大点规模的并发考虑上消息队列
2. 如果项目本身使用 redis 就比较多那应该在设计初期就构建 redis 集群以保证动态扩容的灵活性; 如果是短期异常增长导致, 排查是否有异常的大规模缓存, 清理废数据; 再就是可能业务规模突然爆发超出预期, 我觉得可以全量备份以后到新服务器恢复数据然后后端暂时切换 redis 的连接
3. 并发问题主要在 io 和锁资源竞争, 优化 io 的基本方式就是异步解耦吧, 锁的话主要是对应业务场景下选择合适的锁
imokkkk
236 天前
1.方法有很多 说一个上面没提到的 合并请求 把多个扣减课程余额的事务维护在内存或者缓存,合并成一次批量扣减课程余额的事务
2.搞不懂这个问题想问什么 分析大 key? 内存淘汰策略?集群架构打散数据?
3.这个问题大了 不好回答
性能优化:代码优化(异步、并行、各种资源的池化)、缓存(Nginx 静态缓存、CDN 、JVM 缓存、Redishuanc)、数据库优化(索引、大数据量下的分库分表、分布式数据库)
分布式架构:微服务拆分(水平扩展、负载均衡)
并发控制:高并发带来的问题(合理的使用锁、尽量避免事务/长事务、乐观锁)
监控:APM 、压力测试
xxxccc
236 天前
高并发的本质就是有效的资源下完成更多的请求。如何完成更多的请求?
1. 减少单个请求的处理时间。从缓存、异步的角度考虑。
2. 提升服务承接并发数。以 web 服务为例子,就是提升最大连接数。
另外一方面就是扩展性,如果服务都是无状态的服务,那么直接水平扩展,因此这要求服务尽量做到无状态。
cenbiq
236 天前
1.乐观锁,人再多那就只能队列解决;
2.不造;
3.资源永远是有限的,而 IO 资源更为有限,所以高并发的本质是抢夺有限的资源,解决方法是对资源合理利用(线程和锁的优化,缓存)、流量进行削峰填谷(消息队列)、以及服务器负载均衡来尽量确保资源的合理分配。
8355
236 天前
@WashFreshFresh 6 实在是 6

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1035477

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX