数据产生:
业务系统部署在多个机房,分主机房和备机房,多个机房都可用
其他系统通过队列下发数据,只能在主机房接收
主机房接收数据之后,修改数据库数据,并同步到备机房数据库,然后删除redis缓存(通过懒加载在下次查询数据时写缓存),删除动作也同步到备机房
数据查询:
通过分流将对业务系统的接口请求,根据业务key进行拆分,也就是说,对于一个固定的key,始终是到同一个机房,不会有这次主机房下次备机房的情况
对于key1被分配到了备机房,在请求数据时,如果有缓存,则返回缓存数据,如果没有缓存,则查询数据库,然后写缓存,再返回查询到的数据
问题:
其他系统在某次查询时发现数据不一致问题,也就是新数据已经下发,但是查到的还是旧数据
分析:
1. 跟踪链路发现进入的是备机房
2. 查询数据库,确认数据在请求发起时确实已经入了被机房数据库
3. 通过后台管理查询缓存,却没有查到缓存
4. 但是在请求数据时,却没有查数据库,直接返回了旧数据,说明缓存是存在的,且是旧数据
然后意识到PC后台管理访问的是主机房,难道主机房的redis没有数据,备机房有数据?
由于key1被分配到了备机房,所以查询始终发生在备机房,写入了备机房的redis,但是数据同步不会发生备机房同步到主机房,所以主机房没有缓存数据,解释了PC后台查不到缓存的现象
主机房在接收到队列下发的数据,保存数据库成功之后,删除redis缓存时,由于key1的查询不会发生在主机房,所以主机房redis中不存在这个缓存,所以删除操作失败,导致这个删除的动作没有同步给备机房,所以主机房没有缓存但是备机房有
解决:
方案一:所有数据查询都分配到主机房
方案二:缩短redis缓存时间,以减少不一致现象发生的机会,不过还是会发生
方案三:主备机房使用统一的redis入口,不过打破了原本架构
方案四:调整redis同步机制,确保主备机房缓存一致
首选方案一,发生这个问题也说明了在此种场景下不适合使用分流的方案,分流的方案自有其他场景适用