从MongoDB迁移到Elasticsearch后,我们减少了80%的服务器

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 本文介绍“为什么要从MongoDB迁移到Elasticsearch?”以及“如何从MongoDB迁移到Elasticsearch?”。

本文作者

李猛,Elastic Stack 深度用户,通过 Elastic 工程师认证,2012年接触 Elasticsearch,对 Elastic Stack 技术栈开发、架构、运维等方面有深入体验,实践过多种大中型项目;为企业提供 Elastic Stack 咨询培训以及调优实施;多年实战经验,爱捣腾各种技术产品,擅长大数据,机器学习,系统架构。

序言

本文内容涉及到 MongoDB Elasticsearch 两大阵营,可能会引起口水之争,仅代表个人经验之谈,非阵营之说,围绕两个话题展开:
• 为什么要从 MongoDB 迁移到 Elasticsearch?
• 如何从 MongoDB 迁移到 Elasticsearch?

现状背景

MongoDB 本身定位与关系型数据库竞争,但工作中几乎没有见到哪个项目会将核心业务系统的数据放在上面,依然选择传统的关系型数据库。

1.项目背景

公司所在物流速运行业,业务系统复杂且庞大,用户操作者很多,每日有大量业务数据产生,同时业务数据会有很多次流转状态变化,为了便于记录追踪分析,系统操作日志记录项目应运而生,考虑到原有的日均数据量,操作日志数据基于 MongoDB 存储。
操作日志记录系统需要记录两种数据,如下说明:

1)变更主数据,什么人在什么时间在系统哪个模块做了什么操作,数据编号是什么,操作跟踪编号是什么。

{
  "dataId": 1, 
  "traceId": "abc",        
  "moduleCode": "crm_01",           
  "operateTime": "2019-11-11 12:12:12", 
  "operationId": 100,
  "operationName": "张三",
  "departmentId": 1000,
  "departmentName": "客户部",
  "operationContent": "拜访客户。。。"
}

2)变更从数据,实际变更数据的变化前后,此类数据条数很多,一行数据多个字段变更就记录多条。

[
  {
    "dataId": 1,
    "traceId": "abc",
    "moduleCode": "crm_01",
    "operateTime": "2019-11-11 12:12:12",
    "operationId": 100,
    "operationName": "张三",
    "departmentId": 1000,
    "departmentName": "客户部",
    "operationContent": "拜访客户",
    
    "beforeValue": "20",
    "afterValue": "30",
    "columnName": "customerType"
  },
  {
    "dataId": 1,
    "traceId": "abc",
    "moduleCode": "crm_01",
    "operateTime": "2019-11-11 12:12:12",
    "operationId": 100,
    "operationName": "张三",
    "departmentId": 1000,
    "departmentName": "客户部",
    "operationContent": "拜访客户",
    
    "beforeValue": "2019-11-02",
    "afterValue": "2019-11-10",
    "columnName": "lastVisitDate"
  }
]

2.项目架构

项目架构描述如下:

1、业务系统新增或者编辑数据,产生操作日志记录发送到Kafka集群,基于dataid字段作为key;
2、新增或编辑数据实际存储到MySQL数据库;
3、canal集群订阅MySQL集群,按照业务系统模块配置监控的数据库与表;
4、canal将监控到的变更业务数据发送到Kafka集群,基于dataid字段作为key;
5、操作日志系统从Kafka获取主记录数据与从记录数据;
6、操作日志系统写入数据到MongoDB,同时需要反查询。

image.png


图示:操作日志记录业务流程说明

Mongo DB架构

集群架构说明:

1)服务器配置8c/32gb/500gb ssd;
2)Router路由服务器部署了3个节点;
3)Config配置服务器部署了3个节点;
4)Shard分片服务器部署了9个节点;
5)主操作记录设计3个分片;
6)从操作记录设计3个分片。

image.png

问题说明

MongoDB的信徒们可能怀疑我们没有使用好,或者我们的运维能力欠缺,或者认为我们有Elasticsearch的高手在。不是这样的,弃用MongoDB选择Elasticsearch其实并非技术偏见问题,而是我们的实际场景需求,原因如下:

1.搜索查询

1)MongoDB内部采用B-Tree作为索引结构,此索引基于最左优先原则,且必须保证查询顺序与索引字段的顺序一致才有效,这个即是优点,但在现在复杂业务场景也是致命的;

2)业务系统查询操作日志记录会有很多过滤条件,且查询条件是任意组合的,现有MongoDB是不支持的,或者说所有关系型数据库都不支持,如果要支持,得创建好多组合的B+数索引,想法很不理智。

3)同时主记录与从记录中有很多字符类的数据,这些数据查询即要支持精确查询,也要支持全文检索,这几个方面MongoDB功能很单一,性能也很糟糕,业务系统查询时经常超时,反倒是Elasticsearch非常合适。

2.技术栈成熟度

1)分片与副本实现问题,MongoDB集合数据在设计时是需要绑定到具体的机器实例的,哪些分片分布在哪些节点上,哪些副本分布在哪些节点上,这些都需要在配置集群时就要绑定死,跟传统的关系型数据库做分库分表本质上没有什么两样,其实现在很多数据产品的集群还是这种模式偏多,比如Redis-cluster,ClickHouse等。而Elasticsearc的集群与分片和副本没有直接的绑定关系,可以任意的平衡调整,且节点的性能配置也可以很容易差异化;

2)操作日志数据量增加很快,单日写入超过千万条,不用多久,运维人员就需要对服务器进行扩容,且相对Elasticsearch复杂很多;

3)MongoDB单集合数据量超过10亿条,此情况下即使简单条件查询性能也不理想,不如Elasticsearch倒排索引快;

4)公司对于ES与MongoDB技术栈的经验积累不同,Elasticsearc在很多项目中运用,非常核心的项目也是大量运用,对于其技术与运维经验更丰富,而MongoDB如果除去核心业务场景,几乎找不到合适的切入口,实际没有人敢在核心项目中使用MongoDB,这就很尴尬。

3. 文档格式相同

MongoDB与Elasticsearch都属于文档型数据库 ,Bson类同与Json,_objectid与_id原理一样,所以主数据与从数据迁移到Elasticsearch平台,数据模型几乎无需变化。

迁移方案

异构数据系统迁移,主要围绕这两大块内容展开:

1)上层应用系统迁移,原来是针对MongoDB的语法规则,现在要修改为面向Elasticsearch语法规则;
2)下层MongoDB数据迁移到Elasticsearch。

1. Elastic 容量评估

原有MongoDB集群采用了15台服务器,其中9台是数据服务器,迁移到Elastic集群需要多少台服务器?我们采取简单推算办法,如假设生产环境上某个MongoDB集合的数据有10亿条数据, 我们先在测试环境上从MongoDB到ES上同步100万条数据,假设这100万条数据占用磁盘10G,那生产上环境上需要1个T磁盘空间,然后根据业务预期增加量扩展一定冗余。根据初步评估,Elastic集群设置3台服务器, 配置8c/16g内存/2T机械磁盘。服务器数量一下从15台缩减到3台,且配置也降低不少。

2.Elastic 索引规则

系统操作日志是时序性数据,写完整后基本上无需再次修改。操作日志记录查询主要是当月的居多,后续的历史性数据查询频率很低,根据评估,核心数据索引按月创建生成, 业务查询时候必须带上操作时间范围,后端根据时间反推需要查询哪些索引,Elastic-Api支持多索引匹配查询,完美利用Elastic的特性解决跨多个月份的查询合并。对于非核心数据索引,按年创建索引生成足以。

image.png

3.核心实现逻辑设计

Elasticsearch不是关系型数据库,不具备事务的机制。操作日志系统的数据来源都是Kafka,消费数据是有顺序机制的,有2种场景特别注意,如下:

• 主数据先到操作日志系统,从数据后到,从数据写的时候先拼凑主数据记录和Binlog字段数据;
• 从数据先到操作日志系统,主数据后到,主数据更新从索引的相关的索引字段。

Elasticsearch索引数据更新是近实时的刷新机制,数据提交后不能马上通过Search-Api查询到,主记录的数据如何更新到从记录呢?而且业务部门不规范的使用,多条主记录的dataId和tracId可能一样。

由于主数据与从数据关联字段是dataId和traceId。如果主数据与从数据在同时达到操作日志系统,基于update_by_query 命令肯定失效不 准确, 主从数据也可能是多对多的关联关系,dataId 和traceId不能唯一决定一条记录。

Elasticsearch其实也是一个NoSQL数据库, 可以做key-value缓存。这时新建一个Elastic索引作为中间缓存, 原则是主数据与从数据谁先到缓存谁,索引的 _id=(dataId+traceId) , 通过这个中间索引可以找到主数据记录的Id或者从记录Id, 索引数据模型多如下,detailId为从索引的_id的数组记录。

{
  "dataId": 1,
  "traceId": "abc",
  "moduleCode": "crm_01",
  "operationId": 100,
  "operationName": "张三",
  "departmentId": 1000,
  "departmentName": "客户部",
  "operationContent": "拜访客户",
  "detailId": [
    1,
    2,
    3,
    4,
    5,
    6
  ]
}

前面我们讲过主记录和从记录都是一个Kafka的分区上,我们拉一批数据的时候,操作ES用的用到的核心API:

#批量获取从索引的记录
_mget 
#批量插入
bulk
#批量删除中间临时索引
_delete_by_query 

迁移过程

1.数据迁移

选择DataX作为数据同步工具由以下几个因素:

• 历史型数据。操作日志记录数据属于历史性的数据,记录产生之后几乎无需二次修改,等同于离线数据;
• 非持续性迁移。项目全部完工之后,原有的MongoDB集群会全部销毁,不会有二次迁移需求;
• 数据量问题。原有MongoDB操作日志数据量有几十亿条,迁移过程不能太快也不能太慢,速度太快,MongoDB集群会出现性能问题,速度太慢,项目周期太长,增加运维的成本与复杂度。否则可以选择Hadoop作为中转平台的迁移;
• DataX源码特定场景改造。如日期类型的转换、索引主键_id的生成、索引主键_id映射,支持重复同步;
• 多实例多线程并行。主数据同步部署多个实例,从数据同步也部署多个实例,单实例中配置多个Channel。

image.png

2.迁移索引设置

临时修改索引的一些设置,当数据同步完之后再修改回来,如下:

  "index.number_of_replicas": 0,
  "index.refresh_interval": "30s",
  "index.translog.flush_threshold_size": "1024M"
  "index.translog.durability": "async",
  "index.translog.sync_interval": "5s"

3.应用迁移

操作日志项目采用Springboot构建,增加了自定义配置项,如下:

#应用写入mongodb标识
writeflag.mongodb: true
#应用写入elasticsearch标识
writeflag.elasticsearch: true

项目改造说明:
• 第一次上线的时候,先将2个写入标识设置为true,双写MongoDB和ES;
• 对于读,提供2个不同接口,前端自由的切换;
• 等数据迁移完,没有差异的时候,重新更改flag的值。

image.png

结语

1.迁移效果

弃用MongoDB使用ElasticSearch作为存储数据库,服务器从原来的15台MongoDB,变成了3台ElasticSearch,每月为公司节约了一大笔费用。同时查询性能提高了10倍以上,而且更好的支持了各种查询,得到了业务部门的使用者,运维团队和领导的一致赞赏。

2.经验总结

整个项目前后历经几个月,多位同事参与,设计、研发,数据迁移、测试、数据验证、压测等各个环节。技术方案不是一步到位,中间也踩了很多坑,最终上线了。ES的技术优秀特点很多,灵活的使用,才能发挥最大的威力。

声明:本文由原文作者“李猛”授权转载,对未经许可擅自使用者,保留追究其法律责任的权利。


image.png

阿里云Elastic Stack】100%兼容开源ES,独有9大能力,提供免费X-pack服务(单节点价值$6000)

相关活动


更多折扣活动,请访问阿里云 Elasticsearch 官网

阿里云 Elasticsearch 商业通用版,1核2G ,SSD 20G首月免费
阿里云 Logstash 2核4G首月免费


image.png

image.png

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
24天前
|
SQL NoSQL Java
springboot操作nosql的mongodb,或者是如何在mongodb官网创建服务器并进行操作
本文介绍了如何在Spring Boot中操作NoSQL数据库MongoDB,包括在MongoDB官网创建服务器、配置Spring Boot项目、创建实体类、仓库类、服务类和控制器类,以及如何进行测试。
16 1
springboot操作nosql的mongodb,或者是如何在mongodb官网创建服务器并进行操作
|
19天前
|
SQL 分布式计算 NoSQL
大数据-170 Elasticsearch 云服务器三节点集群搭建 测试运行
大数据-170 Elasticsearch 云服务器三节点集群搭建 测试运行
33 4
|
18天前
|
NoSQL MongoDB 数据库
使用NimoShake将数据从AWS DynamoDB迁移至阿里云MongoDB
使用NimoShake将数据从AWS DynamoDB迁移至阿里云MongoDB
|
19天前
|
SQL 分布式计算 大数据
大数据-168 Elasticsearch 单机云服务器部署运行 详细流程
大数据-168 Elasticsearch 单机云服务器部署运行 详细流程
40 2
|
3月前
|
JSON NoSQL Ubuntu
在Ubuntu 14.04上如何备份、恢复和迁移MongoDB数据库
在Ubuntu 14.04上如何备份、恢复和迁移MongoDB数据库
76 1
|
3月前
|
NoSQL MongoDB 数据库
DTS 的惊天挑战:迁移海量 MongoDB 数据时,捍卫数据准确完整的生死之战!
【8月更文挑战第7天】在数字化时代,大数据量的MongoDB迁移至关重要。DTS(数据传输服务)通过全面的数据评估、可靠的传输机制(如事务保证一致性)、异常处理(如回滚或重试),以及迁移后的数据校验来确保数据准确无损。DTS还处理数据转换与映射,即使面对不同数据库结构也能保持数据完整性,为企业提供可靠的数据迁移解决方案。
60 2
|
4月前
|
DataWorks NoSQL fastjson
DataWorks操作报错合集之DataX进行MongoDB全量迁移的过程中,DataX的MongoDB Reader插件在初始化阶段找不到Fastjson 2.x版本的类库,该怎么办
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
4月前
|
存储 NoSQL 关系型数据库
MongoDB的配置服务器和复制机制
【7月更文挑战第2天】MongoDB配置服务器存储分片和权限元数据,支持在主节点故障时保持读服务。关键组件,性能影响显著。复制集包含Primary和Secondary,通过oplog实现数据同步,类似MySQL binlog。oplog的幂等性可能导致大量set操作,且大小受限,可能导致从节点需全量同步。读写分离提升效率,主从切换确保高可用。
47 0
|
5月前
|
存储 数据采集 NoSQL
DTS在迁移大数据量的MongoDB数据库时如何保证数据的准确性和完整性?
【6月更文挑战第4天】DTS在迁移大数据量的MongoDB数据库时如何保证数据的准确性和完整性?
137 1
|
6月前
|
监控 API 索引
实战问题:Elasticsearch 2.X 数据如何迁移到 7.X?
实战问题:Elasticsearch 2.X 数据如何迁移到 7.X?
41 0

相关产品

  • 检索分析服务 Elasticsearch版