面试题答案
一键面试实现思路
- 缓存更新策略:
- 读写时更新:当对商品数据进行写操作(如更新商品价格、库存等)时,同时更新数据库和缓存。先更新数据库,成功后再更新缓存。这样能保证数据一致性,但在高并发场景下,可能会有短暂的不一致情况,因为更新数据库和缓存不是原子操作。例如,在更新数据库后,还没来得及更新缓存时,其他读请求过来,可能读到旧的缓存数据。
- 读写分离更新:在写操作时,先更新数据库,然后设置一个标志(如在Redis中设置一个特定的键值对表示数据已更新),读操作时先检查这个标志,如果标志表明数据已更新,则更新缓存并清除标志。这种方式可以减少高并发下不一致的时间窗口。
- 删除缓存而非更新:在写操作更新数据库成功后,删除Redis中的缓存数据,而不是直接更新缓存。下次读请求过来时,发现缓存不存在,就从数据库读取并重新写入缓存。这样能避免更新缓存时可能出现的复杂逻辑,但会增加数据库的读压力,尤其是在缓存击穿的情况下(大量请求同时发现缓存不存在,都去读数据库)。
- 异步处理:
- 使用消息队列(如Kafka、RabbitMQ等)。当商品数据变化时,先将更新操作发送到消息队列,数据库更新成功后,消息队列中的任务再去处理缓存的更新或删除操作。这样可以将缓存操作异步化,减少对主业务流程的性能影响。例如,在电商系统处理订单过程中,订单完成后需要更新商品库存,将库存更新操作放入消息队列,主业务流程继续处理其他订单,消息队列异步处理库存缓存更新。
- 缓存过期策略:
- 设置合理的缓存过期时间。对于不经常变化的商品数据,可以设置较长的过期时间;对于变化频繁的商品数据,设置较短的过期时间。当缓存过期后,读请求会从数据库读取最新数据并更新缓存,从而保证数据一致性。例如,一些热门且价格变动频繁的商品,设置10分钟的缓存过期时间,既能减少数据库读压力,又能在一定时间内保证数据的相对一致性。
可能用到的Redis命令
- SET:用于更新缓存中的商品数据。例如,当采用读写时更新策略时,在更新数据库成功后,使用
SET key value [EX seconds] [PX milliseconds]
命令将新的商品数据写入Redis缓存,EX
选项用于设置过期时间(单位为秒),PX
选项用于设置过期时间(单位为毫秒)。如SET product:1 { "name": "商品1", "price": 100 } EX 3600
,表示将商品1的信息写入缓存,有效期为1小时。 - DEL:当采用删除缓存策略时,使用
DEL key
命令删除Redis中的商品缓存数据。例如,在更新商品数据库成功后,执行DEL product:1
,删除商品1的缓存数据。 - SETNX:在读写分离更新策略中,用于设置数据更新标志。
SETNX key value
命令只有在键不存在时,才会设置键的值。例如,在更新数据库成功后,执行SETNX product:1:update_flag true
,表示设置商品1的数据更新标志。读操作时通过检查这个标志来决定是否更新缓存。