imp 只导入索引_Elasticsearch系列---实战零停机重建索引
前言
我们使用Elasticsearch索引文档时,最理想的情况是文档JSON结构是确定的,数据源源不断地灌进来即可,但实际情况中,没人能够阻拦需求的变更,在项目的某个版本,可能会对原有的文档结构造成冲击,增加新的字段还好,如果要修改原有的字段,只能重建索引了。
概要
本篇以实战方式讲解如何零停机完成索引重建的三种方案。
外部数据导入方案
整体介绍
系统架构设计中,有关系型数据库用来存储数据,Elasticsearch在系统架构里起到查询加速的作用,如果遇到索引重建的操作,待系统模块发布新版本后(若重建索引不是因为客户端修改导致的,可以不停机发版,直接操作),可以从数据库将数据查询出来,重新灌到Elasticsearch即可。
执行步骤
建议的功能方案:数据库 + MQ + 应用模块 + Elasticsearch,可以在MQ控制台发送MQ消息来触发重导数据,按批次对数据进行导入,整个过程异步化处理,请求操作示意如下所示:
详细操作步骤:
- 通过MQ的web控制台或cli命令行,发送指定的MQ消息
- MQ消息被微服务模块的消费者消费,触发ES数据重新导入功能
- 微服务模块从数据库里查询数据的总数及批次信息,并将每个数据批次的分页信息重新发送给MQ消息,分页信息包含查询条件和偏移量,此MQ消息还是会被微服务的MQ消息者接收处理。
- 微服务根据接收的查询条件和分页信息,从数据库获取到数据后,根据索引结构的定义,将数据组装成ES支持的JSON格式,并执行bulk命令,将数据发送给Elasticsearch集群。
这样就可以完成索引的重建工作。
方案特点
MQ中间件的选型不做具体要求,常见的rabitmq、activemq、rocketmq等均可。
在微服务模块方面,提供MQ消息处理接口、数据处理模块需要事先开发的,一般是创建新的索引时,配套把重建的功能也一起做好。整体功能共用一个topic,针对每个索引,有单独的结构定义和MQ消息处理tag,代码尽可能复用。处理的批次大小需要根据实际的情况设置。
微服务模块实例会部署多个,数据是分批处理的,批次信息会一次性全部先发送给MQ,各个实例处理的数据相互不重叠,利用MQ消息的异步处理机制,可以充分利用并发的优势,加快数据重建的速度。
方案缺点
- 对数据库造成读取压力,短时间内大量的读操作,会占用数据库的硬件资源,严重时可能引起数据库性能下降。
- 网络带宽占用多,数据毕竟是从一个库传到另一个库,虽说是内网,但大量的数据传输带宽占用也需要注意。
- 数据重建时间稍长,跟迁移的数据量大小有关。
基于scroll+bulk+索引别名方案
整体介绍
利用Elasticsearch自带的一些工具完成索引的重建工具,当然在方案实际落地时,可能也会依赖客户端的一些功能,比如用Java客户端持续的做scroll查询、bulk命令的封装等,但与上一方案相比,最明显的区别就是:数据完全自给自足,不依赖其他数据源。
执行步骤
假设原索引名称是music,新的索引名称为musicnew,Java客户端使用别名musicalias连接Elasticsearch,该别名指向原索引music。
- 若Java客户端没有使用别名,需要给客户端分配一个:
PUT /music/_alias/music_alias
- 新建索引music_new,将mapping信息,settings信息等按新的要求全部定义好。
- 使用scroll api将数据批量查询出来
GET /music/_search?scroll=1m
{"query": {"match_all": {}},"sort": ["_doc"],"size": 1000
}
- 采用bulk api将scoll查出来的一批数据,批量写入新索引
POST /_bulk
{ "index": { "_index": "music_new", "_type": "children", "_id": "1" }}
{ "name": "wake me, shake me" }
- 反复执行步骤3和步骤4,查询一批导入一批,可以借助Java Client或其他语言的API支持。
- 切换别名musicalias到新的索引musicnew上面,此时Java客户端仍然使用别名访问,也不需要修改任何代码,不需要停机。
POST /_aliases
{"actions": [{ "remove": { "index": "music", "alias": "music_alias" }},{ "add": { "index": "music_new", "alias": "music_alias" }}]
}
- 验证别名查询的是否为新索引的数据
方案特点
在数据传输上基本自给自足,不依赖于其他数据源,Java客户端不需要停机等待数据迁移,网络传输占用带宽较小。
只是scroll查询和bulk提交这部分,数据量大时需要依赖一些客户端工具。
补充一点
在Java客户端或其他客户端访问Elasticsearch集群时,使用别名是一个好习惯。
Reindex API方案
Elasticsearch v6.3.1已经支持Reindex API,它对scroll、bulk做了一层封装,能够 对文档重建索引而不需要任何插件或外部工具。
最基础的命令:
POST _reindex
{"source": {"index": "music"},"dest": {"index": "music_new"}
}
响应结果:
{"took": 180,"timed_out": false,"total": 4,"updated": 0,"created": 4,"deleted": 0,"batches": 1,"version_conflicts": 0,"noops": 0,"retries": {"bulk": 0,"search": 0},"throttled_millis": 0,"requests_per_second": -1,"throttled_until_millis": 0,"failures": []
}
注意:如果不手动创建新索引music_new的mapping信息,那么Elasticsearch将启动自动映射模板对数据进行类型映射,可能不是期望的类型,这点要注意一下。
version_type 属性
使用reindex api也是创建快照后再执行迁移的,这样目标索引的数据可能会与原索引有差异,version_type属性可以决定乐观锁并发处理的规则。
reindex api可以设置version_type属性,如下:
POST _reindex
{"source": {"index": "music"},"dest": {"index": "music_new""version_type": "internal"}
}
version_type属性含义如下:
- internal:直接拷贝文档到目标索引,对相同的type、文档ID直接进行覆盖,默认值
- external:迁移文档到目标索引时,保留version信息,对目标索引中不存在的文档进行创建,已存在的文档按version进行更新,遵循乐观锁机制。
op_type 属性和conflicts 属性
如果op_type设置为create,那么迁移时只在目标索引中创建ID不存在的文档,已存在的文档,会提示错误,如下请求:
POST _reindex
{"source": {"index": "music"},"dest": {"index": "music_new","op_type": "create"}
}
有错误提示的响应,节选部分:
{"took": 11,"timed_out": false,"total": 5,"updated": 0,"created": 1,"deleted": 0,"batches": 1,"version_conflicts": 4,"noops": 0,"retries": {"bulk": 0,"search": 0},"throttled_millis": 0,"requests_per_second": -1,"throttled_until_millis": 0,"failures": [{"index": "music_new","type": "children","id": "2","cause": {"type": "version_conflict_engine_exception","reason": "[children][2]: version conflict, document already exists (current version [17])","index_uuid": "dODetUbATTaRL-p8DAEzdA","shard": "2","index": "music_new"},"status": 409}]
}
如果加上"conflicts": "proceed"配置项,那么冲突信息将不展示,只展示冲突的文档数量,请求和响应结果将变成这样:
请求:
POST _reindex
{"conflicts": "proceed","source": {"index": "twitter"},"dest": {"index": "new_twitter","op_type": "create"}
}
响应:
{"took": 12,"timed_out": false,"total": 5,"updated": 0,"created": 1,"deleted": 0,"batches": 1,"version_conflicts": 4,"noops": 0,"retries": {"bulk": 0,"search": 0},"throttled_millis": 0,"requests_per_second": -1,"throttled_until_millis": 0,"failures": []
}
query支持
reindex api支持数据过滤、数据排序、size设置、_source选择等,也支持脚本执行,这里提供一个简单示例:
POST _reindex
{"size": 100, "source": {"index": "music","query": {"term": {"language": "english"}},"sort": {"likes": "desc"}},"dest": {"index": "music_new"}
}
小结
本篇介绍了零停机索引重建操作的三个方案,从自研功能、scroll+bulk到reindex,我们作为Elasticsearch的使用者,三个方案的参与度是逐渐弱化的,但稳定性却是逐渐上升的,我们需要清楚地去了解各个方案的优劣,适宜的场景,然后根据实际的情况去权衡,哪个方案更适合我们的业务模型,仅供参考,谢谢。
专注Java高并发、分布式架构,更多技术干货分享与心得,请关注公众号:Java架构社区
imp 只导入索引_Elasticsearch系列---实战零停机重建索引相关推荐
- imp 只导入索引_使用imp导入表和索引至不同表空间方法
在以前我的blog中,曾经记录过使用expdp/impdp方式将表和索引导入至不同表空间的方法,这里再提一下: 导出: expdp test/test directory=dump_dir dumpf ...
- elasticsearch 索引_Elasticsearch系列---索引管理
概要 Elasticsearch让索引创建变得非常简单,只要索引一条新的数据,索引会自动创建出来,但随着数据量的增加,我们开始有了索引优化和搜索优化的需求之后,就会发现自动创建的索引在某些方面不能非常 ...
- mysql索引_mysql系列:深入理解mysql 索引特性(屡试不爽的mysql索引总结)
原标题:mysql系列:深入理解mysql 索引特性(屡试不爽的mysql索引总结) mysql为什么使用B+ Tree索引,不使用B- Tree索引? 索引顺序如何生效? 什么是覆盖索引? orde ...
- Oracle索引梳理系列(四)- Oracle索引种类之位图索引
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- Oracle索引梳理系列(二)- Oracle索引种类及B树索引
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- Oracle索引梳理系列(五)- Oracle索引种类之表簇索引(cluster index)
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- Oracle索引梳理系列(六)- Oracle索引种类之函数索引
函数索引 1.1 概述 在实际应用中,当条件列使用函数运算进行数据匹配时,即使该列建立了索引,索引也不会被使用. 如下示例,其中在owner列上建立一个普通b-tree索引,观 察两种查询方式(不使用 ...
- ★Oracle imp/impdp 导入dmp文件到数据库
使用EXPDP和IMPDP时应该注意的事项: EXP和IMP是客户端工具程序,它们既可以在客户端使用,也可以在服务端使用. EXPDP和IMPDP是服务端的工具程序,他们只能在ORACL ...
- Elasticsearch 2.3.0 重建索引
2019独角兽企业重金招聘Python工程师标准>>> 重建索引是2.3.0新增加的接口.这个接口是实验性质的,在未来有可能会改变. 重建索引的最基本的功能是拷贝文件从一个索引到另一 ...
最新文章
- python的功能模块_Python的功能模块[1] - struct - struct 在网络编程中的使用
- oracle逻辑结构包含,在Oracle中,逻辑结构由哪几个部分组成?
- 服务器备份文件格式,证书服务器,备份,还原
- Towards Efficient Privacy-Preserving Inspection of TLS Encrypted Traffic
- 图片素材网站|找素材、提升审美力就靠它了!
- SDN期末作业——负载均衡
- Javascript——Math对象
- emq数据储存到mysql,规则引擎示例 - 保存数据到 MySQL - 《EMQ X Enterprise v4.0 中文文档》 - 书栈网 · BookStack...
- JqueryEasyUI $.Parser
- libyuv NV12裁剪
- Spring Boot 开发微信公众号后台
- 初中中考计算机考试,中考信息技术考试
- Delphi 读取注册表REG_MULTI_SZ类型,注意事项
- python平方上标怎么输出,plot绘图同样适用
- jQuery使用ajaxSubmit()提交表单示例(转)
- Web前端-Ajax(下)
- 顶会论文笔记:联邦学习——ATPFL: Automatic Trajectory Prediction Model Design under Federated Learning Framework
- 简单停车位管理系统(C语言版)
- 第一章Python概述
- 国内外数据安全治理框架介绍与分析
热门文章
- Java 蓝桥杯 算法 和为T
- Java 蓝桥杯 分解质因数
- scrapy导入配置文件setting.py,防止运行时找不到文件
- scrapy通过item类直接创建数据库中的数据表
- 解决python读取pickle报错ValueError: unsupported pickle protocol: 5
- pandas后台导出excel_pandas导出Excel表格,银行卡号、身份证号无法正常显示的问题,该怎么解决?...
- python两个基本的库管理工具_Python多版本共存管理工具之pyenv
- grafana官方使用文档_5. Centos7 下部署使用 nmon2influxdb
- oracle 9i standby,Oracle 9I dataguard(standby)
- java基础之-I/O流和File类解析