ElasticSearch数据的同步方案

一、方案背景

  当订单数据量规模足够大或查询统计足够复杂时,通常会采用MySQL + NoSQL的架构方案,这种方案需要将MySQL中数据同步到其它介质,比如ClickHouse、ES等。订单数据的同步面临着诸多挑战,尤其是异构介质,下面会从”数据同步面临的挑战“和以及”订单数据特点“两个维度来分析。

1.1考虑因素

  1. 性能和稳定性: 订单系统为每个公司的核心业务系统,数据的同步尽量对订单系统无感,换言之,同步双写的方案会影响订单系统的性能和稳定性;
  2. 幂等性: 同步RPC和异步消息,都可能产生重复数据,数据落入ES时需要考虑数据去重,保证幂等性;
  3. 顺序性: 由于网络的不确定性,有可能数据库中先更新的数据后到达ES,导致最新的数据被旧数据覆盖;
  4. 关联性: 通常订单数据会包含很多信息,库表设计时通常会进行垂直拆分,通过订单号进行关联,当进行数据同步时,如何处理这些关联表的数据需要考虑;

1.2 数据特点

  1. 存量数据: 已完成或结束的订单归纳为”存量数据“,其特点是:数据量大、只读(没有变更,无需考虑顺序性);
  2. 增量数据: 未结束的订单归纳为”增量数据“,其特点是:并发量大、数据变更比较频繁(需要考虑顺序性);

ElasticSearch数据的同步方案

MySQL数据同步到ES中,大致总结可以分为三种方案:

方案1:监听MySQL的Binlog,分析Binlog将数据同步到ES集群中。

流程如下:

  • 给mysql开启binlog功能

  • mysql完成增、删、改操作都会记录在binlog中

  • 订单搜索服务基于canal监听binlog变化,实时更新elasticsearch中的内容

方案2:直接通过ES API将数据写入到ES集群中。 

     

基本步骤如下:

  • 订单搜索服务对外提供接口,用来修改elasticsearch中的数据

  • 订单管理服务在完成数据库操作后,直接调用订单搜索服务提供的接口

方案3:异步通知

 

流程如下:

  • 订单管理服务对mysql数据库数据完成增、删、改后,发送MQ消息

  • 订单搜索服务监听MQ,接收到消息后完成elasticsearch数据修改

考虑到订单系统ES服务的业务特殊性,对于订单数据的实时性较高,显然监听Binlog的方式相当于异步同步,有可能会产生较大的延时性。且方案1实质上跟方案2类似,但又引入了新的系统,维护成本也增高。所以订单中心ES采用了直接通过ES API写入订单数据的方式,该方式简洁灵活,能够很好的满足订单中心数据同步到ES的需求。

由于ES订单数据的同步采用的是在业务中写入的方式,当新建或更新文档发生异常时,如果重试势必会影响业务正常操作的响应时间。

所以每次业务操作只更新一次ES,如果发生错误或者异常,在数据库中插入一条补救任务,有Worker任务会实时地扫这些数据,以数据库订单数据为基准来再次更新ES数据。通过此种补偿机制,来保证ES数据与数据库订单数据的最终一致性。

1、实时性要求高的查询走DB

对于ES写入机制的有了解的同学可能会知道,新增的文档会被收集到Indexing Buffer,然后写入到文件系统缓存中,到了文件系统缓存中就可以像其他的文件一样被索引到。

然而默认情况文档从Indexing Buffer到文件系统缓存(即Refresh操作)是每秒分片自动刷新,所以这就是我们说ES是近实时搜索而非实时的原因:文档的变化并不是立即对搜索可见,但会在一秒之内变为可见。

当前订单系统ES采用的是默认Refresh配置,故对于那些订单数据实时性比较高的业务,直接走数据库查询,保证数据的准确性。

2、避免深分页查询

ES集群的分页查询支持from和size参数,查询的时候,每个分片必须构造一个长度为from+size的优先队列,然后回传到网关节点,网关节点再对这些优先队列进行排序找到正确的size个文档。

假设在一个有6个主分片的索引中,from为10000,size为10,每个分片必须产生10010个结果,在网关节点中汇聚合并60060个结果,最终找到符合要求的10个文档。

由此可见,当from足够大的时候,就算不发生OOM,也会影响到CPU和带宽等,从而影响到整个集群的性能。所以应该避免深分页查询,尽量不去使用。

参考:

订单系统设计 —— 数据同步与监控 - 爱码网

有赞订单同步的探索与实践

大促突围:京东到家基于Canal的数据异构设计_架构_dbaplus社群_InfoQ精选文章

百度安全验证

京东到家订单系统高可用架构的迭代实战_老朱的技术博客_51CTO博客

MySQL 数据实时同步到 Elasticsearch的技术方案选型和思考_语言 & 开发_万凯明_InfoQ精选文章 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在传统的开发中,我们可能会使用定时任务去实现数据同步的操作,但是这种方案存在一定的不足,例如数据同步的实时性可能不太好;此外,数据条数增多也可能会导致定时任务处理的效率变低。因此,我们可以使用springboot结合eselasticsearch)实现数据同步,来解决上述的问题。 首先,我们需要在springboot中引入es的相关依赖,例如spring-boot-starter-data-elasticsearch,这样我们就可以在项目中使用es的功能。接着,我们需要定义es的索引,并且定义好与数据库表的映射关系。这里可以使用spring-data-elasticsearch来完成。因为在es中没有表的概念,而是使用索引和类型来代替,因此我们需要将数据库表的数据转换成es中的文档格式。 在实现数据同步的功能时,我们可以使用JPA的监听器,例如@PostPersist,@PostUpdate,@PostRemove等注解,当数据库表的数据发生变化时,监听器会自动触发相应的方法,我们可以在这些方法中编写将数据同步es的代码逻辑,确保数据同步的实时性。 除了使用监听器来实现数据同步,我们还可以考虑使用消息队列(MQ)的方式,以便将数据同步的逻辑异步执行,降低数据同步时的压力。在MQ应用中,当数据源发生变化时,我们只需要将变化的数据同步到MQ中,之后再使用MQ监听器将数据异步地同步es中。 总的来说,springboot结合es实现数据同步,能够提升数据同步的实时性和效率,使整个系统更加稳定可靠,适用于数据实时同步场景,同时也为数据分析、搜索等场景提供了更好的支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值