文章目录
- 前言
- 一、数据异构的常用方法
- 1. 完整克隆
- 2. MQ方式
- 3. binlog方式
- 二、MQ与Binlog方案实现
- MQ方式
- binlog方式
- 注意点
- 三、总结
前言
何谓数据异构:把数据按需(数据结构、存取方式、存取形式)异地构建存储。比如我们将DB
里面的数据持久化到Redis
或者ES
里面去,就是一种数据异构的方式。
常见应用场景
分库分表中有一个最为常见的场景,为了提升数据库的查询能力,我们都会对数据库做分库分表操作。比如订单库,开始的时候我们是按照订单ID
作为分片键去分库分表,后来的业务需求想按照商家维度去查询,比如想查询某一个商家下的所有订单,就非常麻烦。
这个时候通过数据异构就能很好的解决此问题,如下图:
异构维度
数据异构总结起来大概有以下几种场景
- 数据库镜像(DB→DB)
- 数据库实时备份
- 多级索引(DB→ClickHouse)
- search build(比如分库分表后的多维度数据查询)(DB→ES)
- 业务cache刷新(DB→Redis)
- 价格、库存变化等重要业务消息
数据异构方向
异构的几种方向
在日常业务开发中大致可以分为以上几种数据去向,DB-DB
这种方式,一般常见于分库分表后,聚合查询的时候,比如我们按照订单ID
去分库分表,那么这个时候我们要按照用户ID
去查询,查询这个用户下面的订单就非常不方便了(因为分库分表后的查询where
条件必须带分片键),当然可以使用统一加到内存中去,但这样不太好。
所以我们就可以用数据库异构的方式,重新按照用户ID
的维度来分一个表,像在上面常见应用场景中介绍的那样。把数据异构到redis、elasticserach、slor
中去要解决的问题跟按照多维度来查询的需求差不多。这些存储天生都有聚合的功能。当然同时也可以提高查询性能,应对大访问量,比如redis
这种抗量银弹。
一、数据异构的常用方法
1. 完整克隆
这个很简单就是将数据库A
,全部拷贝一份到数据库B
,这样的使用场景是离线统计跑任务脚本的时候可以,如MySQL→Hive
,用于离线数据业务。缺点也很突出,不适用于持续增长的数据。
2. MQ方式
业务数据写入DB
的同时,也发送MQ
一份,也就是业务里面实现双写。这种方式比较简单,但也很难保证数据一致性,对简单的业务场景可以采用这种方式。
3. binlog方式
通过实时的订阅MySQL
的binlog
日志,消费到这些日志后,重新构建数据结构插入一个新的数据库或者是其他存储,比如es、slor
等等。订阅binlog
日志可以比较好的能保证数据的一致性。
二、MQ与Binlog方案实现
MQ方式
mq
的方式,相对简单,实际上是在业务逻辑中写DB
的同时去写一次MQ
,但是这种方式不能够保证数据一致性,就是不能保证跨资源的事务,因为MQ
可能出现消息堆积、重复消息、消息丢失等问题。
注:调用第三方远程RPC的操作一定不要放到事务中。否则可能造成大事务问题,影响程序性能
binlog方式
canal异构方式
binglog
是数据的日志记录方式,每次对数据的操作都会有binlog
日志。现在有很多开源的订阅binlog
日志的组件,比如使用比较广泛的canal
,它是阿里开源的基于mysql
数据库binlog
的增量订阅和消费组件。
由于canal
服务器目前读取的binlog
事件只保存在内存中,并且只有一个canal
客户端可以进行消费。所以如果需要多个消费客户端,可以引入activemq
或者kafka
。如上图绿色虚线框部分。
我们还需要确保全量对比来保证数据的一致性(canal+mq
的重试机制基本可以保证写入异构库之后的数据一致性),这个时候可以有一个全量同步WORKER
程序来保证,如上图深绿色部分。
canal的工作原理
先来看下mysql
主备(主从)复制原理如下图,在此原理基础之上我们再来理解canal
的实现原理就一眼能明白了。
mysql主备复制实现原理
mysql
主备(主从)复制原理,从上层来看,复制分成三步:
-
master
将改变记录到二进制日志(binary log
)中(这些记录叫做二进制日志事件,binary log events
,可以通过show binlog events
进行查看); -
slave
将master
的binary log events
拷贝到它的中继日志(relay log
); -
slave
重做中继日志中的事件,将改变反映到它自己的数据。
再来看下canal的原理,如下图:
cannal
实现原理相对比较简单(参照上面的mysql
主备复制实现原理):
-
canal
模拟mysql slave
的交互协议,伪装自己为mysql slave
,向mysql master
发送dump
协议 -
mysql master
收到dump
请求,开始推送binary log
给slave
(也就是canal
) -
canal
解析binary log
对象(原始为byte
流)
我们在部署canal server
的时候要部署多台,来保证高可用。但是canal
的原理,是只有一台服务器在跑处理,其它的服务器作为热备。canal server
的高可用是通过zookeeper
来维护的。
有关canal
更具体的使用和详细原理请参照:https://github.com/alibaba/canal
注意点
- 确认
MySQL
开启binlog
,使用show variables like 'log_bin';
查看ON
为已开启,一般都是已经开启的 - 确认目标库可以产生
binlog
,show master status
注意Binlog_Do_DB
,Binlog_Ignore_DB
参数 - 确认
binlog
格式为ROW
,使用show variables like 'binlog_format';
非ROW
模式则可以登录MySQL
执行set global binlog_format=ROW; flush logs;
或者通过更改MySQL
配置文件并重启MySQL
生效。 - 为保证
binlake
服务可以获取Binlog
,需添加授权,执行GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'admin'@'%' identified by 'admin'; FLUSH PRIVILEGES;
三、总结
本文主要叙述了数据异构的使用场景,方法。这里面涉及到的kafka
以及canal
并没有深入分析,关于这块的内容可以直接参考相关具体文档,文中已给了链接地址。
根据数据异构的定义,将数据异地构建存储,我们可以应用的地方就非常多,文中说的分库分表之后按照其它维度来查询的时候,我们想脱离DB
直接用缓存比如redis
来抗量的时候。数据异构这种方式都能够很好的帮助我们来解决诸如此类的问题。