| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> redis应用 -> 正文阅读 |
|
[大数据]redis应用 |
redis和数据库双写一致性问题分析:一致性问题是分布式常见问题,还可以再分为最终一致性和强一致性。数据库和缓存双写,就必然会存在不一致的问题。答这个问题,先明白一个前提。就是如果对数据有强一致性要求,不能放缓存。我们所做的一切,只能保证最终一致性。另外,我们所做的方案其实从根本上来说,只能说降低不一致发生的概率,无法完全避免。因此,有强一致性要求的数据,不能放缓存。 回答:首先,采取正确更新策略,先更新数据库,再删缓存。其次,因为可能存在删除缓存失败的问题,提供一个补偿措施即可,例如利用设置缓存失效时间(一般再秒级)或者消息队列的重试机制。 分析: 将不一致分为三种情况:
1.读写策略1 读请求不要求强一致性的读请求,走redis,要求强一致性的直接从mysql读取。 读操作优先读取redis,不存在的话就去访问MySQL,并把读到的数据写回Redis中; 2 写请求数据首先都写到数据库,然后把缓存里对应的数据失效掉(删掉)。 为何是删缓存而不是更新缓存? ? 这么做引发的问题是,如果A,B两个线程同时做数据更新,A先更新了数据库,B后更新数据库,则此时数据库里逻辑上存的是B的数据。 但要考虑两种情况: 针对更新失败的解决方案: 方案二:“日志记录后手动操作”。更新失败会记入日志,手动操作【人工操作,不灵活】。 方案三:“key存入MQ重新消费set一次”。借用MQ中间件,将有问题的key放入MQ,重新消费进行更新缓存【借用第三方组件,耗费大】。 删缓存一定能保证双写一致性吗? 线程1和2为分别写数据,线程3为读数据。理论上缓存最后应该是线程2的数据,但实际有可能出现 出现的原因如下: 线程1执行完成后,此时缓存为空。这时线程2去更新数据库因为比较耗时还没有写完,另外一个线程3请求来查询数据,发现缓存里没有,就去数据库里查此时查到的为10,然后准备回写缓存前,此时线程2更新数据库完成了并删了缓存,线程3继续回写完缓存后,此时缓存的值为10。 解决方案1: 遇到这种情况,可以用队列的去解决这个问题,创建一个先进先出的阻塞队列如ArrayBlockingQueue,当有数据更新请求时,先把它丢到队列里去,当更新完后在从队列里去除,如果在更新的过程中,遇到以上场景,先去缓存里看下有没有数据,如果没有,可以先去队列里看是否有相同商品ID在做更新,如果有也把查询的请求发送到队列的末端里去,然后同步等待缓存更新完成。? 这里有一个优化点,如果发现队列里有一个查询请求了,那么就不要放新的查询操作进去了,用一个while(true)循环去查询缓存,循环个200MS左右,如果缓存里还没有则直接取数据库的旧数据(不要更新缓存),一般情况下是可以取到的。 当然这种排队的策略对性能是有一定的影响的。 解决方案2: 利用Redisson的读写锁机制,在操作缓存时,线程3上了读锁之后,线程2就需要等待线程3写缓存释放之后才能去抢锁并删缓存。 注意:此方案报保证抢锁的顺序性,不能让写锁线程2一直阻塞,则会一直读到老的数据。 删除缓存失败的补偿方案参考: 删除缓存失败的补偿方案参考:
第三种方案可以说是一个大杀器,任何不一致,都可以靠失效期解决,失效期越短,数据一致性越高。但是失效期越短,查数据库就会越频繁。因此失效期应该根据业务来定。 2.并发情况选型并发不高的情况: 读: 读redis->没有,读mysql->把mysql数据写回redis,有的话直接从redis中取; 写: 写mysql->成功,再写redis; 并发高的情况: 此种情况对一致性特别低。 读: 读redis->没有,读mysql->把mysql数据写回redis,有的话直接从redis中取; 写:异步化,先写入redis的缓存,就直接返回;定期或特定动作如放到先进先出的阻塞队列将数据保存到mysql,可以做到多次更新,一次保存; ?
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/18 6:30:39- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |