缓存:缓存一致性解决
用分布式锁的时候,锁的名字要注意,锁的粒度越小,速度越快,每个服务每个功能用到分布式锁的时候,都用不同的分布式锁的名字。
对之前的三级分类进行redisson分布式锁改造:
public Map> getCatalogJsonFromDbWithRedisLock() { RLock lock = redissonClient.getLock("CatalogJson-lock"); lock.lock(10,TimeUnit.SECONDS); Map > dataFromDb; try { dataFromDb = getDataFromDb(); } finally { lock.unlock(); } return dataFromDb; }
==============================================
如果数据库中的数据修改了呢?缓存数据一致性?怎么解决?
这样双写模式就会出现脏数据的情况。怎么解决?
1.加锁。等一个线程过来,拿到锁,然后把写数据库和写缓存全做完。在释放锁。
2.如果业务允许暂时性的数据不一致,那么就这样子,不管他。redis设置数据的时候,设置过期时间,等缓存数据过期了然后再重新查。
上图最下面的请求,读到的可能就是脏数据 db-1
这个地方就是读写的问题, 可以加读写锁。
================================================
上面的解决方式都是加锁。系统就会笨重一些,速度自然就慢了许多。
如果数据经常修改?那还真的要放入缓存吗?所以经常修改的数据,实时性要求高的数据,还是直接读数据库。
======================================================================
canal能就解决缓存一致的问题,但是就是加了一个中间件。性能上可能有影响。
当然 canal 最初的设计目的是大数据的数据异构问题:比如每个人的淘宝首页推荐的商品,用canal就能根据访问记录和商品表经过分析得到新的用户推荐表然后返回给用户。
对于一个数据
读:从缓存读,有就直接返回,没有就读数据库然后写入缓存,然后返回。用到redisson分布式锁。
写:双写模式-----写完数据库再写缓存。加redisson分布式锁,完成所有操作之后再释放锁
失效模式------写完数据库后,让缓存的数据失效,直接清掉缓存。也可以加锁保证顺序一致性。