链接:mp.weixin.qq.com/s/3mOdxTteXnqdmW-f3JhWsA 作者:潘新宇
更多干货关注公众号 勾勾的Java宇宙(Javagogo)
基于 Binlog 完成数据同步的全量缓存的读服务架构方案,可以实现平均性能在一百毫秒以内的高可用方案。不仅可以满足缓存同步的实时性要求,还能够降低同步的复杂度,以及解决分布式事务问题。
如何发送 Binlog?
以 MySQL 作为示例,MySQL 的 Binlog 分为三种数据格式:statement、row 及 mixed,示例:
create table demo_table{
id bigint not null auto_increment comment '主键',
message varchar(100) not null comment '消息',
status tinyint not null comment '状态',
created datetime not null '创建时间',
modified datetime not null '修改时间',
primary key ('id') using btree
}
1. statement 格式
statement 格式是把每次执行的 SQL 语句记录到 Binlog 文件里,在主从复制时,基于 Binlog 里的 SQL 语句进行回放来完成主从复制。
比如执行了如下 SQL 成功后:
update demo_table set status='无效' where id =1
Binlog 中记录的便是上述这条具体的 SQL。
采用 SQL 格式的 Binlog 的好处是内容太少,传输速度快。但存在一个问题,在基于 Binlog 进行数据同步时,需要解析上述的 SQL 获取变更的字段,存在一定的开发成本。
2. row 格式
row 格式的 Binlog 会把当次执行的 SQL 命中的那条数据库行的变更前和变更后的内容,都记录到 Binlog 文件里。以上述 statement 格式里的 SQL 作为示例,该 SQL 在 row 格式下执行后会产生如下的数据:
{
"before":{
"id":1,
"message":"文本",
"status":"有效",
"created":"xxxx-xx-xx",
"modified":"xxxx-xx-xx"
},
"after":{
"id":1,
"message":"文本",
"status":"无效",
"created":"xxxx-xx-xx",
"modified":"xxxx-xx-xx"
},
"change_fields":["status"]
}
上述案例记录的 Binlog 数据非常全面,包含了 demo_table 中所有字段对应的变更和未变更的数据,同时标记了具体哪些字段发生了变更。在数据同步时,可以完全以它为准。
基于上述格式的数据同步的实现代码会非常简单,但缺点是,产生的数据量较大。
- mixed 格式
mixed 是上述两种模式的动态结合。采用 mixed 格式的 Binlog 会根据每一条执行的 SQL 动态判断是记录为 row 格式还是 statement 格式。
比如一些 DDL 语句,如新增加字段的 SQL,就没有必要记录为 row 格式,记录为 statement 即可,因为它本身并没有涉及数据变更。
在实际应用中,推荐使用 row 或者 mixed。
-
原因一:这两种格式的数据量全,可以让你做更多的逻辑。因为随着业务需求的发展,同步逻辑会出现非常多的个性化需求,越多信息的数据,在编写代码时会越简单。
-
原因二:
row格式无须解析 SQL,实现复杂度非常低。在执行的 SQL 非常复杂时,对statement格式里记录的 SQL 的解析需要耗费大量开发精力,越复杂的解析越容易产生 Bug,所以推荐更加简单的row格式的数据。
链接:mp.weixin.qq.com/s/3mOdxTteXnqdmW-f3JhWsA 作者:潘新宇
更多干货关注公众号 勾勾的Java宇宙(Javagogo)