介绍几种MySQL 同步到 ES 的解决方案

100人浏览   2024-08-06 11:47:21

在实际项目开发中,MySQL是作为业务数据库存在,ES则是作为查询数据库存在,通过两个服务器的共用,来实现读写分离操作,从而缓解了MySQL数据库的压力,同时也支持了海量数据的查询操作。

要完成这一系列的操作,首先需要解决的问题就是MySQL与ES的数据同步问题。下面我们就来讨论几种方案。

数据同步方案

同步双写

这是一种最为简单的实现数据同步的方案,它是将数据在写入到MySQL的时候,同时也写入到了ES中。

其优点就是业务逻辑相对简单,并且实时性较高,缺点则是需要以硬编码的方式写入,需要在写入MySQL的地方全部添加写入ES的操作,业务耦合性强,存在双写失败导致数据丢失的问题。然后再加上是双写操作,本来系统性能就不高,再加上一个ES操作,系统的性能会进一步的降低。

异步双写

针对多数据源的解决场景,可以借助于MQ的操作来实现异步写入多数据源操作。如下图所示。

其优点就是性能有所提高,由于是异步操作,不易出现数据丢失的情况,这主要是依赖于MQ对消息的保障,例如出现宕机或者假死的情况,MQ可以支持消息的重复消费。然后就是多数据源之间是相互隔离的,这样可以方便多数据源之间可以进行动态的扩展。

缺点则是需要在接入新数据源的时候写入新的消费者代码,并且由于引入了MQ消息中间件,导致系统维护的复杂度增加了。另外就是由于是异步操作,就会导致数据延迟。

基于SQL抽取

上面两种解决方案都存在硬编码的问题。所以代码侵入性太强,不利于扩展。当然如果对于数据的实时性要求不是太高,也可以考虑用定时器来处理。

首先增加一个与时间相关的字段,对于任意的CRUD操作都会导致时间字段发生变化。对原来程序的CRUD操作不做任何的操作,需要增加一个定时器,让定时器去定时执行数据,把这个时间段内的数据进行写入到ES中。

这种方式的优点就是不需要改变原来的代码,并且没有硬编码,代码没有侵入性,不需要与业务进行强耦合,这种方式由于是另外的定时器,所以也不会影响原来代码的性能。对于定时任务的代码编写相对简单,不需要考虑其性能问题。

而其缺点也是显而易见的,由于是定时器,所以说实时性不能保证,数据只能以固定周期来进行查询,尽管数据同步周期已经达到秒级,但是还是会出现延迟操作。并且在定时任务中一直是在执行操作的所以对数据库的性能也是一种考验。

经典方案:借助 Logstash 实现数据同步,其底层实现原理就是根据配置定期使用 SQL 查询新增的数据写入 ES 中,实现数据的增量同步。

基于 Binlog 实时同步

上面三种方案要么有代码侵入,要么有硬编码,要么有延迟,那么有没有一种方案既能保证数据同步的实时性又没有代码侵入呢?那么就有,可以利用 MySQL 的 Binlog 来进行同步

具体操作如下

  • 读取到MySQL的Binlog日志,获取到指定表的日志信息。
  • 将读取到的信息转到MQ中
  • 然后编写一个MQ程序来进行消费
  • 将消费的MQ信息写入到ES中

优点:没有代码侵入,没有硬编码,不会影响到原来的业务系统,实现性能较高,实现了业务之间的解耦,不需要去关注原来业务逻辑。

缺点:Binlog的结构相对复杂,所以构建整个MQ的过程也是比较麻烦的。如果采用了MQ来做消息异步操作,也会像之前的方案一样出现延迟风险。

总结

上面我们介绍了MySQL与ES数据同步的解决方案,当然还有很多的其他的解决方案,可以更具不同的业务选择不同的方式来实现。

相关推荐