Mysql 同步 ElasticSearch 大宽表实践
前言
数据同步大宽表:把多张 Mysql 中的业务数据表组合成一张大宽表,一般业内选择使用 ES 来存储大宽表。
为什么要用 ES 构建大宽表
- Mysql 多表 join 性能很差
- Mysql 无法应对复杂条件查询
- Mysql 模糊查询和全文查询能力弱
- ES 是全文搜索引擎,有丰富的分词插件,支持自定义打分和排序,甚至可以引入检索算法实现语义理解
因此,可以将多个表的 Mysql 数据,同步到 ES 一张大宽表中,实现全局搜索;这需要一个同步方案。
如何从 Mysql 同步数据到 ES
目前主要有四种方案:同步双写、异步双写、定时任务调度、binlog 同步
同步双写
这是一种最为简单的方式,在将数据写到 mysql 时,同时将数据写到 ES。
异步双写
由于发消息比写 es 快多了,所以异步双写通过发消息来异步执行写 es 的逻辑!
定时任务调度
上面两种方案中都存在硬编码问题,也就是有任何对 mysq 进行增删改查的地方要么植入 ES 代码,要么替换为 MQ 代码,代码的侵入性太强,若是实时要求不高的情况下,可以考虑用> 定时器来处理,具体步骤如下:
- 数据库的相关表中增加一个字段为 timestamp 的字段,任何 crud 操作都会导致该字段的时间发生变化;
- 原来程序中的 crud 操作不做任何变化;
- 增加一个定时器程序,让该程序按一定的时间周期扫描指定的表,把该时间段内发生变化的数据提取出来;
- 逐条写入到 ES 中。
Binlog 同步
上面三种方案要不有代码侵入、要不有硬编码、要不有时延,那么有没有一种稍微折中的方法嘞?答案就是利用 mysql 的 binlog! 具体步骤如下:
- 读取 mysql 的 binlog 日志,获取指定表的日志信息;
- 将读取的信息转为 MQ;
- 编写一个 MQ 消费程序;
- 不断消费 MQ,每消费完一条消息,将消息写入到 ES 中。