MYSQL 同步到ES 如何设计架构保持一致性

简单使用某个组件很容易,但是一旦要搬到生产上就要考虑各种各样的异常,保证你方案的可靠性,可恢复性就是我们需要思考的问题。今天来聊聊我们部门在 MYSQL 同步到ES的方案设计。

在面对复杂条件查询时,MYSQL往往显得力不从心,一般公司的做法会通过将mysql中的数据同步到ES,之后的查询就通过ES进行查询,ES在面对多条件复杂查询时,能较快的查询出结果集。

在MYSQL数据 到ES中的数据同步 方案设计上,就有多种选择,

1,最简单的便是直接在业务代码中对数据库进行修改,插入,删除时,同步修改ES中的数据。 但这种方案也是最不可靠的一种设计。在写入MYSQL后,业务服务宕机了,ES数据就会丢失。如果写入ES失败,重试逻辑将会嵌套在业务代码中,业务代码复杂性增加了,并且如果一直失败,要一直重试吗?

所以,对于这种方案,直接pass掉了。

2,第二种同步方案则是业界用的比较多的同步方案,通过binlog进行同步,目前业界已经有比较成熟的模拟mysql从库,拉取binlog的组件,例如阿里开源的canal。整个同步架构如下所示,canal组件充当mysql从库的角色,将mysql的binlog拉取下来,由客户端从canal拉取消息进行消费,再由客户端主动插入或者更新ES中的数据。

📢📢注意,这里我用的是客户端主动从cannal拉取binlog消息的方式,实际上还可以通过让cannal主动发送binlog消息到消息队列,然后client异步消费kafka中的消息。

image.png

所以,我们部门选择了第二种同步方案,并且由于数据量并不大,也没有接入kafka,直接采用客户端从cannal侧拉数据的方式。

canal 同步数据异常情况分析

接着我先来提几个问题,我们可以思考🤔看看当前的架构设计是否能满足数据同步的基本要求。

1,如果客户端消费数据失败,会造成数据丢失吗?

2,如果cannal崩溃了,那么会造成拉取的binlog没有被消费而造成数据丢失的情况吗?

3,canal会有重复推送消费消息的情况吗?

4,如果ES侧暂时宕机,要想不丢失数据,应该怎么做?

以上是我针对同步数据时 围绕这个设计方案的可靠性与可恢复 提出的几个问题,我们针对它们来看看同步数据应该如何来做。

第一个问题, 客户端如果从canal拉取到了消息,但是本地由于异常,或者宕机 导致消费失败了,可以做到不丢失数据。因为canal 对于消息的消费模型提供了ACK机制,客户端在拉取完一批消息后,可以依次消费消息,然后发送对应消息的ACK,如果消费失败,或者本地宕机,那么下次拉取消息的时候依然能够拉取到没有消费完的消息。

第二个问题cannal 如果异常崩溃,也是可以做到 消息不丢失,canal在从数据库拉取binlog时,会记录拉取的日志偏移量offset到内存,但是偏移量的持久化 其实是通过定时任务 考虑客户端ACK位点后,才进行记录的,可以选择记录到zookeeper或者本地文件。所以如果canal宕机了,那么重启后,会从zookeeper或者本地文件中读取客户端最后ack的位点,然后从这个位置开始从数据库拉取消息。为了让canal 快速恢复,还可以做canal集群,让集群中始终有备节点。

第三个问题canal的确会有重复推送消费消息的可能,正如第二问题说的那样 偏移量的持久化是通过定时任务记录的,所以存在客户端消费了消息,但是这个ack位点还没有持久化的情况,如果这个时候canal 宕机重启了,那么将会把客户端消费过的消息也再发一遍。所以客户端消费消息需要做幂等处理。

第四个问题如果ES侧的数据写入失败了,或者ES直接宕机,也是能够做到ES宕机恢复后,数据不丢失的,最简单的方式其实是客户端发现ES写入失败了,然后不ACK消息,直接不断重试,直到写入成功为止,不过这种做法其实不太好,因为不ACK,那么消息会一直存到canal的内存里,同时canal会不断dump 数据库的binlog日志,又塞到内存里等待被客户端拉取消费,这样造成的后果就是canal 的内存会越来越大,最终停止数据库的同步操作。

一个比较好点的方式是,客户端消费了canal的消息,直接在本地将消息保存起来,比如写入到磁盘文件上,写入成功后即可发起ACK,然后本地启一个协程慢慢将磁盘文件上的消息更新到ES中,所以,最后选用了leveldb 对做本地文件的写入,leveldb写入文件的操作是很快的,这样快速的ACK消息对canal的内存压力也会小很多。

综上,我们部门的数据同步模型就变成了下面这样,canal做了集群,保证宕机了还有其他节点可以继续同步,客户端则是消费消息后将先把消息写入到本地,然后开启定时任务写入到ES,如果有错误的话,会一直重试,直到成功为止。

image.png

总结

最后,我来总结下,采用canal 去做MySQL 到ES的数据同步,我们的确是可以做到高可靠性的,但是要注意的canal的消息消费是有可能出现重复消息的,不过由于目前我们部门没有对消息进行统计的需求,仅仅是将数据进行更新或者插入,存在即更新,没有即插入,所以是幂等,可以不用太过关注。

文章转载自:蓝胖子的编程梦

原文链接:https://www.cnblogs.com/hobbybear/p/18087591

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/764376.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Gitlab介绍

1.什么是Gitlab GitLab是一个流行的版本控制系统平台,主要用于代码托管、测试和部署。 GitLab是基于Git的一个开源项目,它提供了一个用于仓库管理的Web服务。GitLab使用Ruby on Rails构建,并提供了诸如wiki和issue跟踪等功能。它允许用户通…

从0到1实现RPC | 02 RpcConsumer的远程调用

一、RPC的简化版原理如下图(核心是代理机制)。 1.本地代理存根: Stub 2.本地序列化反序列化 3.网络通信 4.远程序列化反序列化 5.远程服务存根: Skeleton 6.调用实际业务服务 7.原路返回服务结果 8.返回给本地调用方 二、新建一个模块rpc-demo-c…

Puppet 2024年度报告:平台工程发掘 DevOps 无限潜质

Puppet 于本周发布了一份2024年的 DevOps 现状报告 The State of DevOps Report: The Evolution of Platform Engineering。该报告显示了平台工程的持续成熟,43%的受访者报告称他们的平台团队已经存在至少3-5年。 自2012年以来,Puppet 每年发布的关于 De…

后端程序员入门react笔记(九)- react 插件使用

setState setState引起的react的状态是异步的。操作完毕setState之后如果直接取值,可能取不到最新的值,我们举个例子console.log(this.state.num)打印的值,总是上一次的值而不是最新的。 import React, {Component} from react; class Ap…

基于ArcGIS的2015-2020辽宁省土地利用变化分析

数据准备 栅格转面 运行ArcToolbox,打开【转换工具】,选择【从栅格转出】里面的【栅格转面工具】,调出面板进行参数设置。输入栅格选择裁剪的2015年中国土地利用遥感监测数据(…

Kafka批量消费

在Spring Kafka中,使用KafkaListener注解处理批量信息时,首先需要开启批量监听模式,并配置相应的consumer参数来控制批量消费行为。以下是配置和处理批量消息的基本步骤: 配置Kafka消费者工厂: 设置batchListener属性为…

数据挖掘与分析学习笔记

一、Numpy NumPy(Numerical Python)是一种开源的Python库,专注于数值计算和处理多维数组。它是Python数据科学和机器学习生态系统的基础工具包之一,因为它高效地实现了向量化计算,并提供了对大型多维数组和矩阵的支持…

复习Day1

92. 递归实现指数型枚举 - AcWing题库 #include <bits/stdc.h> using namespace std; const int N17; int n; bool vis[N];//记录某一个数是否出现过 void dfs(int dep){// if(vis[dep])continue;//没有这一句 因为一定不会有已经选过的数if(depn1){for(int i1;i<n;i…

【Node.js从基础到高级运用】十七、Node.js的性能优化

引言 在软件开发的世界里&#xff0c;性能优化是一个永恒的话题。Node.js作为一个基于Chrome V8引擎的JavaScript运行时&#xff0c;它的性能优化尤为重要。因为Node.js的非阻塞I/O和事件驱动特性&#xff0c;使得它在处理大量并发请求时表现出色。但是&#xff0c;这并不意味着…

【ReactJS】使用GoJS实现自己的图表App

目录 1:用于绘制自定义图表的JavaScript库:用于绘制UML(或BPMN或ERD …)图表的JavaScript库:2:为什么选择GoJS?3:让我们使用现有的React应用程序:步骤1:步骤2:步骤3:步骤4:推荐超级课程: Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战1:…

git创建仓库、克隆、拉取、上传、历史等常见操作集锦

本地工作目录、暂存区、本地仓库和远程仓库 workspace工作区:本地项目地址index/stage暂存区:git add .将工作区内容加入到了暂存区repository本地仓库:在本地存储多个版本的文件,也称为版本库。其中有一个head指针指向最新放入仓库的文件版本,git commit -m "描述你…

[医学分割大模型系列] (1) SAM 分割大模型解析

[医学大模型系列] [1] SAM 分割大模型解析 1. 特点2. 网络结构2.1 Image encoder2.2 Prompt encoder2.3 Mask decoder 3. 数据引擎4. 讨论 论文地址&#xff1a;Segment Anything 开源地址&#xff1a;https://github.com/facebookresearch/segment-anything demo地址&#x…

C#,图片分层(Layer Bitmap)绘制,反色、高斯模糊及凹凸贴图等处理的高速算法与源程序

1 图像反色Invert 对图像处理的过程中会遇到一些场景需要将图片反色,反色就是取像素的互补色,比如当前像素是0X00FFFF,对其取反色就是0XFFFFFF – 0X00FFFF = 0XFF0000,依次对图像中的每个像素这样做,最后得到的就是原始2 图像的反色。 2 高斯模糊(Gauss Blur)算法 …

Word中文字重叠在一起怎么办

Word中文字重叠在一起怎么办 在编辑Word文档时&#xff0c;按照文档排版的设计&#xff0c;对其中的文字设置了字体和字号&#xff0c;没有设置以前&#xff0c;文字在Word中显示是正常的&#xff0c;不过&#xff0c;设置了字体字号后&#xff0c;文字在文档就却重叠在一起了&…

关于Linux环境下的LXD及Docker提权

希望和各位大佬一起学习&#xff0c;如果文章内容有错请多多指正&#xff0c;谢谢&#xff01; 个人博客链接&#xff1a;CH4SER的个人BLOG – Welcome To Ch4sers Blog 0x01 基本概念 LXD、LXC 和 Docker 是三种不同的容器化技术&#xff0c;它们在实现和使用上有一些区别。…

RabbitTemplate :简化与 RabbitMQ 消息代理的交互

RabbitTemplate 是 Spring AMQP 项目中提供的一个核心类&#xff0c;用于简化与 RabbitMQ 消息代理的交互。在 Spring 应用程序中&#xff0c;使用 RabbitTemplate 可以方便地发送和接收消息&#xff0c;从而简化了 RabbitMQ 的使用。 一、RabbitTemplate 概述 RabbitTemplat…

cesium知识点:坐标系

一&#xff0c;地理坐标系 1.经纬度坐标系 对象&#xff1a;没有实际的对象 说明&#xff1a;cesium默认使用WGS84坐标系作为空间参考&#xff0c;坐标原点在椭球的质心。 2.弧度坐标系(Cartographic) 对象&#xff1a;new Cesium.Cartographic(longitude, latitude, heigh…

easyExcel大数据量导出oom

easyExcel大数据量导出 异常信息 com.alibaba.excel.exception.ExcelGenerateException: java.lang.OutOfMemoryError: GC overhead limit exceededat com.alibaba.excel.write.ExcelBuilderImpl.fill(ExcelBuilderImpl.java:84)at com.alibaba.excel.ExcelWriter.fill(Excel…

AI智能分析网关V4养老院视频智能监控方案

随着科技的快速发展&#xff0c;智能监控技术已经广泛应用于各个领域&#xff0c;尤其在养老院这一特定场景中&#xff0c;智能监控方案更是发挥着不可或缺的作用。尤其是伴随着社会老龄化趋势的加剧&#xff0c;养老院的安全管理问题也日益凸显。为了确保老人的生活安全&#…