面试题答案
一键面试缓存的作用
- 减轻数据库压力:在高并发下单场景下,直接操作数据库扣减库存会对数据库造成巨大压力。缓存可以在内存中快速处理大量库存扣减请求,减少对数据库的直接访问。
- 提高响应速度:由于缓存位于内存中,读写速度远快于数据库,能够快速响应用户下单请求,提升用户体验。
消息队列的作用
- 削峰填谷:在促销等高峰时段,下单请求量可能会瞬间剧增。消息队列可以接收并暂存这些大量的库存扣减请求,然后按照系统能够处理的速率逐步处理,避免系统因瞬间高并发而崩溃。
- 保证数据一致性:当缓存中库存扣减成功后,通过消息队列异步通知数据库进行库存的最终更新,确保缓存与数据库中库存数据的一致性。即使在数据库更新过程中出现问题,消息队列可以保证消息不会丢失,可进行重试等操作。
数据交互流程
- 下单请求到达:用户发起下单请求,系统首先检查缓存中对应商品的库存。
- 缓存扣减库存:如果缓存中库存足够,直接在缓存中扣减库存,并将库存扣减消息发送到消息队列。同时,给用户返回下单成功的响应。
- 消息队列处理:消息队列按照顺序依次取出库存扣减消息,通知数据库进行库存更新操作。数据库更新成功后,反馈更新结果。
- 缓存与数据库一致性校验:定期(或在某些特定时机)对缓存和数据库中的库存数据进行一致性检查。如果发现不一致,以数据库中的数据为准,对缓存进行修正。
可能遇到的问题及解决方案
- 缓存击穿:
- 问题描述:在高并发场景下,某个热点商品的缓存过期瞬间,大量请求直接访问数据库,可能导致数据库压力过大甚至崩溃。
- 解决方案:可以使用互斥锁(如 Redis 的 SETNX 命令)。当缓存过期时,只有一个请求能够获取到锁,去查询数据库并更新缓存,其他请求等待。待缓存更新完成后,释放锁,其他请求可以从缓存中获取数据。
- 缓存雪崩:
- 问题描述:大量缓存同时过期,导致大量请求直接访问数据库,引发数据库压力剧增。
- 解决方案:为不同的缓存设置不同的过期时间,避免集中过期。同时,可以使用二级缓存,一级缓存失效后,从二级缓存获取数据,减轻数据库压力。
- 消息队列消息丢失:
- 问题描述:在消息队列处理过程中,可能因为网络问题、服务器故障等原因导致消息丢失,从而数据库未能及时更新库存,造成缓存与数据库数据不一致。
- 解决方案:采用消息确认机制,消息队列发送消息后等待接收方的确认回复。如果未收到确认,进行重试。同时,可以开启消息持久化,将消息存储在磁盘上,即使消息队列服务器重启,消息也不会丢失。
- 缓存与数据库数据不一致:
- 问题描述:由于网络延迟、系统故障等原因,可能导致缓存扣减成功但数据库更新失败,或者数据库更新成功但缓存未及时同步,造成数据不一致。
- 解决方案:一方面,加强消息队列的可靠性,确保库存更新消息能成功发送到数据库并处理。另一方面,定期进行缓存与数据库的数据比对和修复,发现不一致及时调整。还可以使用分布式事务框架(如 Seata 等)来保证数据的一致性。