面试题答案
一键面试1. 版本标识生成
- 全局版本号:使用一个全局的版本号服务,例如可以基于数据库自增字段,或者使用分布式ID生成器(如雪花算法)生成一个唯一的递增数字作为全局版本号。每当商品数据有任何修改时,全局版本号就递增。
- 商品维度版本号:除了全局版本号,每个商品还维护一个自身的版本号。在商品表中添加一个版本字段,每次商品数据更新时,该字段加1。这样可以更细粒度地控制每个商品的缓存一致性。
2. 版本更新
- 全局版本更新:当任何业务模块(商品展示、订单处理、库存管理等)修改商品数据时,首先调用全局版本号服务获取新的全局版本号。这个过程可以通过数据库事务确保原子性,即在商品数据修改成功后,同时更新全局版本号。
- 商品版本更新:在修改商品数据的同时,将商品表中的版本字段值加1。这可以通过数据库的
UPDATE
语句实现,例如UPDATE products SET data = new_data, version = version + 1 WHERE id = product_id
。
3. 根据版本号更新或淘汰缓存数据
- 缓存写入:在将商品数据写入缓存时,同时将全局版本号和商品版本号一同写入。例如,使用Redis缓存时,可以将商品数据存储在一个Hash结构中,结构内除了商品具体信息,还包含
global_version
和product_version
字段。 - 缓存读取:每个业务模块在读取缓存数据时,同时获取缓存中的版本号。然后与数据库中的版本号(全局版本号和商品版本号)进行比较。
- 全局版本号比较:如果缓存中的全局版本号小于数据库中的全局版本号,说明有其他地方对商品数据进行了修改,缓存数据可能不一致,此时需要淘汰该商品的缓存数据,并从数据库重新读取数据,更新缓存并写入最新版本号。
- 商品版本号比较:即使全局版本号一致,也对比商品版本号。若缓存中的商品版本号小于数据库中的商品版本号,说明该商品自身数据有更新,同样淘汰缓存数据,从数据库重新读取并更新缓存及版本号。
- 缓存淘汰:在业务模块修改商品数据后,不仅要更新数据库和版本号,还需要主动淘汰相关的缓存数据。可以通过缓存的发布 - 订阅机制,当商品数据修改时,发布一个消息,各个业务模块监听这个消息,收到消息后检查自身缓存中该商品的版本号,按照上述规则决定是否淘汰缓存数据。