首页 > 数据库 >Redis7 数据双写一致性

Redis7 数据双写一致性

时间:2023-12-23 19:00:52浏览次数:39  
标签:缓存 Redis7 redis update 更新 mysql 一致性 数据库 双写

1、缓存双写一致性

如果redis中有数据,需要和数据库中的值相同
如果redis中无数据,数据库中的值要是最新值,且准备回写redis

缓存细分
1、只读缓存
2、读写缓存
2.1、同步直写策略
写数据库后也同步写redis缓存,缓存和数据库中的数据一致
对于读写缓存来说,要想保证缓存和数据库中的数据一致,就要采用同步直写策略

2.2、异步缓写策略
正常业务运行中,mysql数据变动了,但是可以在业务上容许出现一定时间后才作用于redis,必须仓库、物流系统
异常情况出现了,不得不将失败的动作重新修补,有可能需要借助kafka或者RabbitMQ等消息中间件,实现重试重写

2、更新策略

给缓存设置过期时间,定期清理缓存并回写,是保证最终一致性的解决方案。
我们可以对存入缓存的数据设置过期时间,所有的写操作以数据库为准,对缓存操作只是尽最大努力即可。
也就是说如果数据库写成功,缓存更新失败,那么只要到达过期时间,则后面的读请求自然会从数据库中读取新值然后回填缓存,达到一致性
切记,要以mysql的数据库写入库为准。

上述方案和后续落地案例是调研后的主流+成熟的做法,但是考虑到各个公司业务系统的差距,
不是100%绝对正确,不保证绝对适配全部情况,请同学们自行酌情选择打法,合适自己的最好。

2.1、更新数据库,更新缓存

异常问题:
1 先更新mysql的某商品的库存,当前商品的库存是100,更新为99个。
2 先更新mysql修改为99成功,然后更新redis。
3 此时假设异常出现,更新redis失败了,这导致mysql里面的库存是99而redis里面的还是100 。
4  上述发生,会让数据库里面和缓存redis里面数据不一致,读到redis脏数据

【先更新数据库,再更新缓存】,A、B两个线程发起调用
【正常逻辑】
1 A update mysql 100
2 A update redis 100
3 B update mysql 80
4 B update redis 80
=============================
【异常逻辑】多线程环境下,A、B两个线程有快有慢,有前有后有并行
1 A update mysql 100
3 B update mysql 80
4 B update redis 80
2 A update redis 100
 =============================
最终结果,mysql和redis数据不一致
mysql80,redis100

2.2、更新缓存,更新数据库

业务上一般把mysql作为底单数据库,保证最后解释

异常问题:
【先更新缓存,再更新数据库】,A、B两个线程发起调用
【正常逻辑】
1 A update redis 100
2 A update mysql 100
3 B update redis 80
4 B update mysql 80
====================================
【异常逻辑】多线程环境下,A、B两个线程有快有慢有并行
A update redis  100
B update redis  80
B update mysql 80
A update mysql 100
最终结果,mysql和redis数据不一致
----mysql100,redis80

2.3、删除缓存,更新数据库

(1)请求A进行写操作,删除redis缓存后,工作正在进行中,更新mysql......A还么有彻底更新完mysql,还没commit
(2)请求B开工查询,查询redis发现缓存不存在(被A从redis中删除了)
(3)请求B继续,去数据库查询得到了mysql中的旧值(A还没有更新完)
(4)请求B将旧值写回redis缓存
(5)请求A将新值写入mysql数据库 
上述情况就会导致不一致的情形出现。

Redis7 数据双写一致性_缓存

2.4、更新数据库,删除缓存

异常问题

Redis7 数据双写一致性_缓存_02

解决方案

Redis7 数据双写一致性_mysql_03

2.5、总结

优先使用先更新数据库,再删除缓存的方案(先更库→后删存)。理由如下:
1 先删除缓存值再更新数据库,有可能导致请求因缓存缺失而访问数据库,给数据库带来压力导致打满mysql。
2 如果业务应用中读取数据库和写缓存的时间不好估算,那么,延迟双删中的等待时间就不好设置。

多补充一句:如果使用先更新数据库,再删除缓存的方案
如果业务层要求必须读取一致性的数据,那么我们就需要在更新数据库时,先在Redis缓存客户端暂停并发读请求,
等数据库更新完、缓存值删除后,再读取数据,从而保证数据一致性,这是理论可以达到的效果
但实际,不推荐,因为真实生产环境中,分布式下很难做到实时一致性,一般都是最终一致性,请大家参考。

Redis7 数据双写一致性_缓存_04

3、数据双写一致性落到

Redis7 数据双写一致性_mysql_05

3.1、mysql主从复制工作原理

Redis7 数据双写一致性_mysql_06

MySQL的主从复制将经过如下步骤:
1、当 master 主服务器上的数据发生改变时,则将其改变写入二进制事件日志文件中;
2、salve 从服务器会在一定时间间隔内对 master 主服务器上的二进制日志进行探测,探测其是否发生过改变,
如果探测到 master 主服务器的二进制事件日志发生了改变,则开始一个 I/O Thread 请求 master 二进制事件日志;
3、同时 master 主服务器为每个 I/O Thread 启动一个dump  Thread,用于向其发送二进制事件日志;
4、slave 从服务器将接收到的二进制事件日志保存至自己本地的中继日志文件中;
5、salve 从服务器将启动 SQL Thread 从中继日志中读取二进制日志,在本地重放,使得其数据和主服务器保持一致;
6、最后 I/O Thread 和 SQL Thread 将进入睡眠状态,等待下一次被唤醒;

3,2、canal工作原理

Redis7 数据双写一致性_redis_07

3.3、mysql-canal

3.3.1、mysql开启binlog

log-bin=mysql-bin #开启 binlog
binlog-format=ROW #选择 ROW 模式
server_id=1    #配置MySQL replaction需要定义,不要和canal的 slaveId重复

ROW模式 除了记录sql语句之外,还会记录每个字段的变化情况,能够清楚的记录每行数据的变化历史,但会占用较多的空间。
STATEMENT模式只记录了sql语句,但是没有记录上下文信息,在进行数据恢复的时候可能会导致数据的丢失情况;
MIX模式比较灵活的记录,理论上说当遇到了表结构变更的时候,就会记录为statement模式。当遇到了数据更新或者删除情况下就会变为row模式;

新建授权用户
DROP USER IF EXISTS 'canal'@'%';
CREATE USER 'canal'@'%' IDENTIFIED BY 'canal';  
GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%' IDENTIFIED BY 'canal';  
FLUSH PRIVILEGES;
SELECT * FROM mysql.user;

3.3.2、canal服务端

1、下载地址
https://github.com/alibaba/canal/releases
2、解压
tar -xf canal.deployer-1.1.7.tar.gz -C /mycanal
3、配置
修改/mycanal/conf/example路径下的instance.properties

mysql主机地址配置

Redis7 数据双写一致性_mysql_08

账号和密码配置

Redis7 数据双写一致性_redis_09

启动
cd /mycanal/bin路径下执行
./startup.sh

查看server日志

Redis7 数据双写一致性_mysql_10

查看样例example的日志

Redis7 数据双写一致性_redis_11

标签:缓存,Redis7,redis,update,更新,mysql,一致性,数据库,双写
From: https://blog.51cto.com/u_13236892/8945869

相关文章

  • 微服务广播模式实践:维护内存数据的缓存一致性
    本文分享自华为云社区《微服务广播模式实践》,作者:张俭。微服务广播模式,指的是在微服务多实例部署的场景下,将消息广播到多个微服务实例的一种模式。广播模式,一般用来维护微服务的内存数据,根据数据类型的不同,有助于解决两类问题。通常广播模式会使用支持发布订阅的消息中间件实......
  • 接口超时,接口参数的特殊符号,接口的有序性,重试机制的结果一致性
    接口超时,接口参数的特殊符号,接口的有序性,重试机制的结果一致性1.http超时时间,将restTemplate的连接,超时时间设置更加长的时间。2.httpmvcGET请求,?a=1&b=2&c=#3,测试发现含#符号会在服务接口接收参数异常。需要将#特殊符合过滤,比如:可以替换为中文”井“3.请求的有序性保持3.1服......
  • Redis7 BigKey
    1、MoreKey1.1、大数据模拟往redis插入大量数据进行测试for((i=1;i<=100*10000;i++));doecho"setk$iv$i">>/tmp/redisTest.txt;done;通过redis提供的管道--pipe命令插入100W大批量数据cat/tmp/redisTest.txt|/opt/redis-7.0.0/src/redis-cli-h127.0.0.1-p6379-a......
  • Redis和Mysql如何保证数据一致性?
    1、redis作用:用于读数据库操作的缓存层,可以减少数据库的io,还能提升数据的io性能;无法保证数据的acid2、实现一致性方案:1、先更新数据库,在更新缓存2、先删除缓存再更新数据库3、最终一致性方案: (1)基于roketMQ可靠通信 (2)通过canal组件采集mysqlbinlog日志,同步redis......
  • Midjourney人物一致性探索
    原图a25yearsoldmaleinancientChineserobewithblackbigbackhairandsmalleyesandnormalnoseandsmallmouthandasmallface垫图https://s.mj.run/gBMdKDa7UJo,a25yearsoldmaleinancientChineserobewithblackbigbackhairandsmalle......
  • Redis7 复制
    1、主从复制1.1、常用命令1、主从复制从库操作replicaof主库IP主库端口或者slaveof主库IP主库端口2、取消主从slaveofnoone1.2、主从复制原理和工作流程1、slave启动,同步初请slave启动成功连接到master后会发送一个sync命令slave首次全新连接master,一次完全同步(全......
  • Redis7 发布订阅
    1、是什么是一种通信模式:发送者(PUBLISH)发送消息,订阅者(SUBSCRIBE)接收消息,可以实现进程间的消息传递Redis可以实现消息中间件MQ的功能,通过发布订阅实现消息的引导和分流2、能干啥Redis客户端可以订阅任意数量的频道,类似于微信关注多个公众号当有新消息通过PUBLISH命令发送给频......
  • Redis生产实战-热key、大key解决方案、数据库与缓存最终一致性解决方案
    生产环境中热key处理热key问题就是某一瞬间可能某条内容特别火爆,大量的请求去访问这个数据,那么这样的key就是热key,往往这样的key也是存储在了一个redis节点中,对该节点压力很大那么对于热key的处理就是通过热key探测系统对热key进行计数,一旦发现了热key,就将热key......
  • 解密 ArcGraph 分布式一致性:Raft 协议与分布式事务实现丨技术专栏
    导读:本文提出了一种将事务日志和Raft日志融合在一起的机制,从而实现了分布式事务和数据一致性的场景。01背景介绍分布式系统是伴随着互联网的高速发展而出现的。其出现为了应对单机系统无法解决的高并发、高可用性、容错性等问题。分布式系统将传统的系统扩容模式,从scaleup......
  • Zookeeper——分布式一致性协议及Leader选举原理
    一、引言随着业务的增长,单体架构发展为分布式架构,大大提升了业务的处理能力,但同时也带来了很多单体架构不存在的问题,如:各节点之间网络通信的异常以及因其引起的脑裂问题(网络分区)。引出“三态”。在单体架构中只会存在“成功”或“失败”两种结果,但是在分布式架构中由于网络异......