【HBZ分享】Redis如何与Mysql做数据同步,有几种方法?

2023-11-14

1. Mysql查完数据,再同步写入到Redis中

  1. 缺点1:会对接口造成延迟,因为同步写入redis本身就有延迟,并且还要做重试,如果redis写入失败,还需要重试,那就更费时间了。
  2. 缺点2:不解耦,如果redis崩了,那直接卡线程了
  3. 缺点3:如果人为该数据库,那就没法同步了, 除非再人为删除对应的Redis,但删除Redis这个过程也有个时间差

2. Mysql查完数据,通过发送MQ,在消费者线程去同步Redis

  1. 缺点1:多了层MQ,也就是会有很大的概率导致同步延迟问题.
  2. 缺点2:要对MQ的可用性做预防
  3. 缺点3:如果人为该数据库,那就没法同步了
  4. 优点1:可以大幅减少接口的延迟返回的问题
  5. 优点2:MQ本身有重试机制,无需人工去写重试代码
  6. 优点3:解耦,把查询Mysql和同步Redis完全分离,互不干扰

3. 订阅Mysql的Binlog文件(可借助Canal来进行)

  1. CanalServer会伪装成MysqlServer从库,去订阅MysqlServer主库的Binlog文件
  2. Canal启动的时候会配置对应的消息MQ(RabbitMQ, RocketMQ, Kafka), 监听到Binlog文件有变化是,会把变化的sql语句转换成json格式,并作为消息内容发送到MQ中
  3. 项目中只要监听对应MQ,就能拿到Binlog改动的内容,Json数据中有明确的操作类型(CURD), 以及对应的数据。把对应数据同步到redis即可
  4. 缺点1:canal订阅Binlog的整个操作过程是单线程的,所以面临超高并发的情况下,性能可能不太出色。当然可以部署多个Canal 与 多个消费者,但是要注意消息重复消费问题,做好幂等性校验
  5. 优点1:即使人为改数据库,也会监听到,并且也会同步
  6. 优点2:异步同步,不会对接口返回有格外延迟

4. 延迟双删

  1. 在执行修改sql之前,先将redis的数据删除
  2. 执行更新sql
  3. 延迟一段时间
  4. 再次删除redis的数据
// 延迟双删伪代码
deleteRedisCache(key);   // 删除redis缓存
updateMysqlSql(obj);        // 更新mysql
Thread.sleep(100);           // 延迟一段时间
deleteRedisCache(key);   // 再次删除该key的缓存

缺点:这个延迟时间不好把控,到底延迟多久,这个很难去评估

扩展: 如果不使用延迟双删,仅仅是delete缓存,然后改mysql数据。只有这两步会出现什么问题呢?
5. 单个请求,单线程没问题,高并发多线程下会出问题
6. 如果Thread1线程要更新数据,此时Thread1线程把redis清理了
7. 此时Thread2线程来了,但Thread1还没有更新mysql完毕
8. Thread2查询redis肯定是null,此时Thread2就要查mysql了,然后再把查到的数据写到缓存
9. 由于Thread1还没来得及修改mysql数据,所以此时Thread2查出来的数据是【旧数据】,Thread2把旧数据又写入Redis 了
10. 此时Thread3线程来了,查询Redis发现有数据,则直接拿缓存数据了,此时【Thread3查出来的是旧数据】,直接带着旧数据返回了,这就是问题所在
11. 而延迟双删的第二次删除作用就是防止Thread2把旧数据又写入了,有了延迟双删,Thread3查询Redis的时候还是null,就会从mysql 去拿最新数据了
12. 所以正常的这个延迟时间,应该是Thread2查缓存到拿mysql数据,到再保存到redis这整个时间,作为Thread1的延迟时间,但是这个Thread2这个过程的时间会受到很多因素影响,因此很难断定究竟会是多久

5. 延迟双写

// 延迟双写伪代码
updateMysqlSql(obj);        // 更新mysql
addRedis(key);   // 再次删除该key的缓存

上述代码缺陷;

  1. 高并发下,两条线程同时执行上面代码,并对mysql 修改,且修改内容不通,可能会导致Redis与Mysql数据不一致
  2. T1线程执行完updateMysqlSql,释放了行锁,此时T2线程再执行updateMysqlSql 与 addRedis, 最后T1执行addRedis,这种情况会导致数据库改成了T2线程的数据,但Redis却是T1线程的数据
优化
// 完美延迟双写伪代码
开启事务
updateMysqlSql(obj);        // 更新mysql
addRedis(key);   // 再次删除该key的缓存
提交事务

上述代码改正:

  1. 把两句代码放到一个事务里面,只有T1执行完Mysql 与 Redis的时候,T2才能开始执行,就可以保证数据一致性。推荐使用分布式锁
  2. 双写缺点:Mysql 与 Redis是单线程的。性能方面不行,因此不推荐使用

总结: 推荐使用Canal的方式,进行异步同步。其次是MQ方式

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【HBZ分享】Redis如何与Mysql做数据同步,有几种方法? 的相关文章

随机推荐

  • hdu 2586 How far away ?

    Problem acm hdu edu cn showproblem php pid 2586 Meaning 给一棵 n 个点的树 和 n 1 条边的边权 多次询问树上两点的距离 Analysis 以任意顶点为根 DFS 预处理出所有结点
  • 【数据库MongoDB的学习】

    一 数据库和文件的主要区别 1 数据库有数据库表 行和列的概念 让我们存储操作数据更方便 2 数据库提供了非常方便的接口 可以让 nodejs php java net 很方便的实现增加修改删 除功能 二 关系型和非关系型数据库的介绍 关系
  • 深度学习数字仪表盘识别_一种改进的卷积神经网络的数显仪表识别方法

    数显仪表 就是一种显示数字的仪器 便于人们了解相关信息 目前 数显仪表被广泛的应用于航天 农业 工业等各个行业中 但出于工作条件和成本控制等原因 仍有很多的仪表无法直接获得读数 大多由人工读取 但是人工无法长时间且实时记录 还有些地方工人不
  • Deepin操作系统丨一台10年前的家用联想台式机重装国产Linux系统,制作成生信服务器

    本篇笔记是利用个人电脑搭建Linux系统 deepin 20 8 的教程 包括系统下载 映像刻录 启动盘制作 电脑BIOS设置 安装系统 故障解决 驱动更新 软件下载 conda配置 R语言和Rstudio server配置 远程SSH配置
  • 【深度学习】入门的25个概念

    神经网络基础 1 神经元 Neuron 就像形成我们大脑基本元素的神经元一样 神经元形成神经网络的基本结构 想象一下 当我们得到新信息时我们该怎么做 当我们获取信息时 我们一般会处理它 然后生成一个输出 类似地 在神经网络的情况下 神经元接
  • R ggplot2坐标轴设置相关函数

    1 设置坐标轴标签 xlab ylab labs x NULL y NULL 2 设置坐标轴刻度范围 xlim ylim 3 添加标题 ggtitle 4 theme 控制字体 坐标轴刻度 背景以及背景上的线条 4 1 在theme 内部有
  • 出现—passwd:Authentication token manipulation error—错误的解决办法

    在服务器安装过程中 经常遇到软件安装失败 有一部分原因是在linux系统禁止添加新的用户和修改原有用户 在网上找了一篇解决此问题的文章 特转到此处作为参考 文章 http blog sina com cn s blog 70c9c4b401
  • AI数字人:基于VITS-fast-fine-tuning构建多speaker语音训练

    1 VITS模型介绍 VITS Variational Inference with adversarial learning for end to end Text to Speech 是一种语音合成方法 它使用预先训练好的语音编码器 v
  • import cv2 ImportError: /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so: undefined symbol: P

    usr bin python3 5 home utryjc PycharmProjects qtWayPionts ui main py Traceback most recent call last File home utryjc Py
  • 【PTA】斐波那契数列第n项

    求斐波那契数列的第n项 f n f n 1 f n 2 其中f1 f2 1 import java util public class Main public static void main String args Scanner sca
  • 加密so文件中指定的函数

    加密so文件中指定的函数 作者 0n1y3nd丶 分类 逆向学习 发布时间 2014 09 04 22 24 61条评论 前言 上一篇文章中详细分析了对so文件中自定义section的加密 这一篇来分析下对so文件中自定义函数的加密 原文地
  • 拉格朗日乘子法和KKT条件

    拉格朗日乘子法 Lagrange Multiplier 和KKT Karush Kuhn Tucker 条件是求解约束优化问题的重要方法 在有等式约束时使用拉格朗日乘子法 在有不等约束时使用KKT条件 前提是 只有当目标函数为凸函数时 使用
  • 【吴恩达-AIGC/ChatGPT提示工程课程】第六章 - 文本转换 Transforming

    吴恩达 AIGC ChatGPT提示工程课程 第六章 文本转换 Transforming 1 引言 LLM非常擅长将输入转换成不同的格式 例如多语种文本翻译 拼写及语法纠正 语气调整 格式转换等 本章节将介绍如何使用编程的方式 调用API接
  • C语言实现求解斐波那契数列的四种方法及优化处理(递归,迭代,特殊性质公式,矩阵快速幂)

    众所周知 斐波那契数列是非常经典的一个数列 它的数学公式如下 为了便于观察 我们列出它的几项 0 1 1 2 3 5 8 13 21 下面我们将介绍四种方法来用C语言计算机代码实现对斐波那契数列的求解 分别是 递归法 迭代法 矩阵求解法以及
  • 进厂拧了4年螺丝,零基础自学python月入过万,一切都来之不易

    前言 种子放在水泥板上就会被晒死 放在水里就会被淹死 但是放在肥沃的土壤里 就会生根发芽 选择可以决定命运 环境可以造就人生 今天给大家分享一位从工厂到程序员小哥的逆袭之路 就是这样一个在朋友眼里的满是羡慕的高薪工作 或许只有只有我自己 才
  • 在 Mac 上升级 pip

    遇到的问题 终端安装包时 会有以下提示 pip install upgrade pip WARNING You are using pip version 20 2 3 however version 21 0 1 is available
  • C++基础知识(十四)--- vector容器

    目录 1 数据结构 线性连续空间 2 迭代器 随机迭代器 三 vector容器动态增长原理 四 vector 常用API 1 vector 构造函数 2 vector 赋值操作 3 vector 大小操作 swap 的使用 缩小容量 4 v
  • 如何创建指向目录的链接

    本文翻译自 How to create a link to a directory closed How to create a link xxx to home jake doc test 2000 something 如何创建到 hom
  • 史上最全

    点击下方卡片 关注 自动驾驶之心 公众号 ADAS巨卷干货 即可获取 点击进入 自动驾驶之心技术交流群 后台回复 BEV综述 获取论文 后台回复 ECCV2022 获取ECCV2022所有自动驾驶方向论文 1摘要 以视觉为中心的俯视图 BE
  • 【HBZ分享】Redis如何与Mysql做数据同步,有几种方法?

    1 Mysql查完数据 再同步写入到Redis中 缺点1 会对接口造成延迟 因为同步写入redis本身就有延迟 并且还要做重试 如果redis写入失败 还需要重试 那就更费时间了 缺点2 不解耦 如果redis崩了 那直接卡线程了 缺点3