共计 865 个字符,预计需要花费 3 分钟才能阅读完成。
问题场景
- 促销零碎中,针对某个商品已配置了多个促销流动,且这些流动曾经处于进行中
- 此时新建了一个促销流动,状态为未开始
- 算价查问促销流动时,仅获取到了将来开始的流动,没有获取到已开始的流动,导致商品价格没有优惠
问题背景
- 促销零碎为了晋升算价性能,以商品 sku 为 key,促销流动汇合为 value,寄存于 redis 与 guava 中
- guava 的过期工夫为 48 小时,若该 sku 在 48 小时内没有产生查问,则该本地缓存将过期
- 查问策略为优先查问 guava,guava 中存在数据则间接返回,不存在则查问 redis,再将数据存入 guava
问题剖析
- 当查问该 sku 的促销流动时,零碎获取处于进行中的流动,并存放在 guava 中
- 48 小时后,因为没有算价申请,该 sku 对应的本地缓存过期
- 此时对该 sku 新建促销流动,B 端触发保留策略,将新建的流动保留至 redis 与 guava 中,但此处保留至 guava 实际上是増量保留,并不是通过 sku 进行全量流动获取,导致 guava 中仅存在新增的流动
- 此时算价查问该 sku 的促销流动,仅获取了未失效的流动,导致价格没有优惠
问题解决
调整 guava 的写入策略,在新建促销流动时,拉取该 sku 对应的全量流动,并放入 guava 中
问题思考
本地缓存波及到临界问题时,须要思考缓存写入与读取的计划是否正当,或者说须要思考缓存一致性问题,如果肯定要应用 guava,则在 DB 数据写入后全量从新获取受影响的数据,而不能采纳増量的模式
- 例如,数据写入 DB 前,删除 redis 中的数据,写入 DB 后加锁从 DB 获取全量数据存入 redis(防止高并发打崩 DB),而后告诉所有实例删除 guava 缓存,则在查问时,所有申请会从 redis 从新读取数据,当然具体数据删除写入逻辑还需联合具体场景探讨,此处阐明的重点在于受影响的数据须要全量更新
在上述案例中,算价查问业务理论应该了解为强统一场景,而 guava 难以解决一致性问题,在后续优化中应该思考去掉本地缓存,对立从 redis 中获取数据,且采纳读写锁概念,写数据时不能读取,否则在极其场景下,对于用户感知同一时刻的算价后果可能不同
正文完