Mysql数据如何优雅的同步ES?

文章目录

  • 一、前言
  • 二、ES数据同步方案
    • 1、方案一:应用程序双写
        • 1)同步双写,代码侵入性比较高
        • 2)异步双写,MQ方式
        • 3)异步双写,定时任务方式
    • 2、方案二:基于binlog 同步(业界比较成熟的方案)
          • 1) 限制条件:
          • 2) 具体步骤如下:
          • 3)优缺点

一、前言

随着业务发展,数据量的增长,对数据全文检索模糊查询显得普遍而重要。

这个时候Mysql就无法应对海量数据下各种复杂条件的查询。有人说加索引,加索引确实可以提升查询速度,但是索引也是成本,Mysql 中加多个索引最终在执行 SQL 的时候它只会选择成本最低的那个索引,如果没有索引满足搜索条件,就会触发全表扫描,出现慢sql等性能低下,而有些场景是加索引也解决不了的。

这样的话,我们可以借助搜索引擎,将数据发送到搜索引擎(如ES)上,由搜索引擎来提供专业的服务。而ES是搜索引擎中佼佼者,选用ES无疑是Mysql的一个有效补充。

二、ES数据同步方案

1、方案一:应用程序双写

Mysql数据如何优雅的同步ES?_第1张图片

1)同步双写,代码侵入性比较高

这是一种最为简单的方式,在将数据写到mysql时,同时将数据写到ES,实现数据的双写。

优点:

  • 业务逻辑简单。

缺点:

  • 硬编码:有需要写入mysql的地方都需要添加写入ES的代码;业务强耦合;
  • 存在双写失败丢数据风险;ES系统不可用;应用系统和ES之间的网络故障;应用系统重启,导致系统来不及写入ES等;
  • 性能较差:本来mysql的性能就不是很高,再加写一个ES,有数据强一致性要求的,就必须双写放到事物中来处理,系统的性能必然会下降。

2)异步双写,MQ方式

针对第一种同步双写的性能和数据丢失问题,可以考虑引入MQ中间件:

优点:

  • 性能高,MQ的性能基本比mysql高出一个数量级;解决数据一致性问题;
  • 把同步变为异步,做了部分解耦

缺点:

  • 会增加延迟性,由于MQ的消费可能由于网络或其它原因导致用户写入的数据不一定可以马上看到,造成延时;
  • 硬编码问题:依然存在业务强耦合,业务系统增加mq代码;
  • 复杂度增加:多一个MQ中间件要维护

3)异步双写,定时任务方式

上面两种方案中都存在硬编码问题,也就是有任何对mysq进行增删改查的地方要么植入ES代码,要么替换为MQ代码,代码的侵入性太强。

如果对实时性要求不高的情况下,可以考虑用定时器来处理,在 MySQL 的表结构里设置特殊的字段,增加一个字段为timestamp的字段,如 updated_at(数据的更新时间),任何crud操作都会导致该字段的时间发生变化。起一个定时任务,在用户低峰的时候,执行定时任务,去查询实际变更的数据,从而实现数据的增量更新到es中。这种方式可以使用开源的 Logstash 去完成。当然缺点也很明显,就是无法同步数据的物理删除操作。

优点:

  • 不改变原来代码,没有侵入性、没有硬编码;
  • 没有业务强耦合;不改变原来程序的性能;
  • 定时代码编写简单不需要考虑增删改查。

缺点:

  • 时效性较差,由于定时器工作周期不可能设在秒级,所以实时性没有上面几种好;
  • 对数据库有一定的轮询压力,一种改进方法是将轮询放到压力不大的重库上。

2、方案二:基于binlog 同步(业界比较成熟的方案)

上面三种方案要么有代码侵入,要么有硬编码,要么有时延,所以通常我们利用mysql的binlog方式来进行同步。

1) 限制条件:
  • Mysql binlog必须是row模式

Mysql 的 binlog 三种格式:
第一种:row 模式,binlog 按行的方式去记录数据的变更;
第二种:statement 模式,binlog 记录的是 SQL 语句;
第三种: mixed 模式时,混合以上两种,记录的可能是 SQL 语句或者 ROW 模式的每行变更;

show variables like 'log_bin'; 查看binlog开启状态。
show variables like 'binlog-format'; 查看binlog格式。

  • 要同步的mysql数据表必须包含主键,否则直接忽略,这是因为如果数据表没有主键,UPDATE和DELETE操作就会因为在ES中找不到对应的document而无法进行同步
  • 不支持程序运行过程中修改表结构
  • 要赋予用于连接mysql的账户RELOAD权限以及REPLICATION权限, SUPER权限:
    GRANT REPLICATION SLAVE ON *.* TO 'elastic'@'172.16.32.44'; GRANT RELOAD ON *.* TO 'elastic'@'172.16.32.44'; UPDATE mysql.user SET Super_Priv='Y' WHERE user='elastic' AND host='172.16.32.44';
2) 具体步骤如下:
  • 读取mysql的binlog日志,获取指定表的日志信息;
  • 将读取的信息转为MQ;
  • 编写一个MQ消费程序;
  • 不断消费MQ,每消费完一条消息,将消息写入到ES中。
3)优缺点

优点:

  • 没有代码侵入、没有硬编码;原有系统不需要任何变化,没有感知;
  • 性能高;
  • 业务解耦,不需要关注原来系统的业务逻辑。

缺点:

  • 构建binlog系统复杂;
  • 存在MQ延时的风险

binglog其他详细解释参考博文:https://blog.csdn.net/weixin_47061482/article/details/115163442

你可能感兴趣的:(《数据库问题解决方案》系列,#,《ES必知必会》系列,mysql,es,mysql同步es)