xie233 / redis_some

0 stars 0 forks source link

数据一致性 #2

Open xie233 opened 5 years ago

xie233 commented 5 years ago

数据库与缓存一致性的内容,一般设计为:读数据先查询缓存,没有再查询数据库,写入缓存;写数据,先写数据库再失效缓存。若写数据库成功后再写缓存,容易有事务和并发上的问题。一个事务包含多个操作,其中有写数据库操作失败,事务回滚,缓存却没法回滚,有脏数据产生。并发性问题:两个更新操作并发,若是以A更新数据库,B更新数据库,B更新缓存,A更新缓存这样的顺序发生这次并发,便有脏数据产生。对于先写数据库再删除缓存的并发问题发生概率很小,可设置缓存过期时间,同时删除缓存失败,可采用中间件canal(参考)订阅binlog日志的功能,独立于业务代码重试删除缓存的操作。

缓存淘汰策略,由于缓存空间有限,需要以一定的策略定时淘汰数据保证热点数据的缓存以及提供缓存的命中率。主要了解LRU(最近最少被使用)和LFU(最近不经常被使用)两种方法。LRU根据时间,保留最近被使用的数据,LFU根据次数,保留最近使用次数多的数据。

xie233 commented 5 years ago

Redis 中的 HyperLogLog 数据结构,用于解决大数据量不精确的去重问题,虽然不精确但能达到一致的数量级,比如某个网站的用户浏览量统计,同一用户多次浏览只计数一次,HyperLogLog 不像集合需要保存数据,却能够进行去重的计数,挺节省内存和实用,内部是基于概率统计的原理,还是有点复杂。

xie233 commented 5 years ago

分布式锁,在分布式场景下,java自身的并发包没法发挥作用,一般有几种实现:基于数据库建锁表,基于缓存,基于zookeeper做分布式锁。以redis分布式锁为例,通过set的扩展参数nx和ex(原子操作)实现锁的互斥和过期时间,通过编程可实现锁的阻塞,删除锁时要比较是否是自己的锁,然后再删除(非原子操作),通过lua脚本保证删除锁的原子性。一般是要保证该锁具有排他性,不死锁,可阻塞,性能以及可用性。