分布式专题——57 如何保证MySQL数据库到ES的数据一致性

1 业务场景介绍

1.1 需求分析

  • 功能需求 :用户可通过目的地、酒店名称、房型、价格范围 等属性,对旅游优惠酒店进行全模糊搜索
  • 非功能需求(性能要求)
    • QPS(每秒查询率):春季促销期间预计达到1000左右,需支撑高并发搜索;
    • 响应时间:搜索响应需控制在500毫秒以内,保障用户体验;
    • 数据一致性:确保搜索结果反映最新的酒店信息及可用性

1.2 技术实现方案

  • 假设底层用MySQL存储酒店数据,技术方案如下:

    • 数据同步 :利用MySQL的binlog(二进制日志)或第三方工具(如Debezium、Canal),实时监听酒店数据的变更,并将变更同步到Elasticsearch(ES)中;

    • 索引构建 :在Elasticsearch中,为目的地、酒店名称、房型、价格范围 等字段建立合适的索引,以支持快速、高效的模糊搜索

  • 思考:如何保证MySQL数据库和ES的数据一致性?

2 业界常用数据一致性方案分析

  • 在确保MySQL数据库和Elasticsearch(ES)数据一致性方面,业界有以下4种常见方案:
    • 同步双写方案:代码中对数据库和ES进行双写操作,保证先更新数据库后更新ES,依赖事务回滚保证一致性

    • MQ异步双写方案:通过消息队列(如RocketMQ、Kafka)做中间件,应用更新数据库后发消息到MQ,由消费者异步更新ES

    • 扫表定时同步方案:通过定时任务扫描数据库,将变更数据同步到ES

    • 监听binlog同步方案:直接监听MySQL的binlog实现数据库和ES的实时同步

2.1 同步双写方案

  • 实现思路 :在数据写入MySQL的同时,直接将相同数据写入ES;

  • 优点

    • 数据一致性:能保证MySQL和ES之间强一致性,数据库变更会同步反映到ES
    • 实时性:数据实时同步,MySQL的操作会立即在ES中体现
    • 易于实现:技术角度实现相对简单,只需在应用代码中添加双写逻辑
  • 缺点

    • 代码复杂性:需在应用程序中添加额外代码处理双写,增加代码复杂度和维护难度
    • 性能开销:每次数据库操作需执行两次(写MySQL+写ES),高并发场景下性能开销显著
    • 数据不一致风险:若系统故障或网络延迟,可能出现"MySQL写入成功但ES写入失败"的不一致情况
  • 应用场景

    • 系统特点:旧系统年限长、单体架构且技术较落后,引入其他中间件治理成本很高

    • 业务场景:用户量少、偏后台管理类的系统,对数据同步实时性要求很高(接近实时)

2.2 MQ异步双写方案

  • 实现思路 :使用消息队列(如RocketMQ、Kafka)作为中间件,应用程序更新数据库后发送消息到MQ ,由MQ的消费者异步更新ES

  • 方案核心

    • 生产者双写:生产者系统发送消息到MQ的同时,写入MySQL

    • 消费者异步处理:消费者从MQ中读取消息,异步将处理结果写入ES

  • 优点

    • 系统解耦:降低MySQL和ES之间的依赖性,提升系统可维护性和扩展性
    • 高可用性:MQ提供消息持久化存储,即使系统故障,消息也不会丢失
    • 容错性:某系统出现故障时,数据仍可通过其他系统恢复
  • 缺点

    • 延迟:异步处理可能导致数据同步延迟,高负载或资源不足时更明显
    • 复杂度:引入MQ和双写机制增加系统复杂度,开发和维护成本上升
    • 补偿机制:需设计复杂补偿机制处理同步失败情况,进一步增加复杂度
  • 应用场景

    • 系统特点:

      • C端系统:面向最终用户(如移动应用、Web应用、桌面应用)
      • 引入MQ中间件:系统架构已包含消息队列中间件,为异步处理提供基础
      • 接口TPS性能要求:系统对接口吞吐量(TPS)有要求,需保证高并发场景下的性能
    • 业务场景:

      • 用户体量大,高并发场景:大量用户同时操作,系统面临高并发压力
      • 业务变更少:业务逻辑变更相对少,数据同步需求较稳定
      • 允许一定延迟:在保证用户体验的前提下,数据同步延迟在秒级范围内可接受

2.3 扫表定期同步方案

  • 实现思路 :通过定时任务定期扫描MySQL数据库,将变更的数据同步到ElasticSearch;

  • 优点

    • 实现简单:借助定时任务调度框架,无需复杂开发工作
    • 适合批量数据:批量处理可减少网络传输次数和ES写入压力,适用于大量数据迁移
    • 对业务影响小:定时任务可在系统负载较低的时段运行,降低对在线业务的干扰
  • 缺点

    • 实时性差:因定期执行,数据同步存在延迟,不适合实时性要求高的场景
    • 性能影响:同步过程中(尤其是数据量大时)可能对MySQL和ES的性能产生短期影响
    • 数据一致性风险:若同步周期内数据发生变化,可能导致ES与MySQL数据不一致
  • 应用场景

    • 系统特点:旧系统年限长、技术框架老旧,引入其他中间件治理成本很高

    • 业务场景:用户体量小、偏报表统计类业务、对数据实时性要求不高的场景

2.4 监听binlog同步方案

  • 实现思路 :通过直接监听MySQL的binlog(二进制日志),实现数据库和ES之间的实时同步;

    • 基础流程:酒店管理服务写入MySQL后,由canal服务监听binlog变更,直接同步到ES

    • 高并发优化:在高并发场景下,可引入Kafka作为缓冲层,暂时存储binlog事件,平滑数据流,避免ES瞬时高负载

  • 优点

    • 业务无侵入:无需修改业务代码,数据同步准实时
    • 业务解耦:不需要关注原系统的业务逻辑,系统间依赖性低
  • 缺点

    • 系统复杂度高:构建Binlog监听系统(如部署canal、Kafka等组件)较为复杂
    • 潜在延迟风险:若采用MQ(如Kafka)消费解析Binlog信息,会存在类似MQ异步方案的延迟风险
  • 应用场景

    • 系统特点:C端系统,可开放MySQL binlog日志监听,引入第三方canal中间件成本不高

    • 业务场景:互联网公司、用户体量大、大型多中心组织、高并发场景,业务上允许一定延迟(秒级)的场景

相关推荐
a努力。21 小时前
宇树Java面试被问:方法区、元空间的区别和演进
java·后端·面试·宇树科技
2501_9167665421 小时前
【面试题1】128陷阱、==和equals的区别
java·开发语言
2301_767902641 天前
MySQL 入门
数据库·mysql
a程序小傲1 天前
蚂蚁Java面试被问:注解的工作原理及如何自定义注解
java·开发语言·python·面试
未知原色1 天前
web worker使用总结(包含多个worker)
前端·javascript·react.js·架构·node.js
7ioik1 天前
说一说MySQL数据库基本架构?
数据库·mysql·架构
@淡 定1 天前
Redis持久化机制
数据库·redis·缓存
幽络源小助理1 天前
SpringBoot+Vue摄影师分享社区源码 – Java项目免费下载 | 幽络源
java·vue.js·spring boot
0和1的舞者1 天前
《软件测试分类指南:8 大维度 + 核心要点梳理》
java·软件测试·单元测试·测试·黑盒测试·白盒测试·测试分类
TAEHENGV1 天前
创建目标模块 Cordova 与 OpenHarmony 混合开发实战
android·java·开发语言