Skip to content

Mysql 同步 ElasticSearch 大宽表实践

前言

数据同步大宽表:把多张 Mysql 中的业务数据表组合成一张大宽表,一般业内选择使用 ES 来存储大宽表。

为什么要用 ES 构建大宽表

  1. Mysql 多表 join 性能很差
  2. Mysql 无法应对复杂条件查询
  3. Mysql 模糊查询和全文查询能力弱
  4. ES 是全文搜索引擎,有丰富的分词插件,支持自定义打分和排序,甚至可以引入检索算法实现语义理解

因此,可以将多个表的 Mysql 数据,同步到 ES 一张大宽表中,实现全局搜索;这需要一个同步方案。

如何从 Mysql 同步数据到 ES

目前主要有四种方案:同步双写、异步双写、定时任务调度、binlog 同步

同步双写

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

异步双写

由于发消息比写 es 快多了,所以异步双写通过发消息来异步执行写 es 的逻辑!

定时任务调度

上面两种方案中都存在硬编码问题,也就是有任何对 mysq 进行增删改查的地方要么植入 ES 代码,要么替换为 MQ 代码,代码的侵入性太强,若是实时要求不高的情况下,可以考虑用> 定时器来处理,具体步骤如下:

  1. 数据库的相关表中增加一个字段为 timestamp 的字段,任何 crud 操作都会导致该字段的时间发生变化;
  2. 原来程序中的 crud 操作不做任何变化;
  3. 增加一个定时器程序,让该程序按一定的时间周期扫描指定的表,把该时间段内发生变化的数据提取出来;
  4. 逐条写入到 ES 中。

Binlog 同步

上面三种方案要不有代码侵入、要不有硬编码、要不有时延,那么有没有一种稍微折中的方法嘞?答案就是利用 mysql 的 binlog! 具体步骤如下:

  • 读取 mysql 的 binlog 日志,获取指定表的日志信息;
  • 将读取的信息转为 MQ;
  • 编写一个 MQ 消费程序;
  • 不断消费 MQ,每消费完一条消息,将消息写入到 ES 中。

参考资料