首先能放在缓存中的数据,应该是即时性和数据一致性要求不高或者访问量大但是更新频率不高的数据。所以一般只需要保证redis和数据库数据的最终一致性即可,此时只需要在数据存入缓存的时候加上失效时间,这样到一定时间之后,自然会重新查数据库存入缓存,此时两边数据就一致了。

用例:比如页面上的一个数据总条数的统计总共有10w条,存在缓存中,这时表中又新增了20条,页面上的总条数没有立即增加,过一小时甚至一天才变成10万零20条也无伤大雅。

如果是及时性要求比较高的数据,那么可以在更新数据的时候重新放入缓存,或者在数据更新时直接删除缓存,那么在下次查询时再重新写入缓存就可以了。这里为了保证更新数据和放入缓存的原子性,可以加上读写锁,保证用户只读数据时不受影响,又能保证在写数据的时候阻塞读的进程。

当然如果是更新频繁的数据,一直会锁住而影响到了读的情况,这种数据是不适合存放在缓存中的。

读写锁:

读写锁是两个锁,一个读锁,一个写锁,读锁与读锁不互斥、读锁与写锁互斥、写锁与写锁互斥。

所以在读数据时加上读锁,写数据时加上写锁,就能实现最高效率的同步操作。

一个线程取得读锁的条件是,没有写锁,一个线程取得写锁的条件是没有读锁也没有写锁。

顺带讲一下乐观锁和悲观锁

乐观锁是所有进程都能执行更新,但是最终只有一个可以更新成功,可以根据更新结果的状态判断成功与否。乐观锁的实现只要加一个版本号就可以了,每次更新时获取到当前版本号,并且更新当前版本号的数据,如果在更新时有其他线程更新了这条数据,那么当前线程再去更新取到的版本号的数据就会失败。

悲观锁是只能有一个执行,只有执行完成之后其他线程才能进入。sychronized就是悲观锁。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐