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

204 天前
 dumbbell5kg

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

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

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

求大佬赐教 orz

8045 次点击
所在节点    数据库
63 条回复
darkengine
204 天前
你认为解决高并发问题的本质是什么?

- 如何最大化资源利用率
LiaoMatt
204 天前
3.你认为解决高并发问题的本质是什么?
我认为是解决客户端体验一致性问题, 因为客户端不能理解为什么并发高低会影响服务, 对于客户端来说, 它希望服务端的表现不要偏离这个预期, 偏离这个预期就算破坏了客户端体验的一致性;
boboaiya3
204 天前
@admol #36 qps=并发/响应时间
dilu
204 天前
小菜鸡一枚,尝试回答一下,以下答案没查阅资料也没参考楼上大佬们的答案。

1. 这个问题我觉得可以分开讨论一下,首先如果真的只是学校的抢课场景,从经验来说,那就算有并发也不会有很高的并发,在不保证高可用的情况下(如果真是学校抢课,没必要真的做什么高可用吧?)单台 redis 足够支撑需求了,最简单的实现肯定是 setnx ,但是可以从这里延伸一下,例如锁的时长要设置多久,锁过期了怎么办,要不要重试等等八股文,也可以用 lua 脚本,但是缺点是什么巴拉巴拉(掺杂八股文)
但是如果不是简单的学校抢课场景,而是电商的抢购商品这种场景(说时候电商秒杀的八股文和方案大家估计背的比我熟了吧?)既要保证高可用也要数据一致性的情况下,我觉得可以这样设计:

a) 根据以往秒杀时期的数据前提下,前端直接抛弃一部分流量,例如只有 20%的请求才能真正的请求,80%的请求在前端直接抛弃。
b) 秒杀请求进入队列,这样可以把对 redis db 等资源的峰值削平避免服务出现毛刺。由于是秒杀场景,失败了用户也会重试,所以完全可以不在意消息是否会丢失,这种情况下 mq 的性能绝对是能承载主流量的
c) 在消费的时候,再按照商品纬度加锁,这里可以用 redis 集群模式,也可以用 zk 等等组件,调你熟悉的讲,例如你熟悉 redis 的 redlock 那就讲 redlock ,熟悉 zk 脑裂你就讲脑裂

2. reidis 内存满了怎么办?我认为有也得分类讨论(前提是 redis 满了已经导致服务不可用了,如果配置了内存淘汰策略那就不用在乎满不满了)
a) 首先确认这个 redis 里面的数据是不是全是“缓存型数据”,如果是,可以挑一些 topn 的 key 先删一批,先让服务正常可用,然后迅速扩容,如果能动态扩容最好,如果不行先用 rdb 复制一台更高规格的 redis ,然后切换过去。
b) 如果 redis 后面不是传统 MySQL 或者 qps 不高的情况下,直接重启是最好的办法,当然这种情况不太常见,如果 qps 过高可能会直接拖垮 DB 。
c) 这件事的关键是要做好事后复盘、做好防护,避免下次再出问题,一个是要增加 redis 内存监控告警,超过 80%要告警,其次要配置一下 redis 的缓存淘汰策略,(这里也可以卖弄一下 LRU 之类的八股文)。

3. 我认为并发问题就是资源竞争的边界问题,解决并发的问题就是让资源竞争的请求从并行变成串行(加锁),让无序变有序,让混沌变秩序。这里可以卖弄一下读写锁,互斥锁,CAS ,原子操作之类的八股文。



其次,有一些关于面试的经验,想分享给 V 友们。

1. 面试跟谈恋爱是一样的,眼缘最重要,而不是闯关或者解密游戏,答对所有题,写出所有算法,不会决定你能否通过,能通过面试,一个是因为合适,一个是因为眼缘。而我认为后者的占比更大一些,所以建议可以适当处理一下个人形象,面试的时候别太颓废,别太随意。不管是面试还是生活中,看起来让人舒服的人,总能占更多的好处。

2. 面试的时候,问题不会,算法不会是很正常的一件事,计算机的知识没人能做到全都懂,你需要做的是把握面试节奏,让面试官去讨论你熟悉的东西,引导面试官的话题。例如楼主的题目,问你 redis 怎么实现分布式锁,如果你不熟悉 redlock 但是你熟悉 zk 那就说不好意思面试官,xxx 我不太熟,但是 zzz 我用的比较多,zzz 的原理是这样的 balabala 。要把节奏掌握在自己手中。

3. 面试官不一定能决定你是否通过,很多情况下还是 HR 话语权大一些

4. 面试前最好了解一下面试的公司和部门,他们有什么产品?主营什么业务,熟悉一下,对方问起来可以增加一些好感。

5. 面试必问,自我介绍、离职原因、语气薪资,这些问题一定要提前想好避免回答的时候大脑一片空白。
xhawk
204 天前
1. 同时间大量学生抢同一门课,如何设计这个功能?

场景分析: 同时大量, 代表资源是有限的。 所以基本策略就是限流和排队的机制。

技术逻辑: 其实跟淘宝的竞拍逻辑基本一样,就是粥少僧多的逻辑。 用户入口与业务入口要做分离, 确保所有用户都可以正常登录,业务入口的请求做流量限定, 同时规划请求 timeout 时间, 确保想提交的人都有机会提交。 提交之后, 要额外开通一个排队的表纪录 用户的提交时间和纪录。 后端的异步逻辑通过用户的提交时间和纪录的合理性确定是否命中这门课。

最后效果: 所有想选课的人, 都能实时在线跟踪课表情况, 想选这门课的人, 基本上, 都有机会提交选票, 同时派发选票号码,并作公布。 采用后端的异步机制, 确认最终命中的人的选票。



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

技术逻辑:Redis 内存满首先是查找问题原因, 能从源头解决最好, 不能解决的话, 只能从技术测来解决。redis 是有 cache 的, 可以在 config 文件自己配置 cache 的大小,可以考虑尽量多, 甚至 80%的内存都做分配,同时调整内存的轮询方法, 这个要根据实际的数据来调整。 当然, 一般一个 redis 就是单独一个服务, 可以多开几个 redis 服务并行处理, 这个也是一种方法。



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

技术逻辑:其实就是流量分配, 最开始金融行业用的 F5 方案, 到后面各种云端企业用的负载均衡, 到最后各种 K8s ,k3s , 不外乎就是规划流量。 做好流量和资源的匹配。 就像 k8s 就会说很牛掰的说, 不行的话, 就多配置几个应用, 多配置几个数据库。
Cola98
204 天前
第一种用消息队列,第二种做配套监控,使用 ttl 定期淘汰任务,做好扩容准备
Campanula
204 天前
1. 预分配、队列、悲观锁、乐观锁;
2. 加内存、扩容 redis 节点、排查内存数据;
3. 本质是资源分配和调度;
han1988
204 天前
1. 先引导到一个在线吃鸡游戏,每场赢得前 N 位可以获得兑换码兑换课程资格
han1988
204 天前
2. 加 Redis 集群节点
3. 加钱
publicWyt
204 天前
还是一句话,抛开业务谈实现都是耍流氓,应该具体问题具体分析的,就比如楼上说的 redis,启动就满了和缓存堆满了就是两码事
me1onsoda
204 天前
redis 满了不是很正常吗,redis 自己会淘汰一部分出去,就跟内存的换入换出一样。觉得太不可控频率太高了就加钱呗
monmon
204 天前
第一个问题从后端视角怎么处理楼上大佬都说的差不多了。
楼上也提到从现实来说,一个学校同时抢课不会有太高的并发量,这种学校的服务大部分就是个单机服务,可能 redis 没有,加个悲观锁基本就可以了。
但是面试官如果说并发量超级高,全地球人都要抢这门课,那么就要从整个系统上看这个问题,可以在前端就做一些规则过滤,不可能让所有的用户操作都请求到服务器,例如根据用户规模,用户点击时的时间戳 %n=0 才发请求到服务器,现实中的高并发场景我们确实是这么干的。
ospider
204 天前
@WashFreshFresh 你这哪里是写代码,写的都是人情世故啊,啊哈哈
Seulgi
204 天前
1 秒杀库存设计,你说 redis lua 没什么问题,所以直接跳过了。
2 线上 redis 内存满了,删 key 、扩容,然后分析内存满的原因,因为一般都设置了过期时间,不存在会打满的情况,从应用、数据、数据结构等方面去分析优化 redis 的使用。
3 缓存、异步、可扩容,再多说的话,就是性能优化、监控、并发控制等。
zanx817
204 天前
简单回答下:

1. 抢课本质就是秒杀。 在系统层面,用户从前端、网关、后端、缓存最后到数据库,要尽可能把用户挡在前面。例如前端限制操作频率,网关限流限制地域等,后端 app 判断用户情况是否合格,不合格的要求 30 分钟后再试,合格的从缓存扣减。 在热点的 xx 分钟内, 相关数据不同步到库,等热点过去了再统一写库(根据场景判断是否使用 MQ 等、是否可以阶段写库)。

2. 针对单节点,有内存淘汰策略。参考官网 key eviction( https://redis.io/docs/latest/develop/reference/eviction/) 达到最大内存会按规则淘汰( LRU 、LFU 、随机等)。 集群环境下应该扩容。

3. 高并发本质是资源的争用,需要解决数据同步的问题。如何展开看面试聊啥。。。
sulinehk
204 天前
@whahuzhihao 好书!
Ashe007
204 天前
尝试解答第三题(解决高并发问题的本质)
1-限流,从入口层控制流量
2-集群,从架构层提升系统负载
3-避免并发安全,并行改为串行(无论是单机锁还是分布式锁)
mintongcn
204 天前
我如先问问 gpt
inostarling
203 天前
3.你认为解决高并发问题的本质是什么?
个人认为是资源分配和数据同步。
cheng6563
203 天前
1.db 性能有限,本质是用更快的方案/中间件做缓冲区
2.要看是否是 Key 泄露,对于线上产品都是先扩容再说。
3.用更快/能水平扩容的中间件来缓存/缓冲数据库,用单线程处理多个 IO 任务(异步/协程)

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

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

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

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

© 2021 V2EX