欢迎投稿

今日深度:

某网站Redis与MySql同步方案分析,redismysql同步方案

某网站Redis与MySql同步方案分析,redismysql同步方案


后续文章: 通过Canal保证某网站的Redis与MySql的数据自动同步


1.编写目的

某网站项目引入了redis缓存技术,如何保证Redis与MySql的数据一致性是开发人员需要首要解决的问题。

本文主要包括以下内容:

  • Redis与MySql的数据一致性方案汇总与选取
  • Canal解析binlog方案简介
  • 其他Redis开发原则

2.方案汇总与选取

下面展示了几种常见的Redis与MySql数据一致性的方案:

序号 方案 方案简述 评价
1 手动同步一 对于读操作,先读redis,有则返回,无则读取MySql,并插入Redis。对于写操作,先写MySql,再读Redis。 直观简单,但是每次数据操作都需要手动维护缓存和数据库的一致性
2 手动同步二 对于读操作,先读redis,有则返回,无则读取MySql,并插入Redis。对于插入操作,先插入MySql,再写入cache。对于更新和删除操作,先删除cache,再操作MySql。 直观简单,但是每次数据操作都需要手动维护缓存和数据库的一致性。高并发情况下,会出现db与cache的不一致
3 MySql的UDF 通过数据库中的触发器(Trigger)调用UDF(user defined function,自定义的函数库),来触发对Redis的相应操作 自定义的函数库需要我们基于MySql的API进行开发(C++)(阿里早期做法)
4 Gearman+PHP+MySql UDF 通过借用已经比较成熟的MySql UDF,将MySql数据首先放入Gearman中,然后通过一个自己编写的PHP Gearman Worker,将数据同步到Redis 一般使用在PHP的开发中
5 Open-Replicator解析binlog Open Replicator是一个用Java编写的MySql binlog分析程序。Open Replicator 首先连接到MySql,然后接收和分析binlog,根据binlog的分析结果进行缓存操作。 主动读取binlog,实时性保证不够,整体解决方案不够成熟
6 Canal解析binlog Canal主要是基于数据库的日志解析,获取增量变更进行同步,由此衍生出了增量订阅&消费的业务,核心基本就是模拟MySql中Slave节点请求。 阿里开源项目,比较成熟的解决方案。

方案分析与选取:

  • 方案1和2都需要开发人员去手动维护Reids和MySql之间的同步。
  • 方案3需要编写UDF。
  • 方案4一般用在PHP开发中。
  • 方案5实时性较差。
  • 本项目采用方案6:通过Canal解析binlog。

3.Canal解析binlog简介

2.2.binlog

binlog,全称binary log,即MySql的二进制日志文件。

binlog用于记录mysql的数据更新或者潜在更新(比如DELETE语句执行删除而实际并没有符合条件的数据),在mysql主从复制中就是依靠的binlog。

2.3.MySql主从复制

下图是对MySql的主从复制(Master/Slave)的简单说明:

原理:

2.4.Canal原理

下图是对MySql的主从复制(Master/Slave)的简单说明:

原理:
1. Canal模拟MySql Slave的交互协议,伪装自己为MySql Slave,向MySql Master发送dump协议
2. MySql Master收到dump请求,开始推送binary log给Slave(也就是Canal)
3. Canal解析binary log对象(原始为byte流)

4.其他Redis开发原则

下面列出一些已经确定的Redis开发原则:

  • 所有的写操作(插入、更新、删除)都访问MySql。
  • 所有的读操作都访问cache。
  • 通过Canal解析MySql的binlog同步Redis来保持数据一致性。
  • 提供一个初始化全部缓存数据的方法:initCache。
  • Redis的KEY命名规范:项目名称-模块名称-对象名称-主键id。例如:baidu-news-user-0000000001。

5.注意事项

通过一段时间的使用,现将使用Canal解析binlog方案过程中的注意事项进行说明:

说明:

//判断每个字段
for (Column column : columns) {
    //如果字段类型为blob,则进行转码
    if ("blob".equals(column.getMysqlType())) {
        json.put(column.getName(), new String(column.getValue().getBytes("ISO-8859-1"),"gbk"));
    }else{//其他字段直接将字段名和值放到json串中
        json.put(column.getName(), column.getValue());
    }
}

具体转换成何种编码,请根据项目情况进行调节。

www.htsjk.Com true http://www.htsjk.com/redis/36262.html NewsArticle 某网站Redis与MySql同步方案分析,redismysql同步方案 后续文章: 通过Canal保证某网站的Redis与MySql的数据自动同步 1.编写目的 某网站项目引入了redis缓存技术,如何保证Redis与MySql的数据一...
相关文章
    暂无相关文章
评论暂时关闭