MySql与Redis
1.Redis和MySQL如何保持数据一致性
数据同步可以有延时
一、延时双删策略
在写库前后都进行redis.del(key)操作,并且设定合理的超时时间。
public void write( String key, Object data ){
redis.delKey( key ); //删除redis缓存
db.updateData( data ); //修改数据库
Thread.sleep( 500 ); //睡眠一会儿
redis.delKey( key );//再次删除redis缓存 ,防止-》[多线程在修改数据库完前,再次获取数据更新redis]
}
//问题:这个500毫秒怎么确定的,具体该休眠多久时间呢?
//1、需要评估自己的项目的读数据业务逻辑的耗时。
//2、这么做的目的,就是确保读请求结束,写请求可以删除读请求造成的缓存脏数据。
//3、当然这种策略还要考虑redis和数据库主从同步的耗时。
//4、最后的的写数据的休眠时间:则在读数据业务逻辑的耗时基础上,加几百ms即可。
- 因为第一次删除的是还没更新前的数据,第二次删除则是因为读取的并发性导致的缓存重新写入数据出现的垃圾数据。
二、中间件通知(MQ、Canal)
- MQ中间件:数据更新后,就通知缓存删除。
- Canal中间件:Canal伪装成MySQL的从节点,通过读取binlog数据来更新缓存,神奇又方便,而且不需要改业务代码!
数据高度一致性:加锁
想要达到强一致性,我们可以借助Redisson提供的读写锁!!!
- 共享锁(读锁readLock):一旦加上这个锁,其他线程就可以共享读操作,不会互相干扰,真是好帮手!
- 排他锁(独占锁writeLock):这个锁更霸道,一旦加上,其他线程就别想读写操作了,得乖乖等着。