MySQL与ES数据同步方案

背景

随着系统业务的不断发展,部分核心业务的数据规模愈发庞大,查询统计等场景愈发复杂,mysql的性能逐渐无法满足日常的使用需求,特别是各种维度的搜索场景。

这种情况下,一般都会选择将搜索的数据源从Mysql转移到ElasticSearch,但同时也需要面对两个数据源的数据如何同步问题。

方案

总的来说,数据同步方案基本分为"同步写"和"异步写"两个大方向,并在这两个大方向上进行具体实现,同时都伴随着各自的优缺点。

同步双写

同步双写,顾名思义,就是数据写入MySQL同时,需要调用ES进行数据写入,如下图:

优点:

  • 实现简单;
  • 相较于其他方案,数据实时性较高。

缺点:

  • 代码耦合性强。
  • 同步双写事务问题,性能较低。
  • 系统可用性同时受多个数据源可用性影响,系统可用性降低;

为何强调该方案数据实时性高是相较于其他方案呢?

在默认情况下,ElasticSearch并非实时写入的,而是近实时,即对文档的修改,默认最多等待1s,就可以查询到。由于其他方案大多不是同步写,所以相对来说,本方案实时性较高。

异步双写

由于同步双写会造成系统可用性降低,那很容易想到优化方案,就是同步改成异步,如下图

关于该方案中的异步,其实有不同的实现方式,比如异步线程、异步消息订阅等实现方式。在实际工作中,一般基于消息中间件的异步消息订阅的方式来实现。

优点:

  • 代码耦合性低,业务代码无需关注数据同步;
  • 性能高,避免了双写的事务问题,系统可用性较高;
  • 拓展性强,基于消息中间件的消息订阅,非常容易进行多数据源和异构数据的拓展。

缺点:

  • 数据实时性相对同步写稍低。
  • 引入其他中间件,增加系统复杂度。

定时同步

基于消息中间件的异步双写是个不错的方案,但是需要同时引入消息中间件,对于部分"小步快跑"的项目来说,增加了时间和金钱的成本,那么此时继续定时任务的数据同步,是个不错的临时选择。

定时任务同步的实现方式,是基于对MySQL表进行定时扫描读取数据后,写入到ElasticSearch中,如下图

优点:

  • 实现简单,对原有代码无侵入性;

缺点:

  • 实时性取决与定时任务的周期,实时性难以保证;
  • 当对实时性有较高要求时,对MySQL会造成较大的压力,可能导致系统整体可用性下降(可将轮询方到MySQL从库在一定程度避免)。

binlog订阅同步

众所周知,binlog是MySQL的逻辑日志,可以用来进行数据的同步和复制,MySQL主从同步就是基于binlog日志实现的。那么,MySQL与ElasticSearch间的数据同步,是否也可以基于binlog日志呢,答案是可以的。

一般来说,该方案需要引入一个中间件工具,作用是伪装成MySQL从库,接收主库binlog,然后同步到的其他数据源,如MySQL、ElasticSearch、HBase等等。市面上常见中间件工具如Flink-CDC、Canal、Otter、DataX等等,其基本原理如下图。

如图所示,实际上,我们往往会将binlog中间件接收到的binlog数据,转换成异步消息后推向消息中间件,方便其他服务订阅消费。其实binlog订阅同步的方案,可以说是前面"异步双写"方案的升级版,其进一步将"数据同步"功能下沉,与业务代码进一步解耦,这也符合软件开发中的"单一职责"原则。

优点:

  • 对业务代码的入侵极少,开发过程中无感知;
  • 数据实时性较高;

缺点:

  • 需要引入中间件,架构上增加了复杂度,且同时增加了维护成本;

总结

本文只对MySQL与ES数据同步实现方案的基本思路进行简单介绍,并未涉及具体业务场景的实践。在实际中,需要对业务场景进行分析,权衡利弊,选择适合自己的方案,并在具体的实现细节上进行调整。

相关推荐
小池先生33 分钟前
springboot启动不了 因一个spring-boot-starter-web底下的tomcat-embed-core依赖丢失
java·spring boot·后端
小蜗牛慢慢爬行2 小时前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
wm10432 小时前
java web springboot
java·spring boot·后端
龙少95434 小时前
【深入理解@EnableCaching】
java·后端·spring
溟洵6 小时前
Linux下学【MySQL】表中插入和查询的进阶操作(配实操图和SQL语句通俗易懂)
linux·运维·数据库·后端·sql·mysql
SomeB1oody8 小时前
【Rust自学】6.1. 定义枚举
开发语言·后端·rust
SomeB1oody9 小时前
【Rust自学】5.3. struct的方法(Method)
开发语言·后端·rust
啦啦右一10 小时前
Spring Boot | (一)Spring开发环境构建
spring boot·后端·spring
森屿Serien10 小时前
Spring Boot常用注解
java·spring boot·后端
盛派网络小助手12 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#