问题
缓存里面的数据如何和数据库保存一致?
解决方案
1.双写模式
即更新数据库的数据后,随即更新缓存里的数据
产生的问题:
如图所示,由于网络等原因第一个更新请求拉顿,而第二个更新请求执行在第一个请求之前就会出现数据不一致的问题
2.失效模式
即更新数据库的数据后删除缓存中的数据
产生的问题:
如图所示,第一个请求更新数据库里的数据,随后删除缓存。第二个请求也进行更改数据,但此时,第三个请求过来读取数据;但由于网络等原因第二个请求在进行更改数据库的数据时有卡顿,所有此时第三个请求读取的数据是第一个请求的数据(脏数据);且如果第三个请求的更新操作慢于第二个请求的删除缓存操作时,即第三个请求会把自己读取的数据(脏数据)更新到缓存中
总结:
无论是双写模式还是失效模式,都会有缓存的不一致的问题,即并发情况下同时更新就会有不一致的问题
解决方式:
- 如果是用户维度数据(比如订单数据,用户数据),这种并发几率小的数据,可以不考虑这方面的问题。可以使用过期时间这一方式,让数据每一段时间触发数据的读的主动更新即可
- 如果是菜单,商品介绍等基础数据,可以使用Canal(阿里开源中间件)订阅binlog的方式
- 通常情况下,使用缓存数据 + 过期时间 就可以解决大部分业务的需求
- 通过加锁保证并发读写,写写的时候按顺序排队(读写锁)
总而言之:
- 缓存中的数据不应该是实时性,一致性要求较高的数据
- 大部分业务使用缓存数据 + 过期时间,保证每天能拿到最新数据即可
- 实时性,一致性较高的数据应该存储在数据库