点击上方 "编程技术圈"关注, 星标或置顶一起成长
文章图片
后台回复“大礼包”有惊喜礼包!
每日英文
Life is too short to worry about what others say or think about you. So have fun and give them something to talk about.
生活短暂,没时间去忧虑别人怎么说或怎么想你。所以开心过自己的,让别人说去吧!
每日掏心话
这人和那人都不缺真诚的时候,缺的是,谁先把真诚亮出来。出示真诚需要点胆子,真诚可不是你想掏就掏得出来的东西。
责编:乐乐 | 来自:dongshao.blog.csdn.net/article/details/107190925
编程技术圈(ID:study_tech)第 1171 次推文
往日回顾:程序员离职后躲老家山洞 2 年,敲出 45 万行代码...
正文
本文介绍MySQL与Redis缓存的同步的两种方案
- 通过MySQL自动同步刷新Redis,MySQL触发器+UDF函数实现
- 解析MySQL的binlog实现,将数据库中的数据同步到Redis
过程大致如下:
- 在MySQL中对要操作的数据设置触发器Trigger,监听操作
- 客户端(NodeServer)向MySQL中写入数据时,触发器会被触发,触发之后调用MySQL的UDF函数
- UDF函数可以把数据写入到Redis中,从而达到同步的效果
文章图片
方案分析:
- 这种方案适合于读多写少,并且不存并发写的场景
- 因为MySQL触发器本身就会造成效率的降低,如果一个表经常被操作,这种方案显示是不合适的
文章图片
下面是UDF的解析代码
文章图片
定义对应的触发器
文章图片
文章图片
文章图片
二、方案2(解析binlog) 在介绍方案2之前我们先来介绍一下MySQL复制的原理,如下图所示:
文章图片
- 主服务器操作数据,并将数据写入Bin log
- 从服务器调用I/O线程读取主服务器的Bin log,并且写入到自己的Relay log中,再调用SQL线程从Relay log中解析数据,从而同步到自己的数据库中
- 上面MySQL的整个复制流程可以总结为一句话,那就是:从服务器读取主服务器Bin log中的数据,从而同步到自己的数据库中
- 我们方案2也是如此,就是在概念上把主服务器改为MySQL,把从服务器改为Redis而已(如下图所示),当MySQL中有数据写入时,我们就解析MySQL的Bin log,然后将解析出来的数据写入到Redis中,从而达到同步的效果
文章图片
例如下面是一个云数据库实例分析:
搜索后端架构师公众号回复“架构整洁”,送你一份惊喜礼包。
- 云数据库与本地数据库是主从关系。云数据库作为主数据库主要提供写,本地数据库作为从数据库从主数据库中读取数据
- 本地数据库读取到数据之后,解析Bin log,然后将数据写入写入同步到Redis中,然后客户端从Redis读数据
文章图片
这个技术方案的难点就在于: 如何解析MySQL的Bin Log。但是这需要对binlog文件以及MySQL有非常深入的理解,同时由于binlog存在Statement/Row/Mixedlevel多种形式,分析binlog实现同步的工作量是非常大的
Canal开源技术 canal是阿里巴巴旗下的一款开源项目,纯Java开发。基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了MySQL(也支持mariaDB)
【数据库|MySQL与Redis缓存的同步方案】开源参考地址有:https://github.com/liukelin/canal_mysql_nosql_sync工作原理(模仿MySQL复制):
- canal模拟mysql slave的交互协议,伪装自己为mysql slave,向mysql master发送dump协议
- mysql master收到dump请求,开始推送binary log给slave(也就是canal)
- canal解析binary log对象(原始为byte流)
文章图片
架构: server代表一个canal运行实例,对应于一个jvm
instance对应于一个数据队列 (1个server对应1..n个instance)
instance模块:
- eventParser (数据源接入,模拟slave协议和master进行交互,协议解析)
- eventSink (Parser和Store链接器,进行数据过滤,加工,分发的工作)
- eventStore (数据存储)
- metaManager (增量订阅&消费信息管理器)
文章图片
大致的解析过程如下:
- parse解析MySQL的Bin log,然后将数据放入到sink中
- sink对数据进行过滤,加工,分发
- store从sink中读取解析好的数据存储起来
- 然后自己用设计代码将store中的数据同步写入Redis中就可以了
- 其中parse/sink是框架封装好的,我们做的是store的数据读取那一步
文章图片
更多关于Cancl可以百度搜索
下面是运行拓扑图
文章图片
MySQL表的同步,采用责任链模式,每张表对应一个Filter。例如zvsync中要用到的类设计如下:
文章图片
下面是具体化的zvsync中要用到的类,每当新增或者删除表时,直接进行增删就可以了
文章图片
三、附加 本文上面所介绍的都是从MySQL中同步到缓存中。但是在实际开发中可能有人会用下面的方案:
- 客户端有数据来了之后,先将其保存到Redis中,然后再同步到MySQL中
- 这种方案本身也是不安全/不可靠的,因此如果Redis存在短暂的宕机或失效,那么会丢失数据
文章图片
PS:欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,欢迎转发分享给更多人。
版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!欢迎加入后端架构师交流群,在后台回复“学习”即可。
文章图片
猜你还想看
阿里、腾讯、百度、华为、京东最新面试题汇集
记住看小电影前一定要检查网址是不是 HTTPS 的,不然…
优秀的 Java 项目代码都是如何分层的?
再见 Win10!下一代操作系统要来了!
BAT等大厂Java面试经验总结
文章图片
别找了,想获取 Java大厂面试题学习资料
扫下方二维码回复「手册」就好了
嘿,你在看吗?
文章图片
推荐阅读
- mysql|MySQL与Redis缓存的同步的方案
- 设计模式|观察者(observer)模式(一)
- 设计模式|观察者(observer)模式(二) —— 实现线程安全的监听器
- #|Mybatis学习 && 配置解析
- node|第四章(数据库和身份认证)
- Java_web|Java-web案例(mybatis、maven、jsp、tomcat、servlet...)
- 数据库|达梦数据库(第一章:MySQL数据库与达梦数据库的区别)
- Leetcode 55 - 跳跃游戏
- spring|springboot+mybais+mabatisplus(swagger)实现增删改查接口