当前位置: 首页 > news >正文

高频面试题:如何保证数据库和es数据一致性

背景

在实际项目开发中,我们经常将MySQL作为业务数据库,ES作为查询数据库,用来实现读写分离,缓解MySQL数据库的查询压力,应对海量数据的复杂查询,这其中有一个很重要的问题,就是如何实现MySQL数据库和ES的数据同步,今天和大家聊聊MySQL和ES数据同步的各种方案,我们先看看下面5种常用的数据同步。

在生产上,为了便于商品的聚合搜索,高速搜索,采用两大优化方案:

  • 把商品数据冗余存储在Elasticsearch中,实现高速搜索
  • 把商品数据冗余存储在redis 中,实现高速缓存
    在这里插入图片描述

要保持分布式数据的一致性,这个问题其实是一样的,关于redis的一致性问题在 《聊聊数据库和缓存一致性的几种实现方式》 。

一、同步双写

这是一种最为简单的方式,在将数据写到MySQL时,同时将数据写到ES。
在这里插入图片描述

优点: 1、业务逻辑简单 2、实时性高

缺点

  • 业务耦合,这种方式代码侵入性强,商品的管理中耦合大量数据同步代码,在每个写 mysql 的地方也都要加写 es 的代码。

  • 高风险:存在双写失败丢数据风险

  • 影响性能,写入两个存储,响应时间变长,本来 MySQL 的性能不是很高,再加一个 ES,系统的性能必然会下降。

二、异步双写

针对多数据源写入的场景,可以借助MQ实现异步的多源写入。
在这里插入图片描述

异步双写优点:

  • 性能高;
  • 不易出现数据丢失问题,主要基于 MQ 消息的消费保障机制,比如 ES 宕机或者写入失败,还能重新消费 MQ 消息;
  • 多源写入之间相互隔离,便于扩展更多的数据源写入。

异步双写缺点

  • 硬编码问题,接入新的数据源需要实现新的消费者代码;
  • 系统复杂度增加,引入了消息中间件;
  • MQ是异步消费模型,用户写入的数据不一定可以马上看到,造成延时

三、定时同步

上面两种方案中都存在硬编码问题,代码的侵入性太强,如果对实时性要求不高的情况下,可以考虑用定时器来处理。
在这里插入图片描述

1、数据库的相关表中增加一个字段为 timestamp 的字段,任何 CURD 操作都会导致该字段的时间发生变化;

2、原来程序中的 CURD 操作不做任何变化;

3、增加一个定时器程序,让该程序按一定的时间周期扫描指定的表,把该时间段内发生变化的数据提取出来;

4、逐条写入到 ES 中。

优点

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

缺点

  • 时效性较差,由于是采用定时器,根据固定频率查询表来同步数据,尽管将同步周期设置到秒级,也还是会存在一定时间的延迟。
  • 对数据库有一定的轮询压力,改进方法是将轮询放到压力不大的从库上,经典方案借助logstash实现数据同步,其底层实现原理就是,根据配置定期使用SQL查询新增的数据写入ES中,实现数据的增量同步。

四、Binlog实时同步

上面三种方案要么有代码侵入,要么有硬编码,要么有延迟,那么有没有一种方案既能保证数据同步的实时性又没有代码侵入呢?

当然有,可以利用MySQL的Binlog来进行同步。

在这里插入图片描述

具体步骤如下:

1、读取MySQL的binlog日志,获取指定表的日志信息;

2、将读取的信息转为MQ;

3、编写一个MQ消费程序;

4、不断消费MQ,每消费完一条消息将消息写入到ES中;

优点

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

缺点

  • 构建binlog系统复杂
  • 如果采用MQ消费解析的binlog信息,也会像方案二一样存在MQ延时的风险

MySQL通过binlog订阅实现主从同步,Canal Server 就是一个伪装的slave节点,接收到binlog日志后,发送到MQ,从而实现CDC(Change Data Capture),将已提交的更改发送到下游,包括insert,delete,update。

在这里插入图片描述

主要流程为:

1、Canal服务端向MySQL的master节点传输dumb协议。

2、MySQL的master节点接收到dump请求后推送binlog日志给Canal服务端,解析binlog对象(原始为byte
流)转成Json格式。

3、Canal客户端通过TCP协议或MQ形式监听Canal服务端,同步数据到ES。

在这里插入图片描述

下面是canal执行的核心流程:
在这里插入图片描述

五、etl工具

MySQL同步到Redis、MySQL同步到hbase、MySQL同步到es、或机房同步、主从同步等,都可以考虑使用etl工具。

什么是etl工具呢?

ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数据从来源端经过抽取(extract)、转换(transform)、加载(load)至目的端的过程。ETL一词较常用在数据仓库,但其对象并不限于数据仓库。

ETL是构建数据仓库的重要一环,用户从数据源抽取出所需的数据,经过数据清洗,最终按照预先定义好的数据仓库模型,将数据加载到数据仓库中去。

常用的etl工具有: databus、canal (方案四用了这个组件,有etl 的部分功能)、otter 、kettle等。

本文的一些专业名词是跟大数据有关的,所以放上一张大数据架构图,方便大家理解。

在这里插入图片描述

欢迎大家点赞、观看、收藏,一键三连~

相关文章:

  • 11.ArkUI Tabs的介绍和使用
  • 跟我学C++中级篇——处理对象的复制
  • 【科研绘图系列】R语言绘制区间点图(dot plot)
  • Vue前端学习笔记
  • 什么是测试驱动开发(TDD)?
  • Safety Estimands与Efficacy Estimands的差异剖析
  • UR5 UR5e机器人URDF文件
  • ai聊天流式响应,阻塞式和流式响应 nginx遇到的坑
  • 科技与商业动态简报
  • 基于python代码的通过爬虫方式实现快手发布视频(2025年4月)
  • QT 连接数据库操作(15)
  • 无人机环境适应性与稳定性技术要点!
  • python 环状图 (pycirclize)
  • 【含文档+PPT+源码】基于微信小程序连锁药店商城
  • 基于 Python(selenium) 的百度新闻定向爬虫:根据输入的关键词在百度新闻上进行搜索,并爬取新闻详情页的内容
  • 【Linux内核设计与实现】第三章——进程管理02
  • 在 Vue3 中封装的 Axios 实例中,若需要为部分接口提供手动取消请求的功能
  • 精益数据分析(22/126):解锁创业增长密码与长漏斗分析
  • 【黑马 微服务面试篇】
  • c# TI BQFS文件格式详解及C#转换
  • 王毅会见乌兹别克斯坦外长赛义多夫
  • 体坛联播|皇马上演罢赛闹剧,杨瀚森宣布参加NBA选秀
  • 剪纸纹样“流动”在水乡,谁不忆江南
  • 四川公布一起影视盗版案例:1个网站2人团伙盗售30多万部
  • 因商标近似李小龙形象被裁定无效,真功夫起诉国家知产局,法院判了
  • 《2025职场人阅读报告》:超半数会因AI改变阅读方向