乐趣区

关于mysql:MySQL-与-Redis-缓存的同步方案

本文介绍 MySQL 与 Redis 缓存的同步的两种计划

  • 计划 1:通过 MySQL 主动同步刷新 Redis,MySQL 触发器 +UDF 函数实现
  • 计划 2:解析 MySQL 的 binlog 实现,将数据库中的数据同步到 Redis

计划 1(UDF)

  • 场景剖析:当咱们对 MySQL 数据库进行数据操作时,同时将相应的数据同步到 Redis 中,同步到 Redis 之后,查问的操作就从 Redis 中查找
  • 过程大抵如下:
  • 在 MySQL 中对要操作的数据设置触发器 Trigger,监听操作
  • 客户端(NodeServer)向 MySQL 中写入数据时,触发器会被触发,触发之后调用 MySQLUDF 函数
  • UDF 函数能够把数据写入到 Redis 中,从而达到同步的成果

  • 计划剖析:
  • 这种计划适宜于读多写少,并且不存并发写的场景
  • 因为 MySQL 触发器自身就会造成效率的升高,如果一个表常常被操作,这种计划显示是不适合的
演示案例

上面是 MySQL 的表

上面是 UDF 的解析代码

定义对应的触发器

计划 2(解析 binlog)

在介绍计划 2 之前咱们先来介绍一下 MySQL 复制的原理,如下图所示:

  • 主服务器操作数据,并将数据写入 Bin log
  • 从服务器调用 I / O 线程读取主服务器的 Bin log,并且写入到本人的 Relay log 中,再调用 SQL 线程从 Relay log 中解析数据,从而同步到本人的数据库中

计划 2 就是:

  • 下面 MySQL 的整个复制流程能够总结为一句话,那就是:从服务器读取主服务器 Bin log 中的数据,从而同步到本人的数据库中
  • 咱们计划 2 也是如此,就是在概念上把主服务器改为 MySQL,把从服务器改为 Redis 而已(如下图所示),当 MySQL 中有数据写入时,咱们就解析 MySQL 的 Bin log,而后将解析进去的数据写入到 Redis 中,从而达到同步的成果。(搜寻公众号民工哥技术之路,回复“1024”,送你一份技术宝典)

例如上面是一个云数据库实例剖析:

  • 云数据库与本地数据库是主从关系。云数据库作为主数据库次要提供写,本地数据库作为从数据库从主数据库中读取数据
  • 本地数据库读取到数据之后,解析 Bin log,而后将数据写入写入同步到 Redis 中,而后客户端从 Redis 读数据

这个技术计划的难点就在于:如何解析 MySQL 的 Bin Log。然而这须要对 binlog 文件以及 MySQL 有十分深刻的了解,同时因为 binlog 存在 Statement/Row/Mixedlevel 多种形式,剖析 binlog 实现同步的工作量是十分大的

Canal 开源技术

canal 是阿里巴巴旗下的一款开源我的项目,纯 Java 开发。基于数据库增量日志解析,提供增量数据订阅 & 生产,目前次要反对了 MySQL(也反对 mariaDB)

开源参考地址有:https://github.com/liukelin/c…\_mysql\_nosql\_sync

工作原理(模拟 MySQL 复制):
  • canal 模仿 mysql slave 的交互协定,假装本人为 mysql slave,向 mysql master 发送 dump 协定
  • mysql master 收到 dump 申请,开始推送 binary log 给 slave(也就是 canal)
  • canal 解析 binary log 对象(原始为 byte 流)

架构:

  • eventParser (数据源接入,模仿 slave 协定和 master 进行交互,协定解析)
  • eventSink (Parser 和 Store 链接器,进行数据过滤,加工,散发的工作)
  • eventStore (数据存储)
  • metaManager (增量订阅 & 生产信息管理器)
  • server 代表一个 canal 运行实例,对应于一个 jvm
  • instance 对应于一个数据队列(1 个 server 对应 1..n 个 instance)
  • instance 模块

大抵的解析过程如下:

  • parse 解析 MySQL 的 Bin log,而后将数据放入到 sink 中
  • sink 对数据进行过滤,加工,散发
  • store 从 sink 中读取解析好的数据存储起来
  • 而后本人用设计代码将 store 中的数据同步写入 Redis 中就能够了
  • 其中 parse/sink 是框架封装好的,咱们做的是 store 的数据读取那一步

更多对于 Cancl 能够百度搜寻

上面是运行拓扑图

MySQL 表的同步,采纳责任链模式,每张表对应一个 Filter。例如 zvsync 中要用到的类设计如下:

上面是具体化的 zvsync 中要用到的类,每当新增或者删除表时,间接进行增删就能够了

附加

本文下面所介绍的都是从 MySQL 中同步到缓存中。然而在理论开发中可能有人会用上面的计划:客户端有数据来了之后,先将其保留到 Redis 中,而后再同步到 MySQL 中 这种计划自身也是不平安 / 不牢靠的,因而如果 Redis 存在短暂的宕机或生效,那么会失落数据

作者 | 江南、董少
起源 | https://dongshao.blog.csdn.ne…

退出移动版