当前位置: 首页 > 科技观察

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

时间:2023-03-14 18:00:48 科技观察

从MongoDB迁移到ES后,我们减少了80%的服务器数量。接触Elasticsearch,在Elastic-Stack开发、架构、运维等方面有深入的体会,实践过各种Elasticsearch项目,最暴力的大数据分析应用,最复杂的业务系统应用;业余时间为企业提供Elastic-stack咨询培训和调优实施。前言图:MongoDB和Elasticsearch热度排行本文涉及MongoDB和Elasticsearch两大阵营,可能引起口水之争。仅代表个人经历,不代表阵营。它围绕两个主题展开:为什么要从MongoDB迁移到Elasticsearch?如何从MongoDB迁移到Elasticsearch?现状背景MongoDB本身的定位是和关系型数据库竞争,但是在工作中,几乎没有项目会把核心业务系统的数据放在上面,依然选择传统的关系型数据库。一、项目背景公司属于物流快递行业。业务系统复杂庞大。用户运营商众多。每天都会产生大量的业务数据。同时,业务数据会发生多次变化。唱片项目应运而生。考虑到原有日均数据量,操作日志数据基于MongoDB存储。操作日志记录系统需要记录两种数据,如下:1)更改主数据,谁在什么时间在系统的哪个模块做了什么操作,数据号是多少,操作跟踪号是多少.{"dataId":1,"traceId":"abc","moduleCode":"crm_01","operateTime":"2019-11-1112:12:12","operationId":100,"operationName":"zhangsan","departmentId":1000,"departmentName":"客户部","operationContent":"拜访客户..."}2)更改slave数据,实际更改数据前后,有很多这样的数据items,当一行数据的多个字段发生变化时,会记录多条记录。[{"dataId":1,"traceId":"abc","moduleCode":"crm_01","operateTime":"2019-11-1112: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-1112:12:12","operationId":100,"operationName":"张三","departmentId":1000,"departmentName":"客户部","operationContent":"拜访客户","beforeValue":"2019-11-02","afterValue":"2019-11-10","columnName":"lastVisitDate"}]2.项目架构项目架构描述如下:业务系统添加或编辑数据,生成操作日志记录并发送到Kafka集群,以dataid字段为key;新增或编辑的数据实际存储在MySQL数据库中;canal集群订阅MySQL集群,根据业务系统模块配置监控的数据库和表;canal将监听到的业务变化数据发送到kafka集群,以dataid字段为key;操作日志系统从Kafka获取主记录数据和从记录数据;操作日志系统向MongoDB写入数据,同时需要反向查询图:操作日志记录业务流程说明3.MongoDB架构集群架构说明:服务器配置8c/32gb/500gbssd;Router路由服务器部署3个节点;config配置服务器部署了3个节点;Shard分片9个节点部署在服务器上;3个分片是为主要操作记录设计的;3个分片是为slave操作记录而设计的。问题说明,MongoDB的信徒可能会怀疑我们没有用好它,或者我们的运维能力欠缺,或者我们有Elasticsearch的高手。不,选择Elasticsearch而不是MongoDB其实并不是技术上的偏见,而是我们的实际场景需求。原因如下:1.B-Tree作为MongoDB内部的索引结构,用于搜索查询。该索引基于最左优先原则,必须保证查询顺序与索引字段的顺序一致才有效。这是优点,但在复杂的业务场景下也是致命的;业务系统查询操作日志记录会有很多过滤条件,查询条件可以任意组合。现有的MongoDB不支持,或者不是所有的关系型数据库都支持。如果要支持,就得创建很多组合的B+数索引。这个想法很不合理。我们已经在文章《DB与ES混合之应用系统场景分析探讨》中讨论过这个。记录中和记录中有很多字符数据。这些数据查询必须支持精确查询和全文搜索。在这些方面,MongoDB功能单一,性能较差。业务系统查询经常超时。Elasticsearch是一个完美的选择。2、技术栈成熟度分片和副本实现问题,MongoDB集合数据在设计时需要绑定到具体的机器实例,哪些分片分布在哪些节点上,哪些副本分布在哪些节点上,这些都需要在配置集群的时候,它必死无疑。分库分表,本质上和传统的关系型数据库是一样的。其实很多数据产品集群还是采用这种模式,比如Redis-cluster、ClickHouse等。Elasticsearch的集群与分片和副本没有直接的绑定关系,可以任意平衡和调整,节点的性能配置也可以易于区分;操作日志数据量激增,单日写入量超过1000万条,运维人员扩容服务器用不了多久,比Elasticsearch要复杂得多;MongoDB在单个集合中拥有超过10亿条数据。这种情况下,即使是简单的条件查询性能也不理想,不如Elasticsearch倒排索引快;公司对ES和MongoDB技术栈的经验积累是不一样的。Elasticsearch在很多项目中都有使用,非常核心的项目也被广泛使用。它在技术和运维方面有更多的经验。但是MongoDB如果去掉核心业务场景,几乎不可能找到合适的。切入点,没人敢在核心项目中使用MongoDB,尴尬。3.文件格式相同。MongoDB和Elasticsearch都是文档数据库。Bson和Json类似,_objectid和_id的原理是一样的。因此,将主数据和从数据迁移到Elasticsearch平台时,几乎不需要改变数据模型。迁移计划异构数据系统的迁移主要围绕两大方面进行:上层应用系统的迁移,原来是针对MongoDB的语法规则,现在修改为面向Elasticsearch的语法规则;将较低级别的MongoDB数据迁移到Elasticsearch。1.弹性容量评估原来的MongoDB集群使用了15台服务器,其中9台是数据服务器。迁移到Elastic集群需要多少台服务器?我们采用一种简单的计算方法,比如假设生产环境中一个MongoDB集合中有10台服务器。1亿条数据,我们先在测试环境将100万条数据从MongoDB同步到ES,假设100万条数据占用10G的磁盘,那么生产环境需要1T的磁盘空间,然后根据业务的预期增长进行扩展一定是多余的。根据初步评估,Elastic集群有3台服务器配置8c/16g内存/2T机械盘。服务器数量从15台减少到3台,配置也减少了很多。2、Elastic索引规则系统的运行日志是时序数据,写入后基本不需要修改。操作日志记录多为当月查询,后续历史数据查询频率很低。根据评估,核心数据指标按月创建和生成。业务查询中必须包含操作时间范围,后台根据时间计算需要查询哪些。Index,Elastic-Api支持多索引匹配查询,完美利用Elastic的特性解决跨月的查询合并。对于非核心数据索引,每年生成一次索引就足够了。图解:Elastic运行日志索引创建规则3.核心实现逻辑设计Elasticsearch不是关系型数据库,没有事务机制。操作日志系统的数据源为Kafka,消费数据具有时序机制。有两种场景需要特别注意,如下:主数据先到达操作日志系统,然后数据到达。写入数据时,首先组装主数据记录。以及Binlog字段数据;从数据先到运行日志系统,主数据后到,主数据从索引更新相关索引字段。Elasticsearch索引数据更新是一种近乎实时的刷新机制。数据提交后,无法立即通过Search-Api进行查询。如何将主记录的数据更新到从记录?而且业务部门使用不规范,多条主记录的dataId和tracId很可能是一样的。由于主数据和从数据的关联字段是dataId和traceId。如果主数据和从数据同时到达操作日志系统,那么update_by_query命令一定是无效的,不准确的。主从数据也可能是多对多的关系,dataId和traceId不能唯一确定一条记录。Elasticsearch实际上是一个NoSQL数据库,可以用于key-value缓存。这个时候新建一个Elasticindex作为中间缓存。原理是主数据和次数据先缓存,索引的_id=(dataId+traceId)。通过这个中间索引,可以找到主数据记录的Id或者从数据记录的Id。索引数据模型大体如下,detailId是索引的_id的数组记录。{"dataId":1,"traceId":"abc","moduleCode":"crm_01","operationId":100,"operationName":"张三","departmentId":1000,"departmentName":"CustomerDepartment","operationContent":"Visitingcustomers","detailId":[1,2,3,4,5,6]}我们前面说过,主记录和从记录都在一个Kafka分区上。拉取一个批处理数据时,操作ES的核心API:#批量从索引中获取记录_mget#批量插入批量#批量删除中间临时索引_delete_by_query迁移过程1.选择DataX作为数据同步工具,通过以下方式进行数据迁移几个因素:历史数据。操作日志记录数据为历史数据,记录生成后几乎不需要二次修改,相当于离线数据;非持久性迁移。项目全部完成后,原有MongoDB集群将彻底销毁,无需二次迁移;数据量问题。原始的MongoDB操作日志有数十亿条数据。迁移过程不应太快或太慢。如果速度太快,MongoDB集群就会出现性能问题。速度太慢,项目周期太长,会增加运维的成本和复杂度。花费。否则,可以选择Hadoop作为迁移的过渡平台;针对特定场景的DataX源码改造。如日期类型转换,索引主键_id生成,索引主键_id映射,支持重复同步;多实例多线程并行。主数据同步部署多实例,从数据同步也部署多实例,单实例配置多个Channel。图:DataX同步数据图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搭建,添加自定义配置项,如下:#Applicationwritesmongodbflagwriteflag.mongodb:true#Applicationwriteselasticsearchflagwriteflag.elasticsearch:true项目改造说明:第一次上线时,先将两个writeflag设置为true,双写MongoDB和ES;对于阅读,提供两种不同的接口,前端可以自由切换;当数据迁移完成,没有差异时,再次更改flag的值。图:ApplicationBalance迁移结论1.迁移效果放弃MongoDB,使用ElasticSearch作为存储数据库。服务器从15个MongoDB变成了3个ElasticSearch,每个月为公司节省了很多钱。同时,查询性能提升10倍以上,更好地支持各种查询,得到了业务部用户、运维团队和领导的一致好评。2.经验总结整个项目前后历时几个月,很多同事参与了设计、研发、数据迁移、测试、数据验证、压力测试等环节。技术方案一步不到位,中间坑了很多,最后还是上马了。ES有很多优秀的技术特性,只有灵活运用才能发挥出最大的威力。从过去40年到现在,数据库的形态基本经历了传统商业数据库、开源数据库、云原生数据库的演变过程。数据库在云时代将如何创新和变革?金融行业核心数据库迁移建设如何安全顺利进行?来Gdevops全球敏捷运维峰会北京站寻找答案:《All in Cloud 时代,下一代云原生数据库技术与趋势》阿里巴巴集团副总裁/达摩院首席数据库科学家李飞飞(飞刀)《AI和云原生时代的数据库进化之路》腾讯数据库产品中心总经理林晓斌(丁奇)《ICBC的MySQL探索之路》工行软件开发中心魏亚东《金融行业MySQL高可用实践》Ecoson技术总监明熙元《民生银行在SQL审核方面的探索和实践》民生银行高级数据库专家李宁宁《OceanBase分布式数据库在西安银行的落地和实践》蚂蚁金服P9高级专家/OceanBase核心总监姜志勇作者介绍李萌(ynuosoft),Elastic-stack产品深度用户,ES认证工程师,2012年接触Elasticsearch,在Elastic-Stack开发、架构、运维等方面有深入的经验,实践过多种Elasticsearch项目,最暴力的大数据分析应用,最复杂的业务系统应用;业余为企业提供Elastic-stack咨询培训和调优实施。