Elasticsearch 零停机索引维护的3种方案
前言
业务开发中诸如一些表的字段更改,增加字段,我们需要将表进行增加字段,删除字段,也可能会重新建表将数据重新放入另一张表等等重建表的一些操作,对此es中我们也需要进行数据更新,或者说数据同步操作。
那么es中我们如何操作呢?
常规的做法是新建index 然后重新将数据写到es中
可以使用java同步操作一遍读一遍写
也可以使用一些中间件mq异步写入es
也可以从es中查询出数据,然后写到es中,中间做一些数据或者类型的改变重新插入index中,这也是一种方案。
那么在es中是如何操作的呢?
es中提供了2中操作
- 使用es自带的scroll + bulk 索引别名方案
- 使用自带的Reindex方案
方案1
外部数据导入 如java客户客户端从mysql等查出数据插入到es中也可以借助中间件mq 异步导入
缺点: 占用数据库资源,占用带宽,索引重建的时间和db数据量大小有关
方案2
使用es自带的scroll + bulk 索引别名方案
使用 scroll 从es指定索引中查询数据,然后借助java客户端使用bulk批量插入,依次循环知道数据全部放入es中。
优点:不需要从db中查询,不会对db造成资源压力
具体步骤
指定别名
PUT /elasticsearch_test/_alias/elasticsearch_test_alias
创建Index
GET /es_new_scroll_bulk/
GET /es_new_scroll_bulk/_search
查询数据
scroll查询 1m表示1分钟 保持上下文环境搜索1分钟,一般1m够用了
POST /elasticsearch_test/_search?scroll=1m
{
"query":{
"match_all": {}
},
"sort":"_id",
"size":10
}
将上面查询出的数据,使用bulk批量插入es index
注意
:使用_bulk
插入数据数据必须保持一行,不能换行
GET /es_new_scroll_bulk/_search
POST _bulk
{"index":{"_index":"es_new_scroll_bulk","_id":1}}
{"doc":{"id":1,"price" : 5.6,"studymodel" : "201001","name" : "spring cloud实战","description" : "本课程主要从四个章节进行讲解: 1.微服务架构入门 .spring cloud 基础入门 3.实战Spring Boot 4.注册中心eureka。","timestamp" : "2021-09-19 16:33:09"}}
POST _bulk
{"index":{"_index":"es_new_scroll_bulk","_id":3}}
{"doc":{"id":2,"price" : 5.6,"studymodel" : "201002","name" : "spring cloud实战","description" : "本课程主要从四个章节进行讲解: 1.微服务架构入门 .spring cloud 基础入门 3.实战Spring Boot 4.注册中心eureka。","timestamp" : "2021-09-19 16:33:09"}}
根据上面查询的第一页 数据结果的scroll id 查询第二页
GET _search/scroll
{
"scroll":"1m",
"scroll_id":"FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFkR3Vll0Q1c0UkZHWllScDRDVndlZ1EAAAAAAAADDxZnYjRHblhUVFJCaXd6bklRWTV2OUdn"
}
依次重复
### 重复查询和插入步骤即可
4 替换索引
将新的index指定到 elasticsearch_test_alias 别名上,删除原先的index即可
POST _aliases
{
"actions": [
{
"add": {
"index": "es_new_scroll_bulk",
"alias": "elasticsearch_test_alias"
},
"remove": {
"index": "elasticsearch_test",
"alias": "elasticsearch_test_alias"
}
}
]
}
查询新建后的index
GET /es_new_scroll_bulk/_search
使用别名访问
GET /elasticsearch_test_alias/_search
方案3
使用自带的Reindex方案
版本6.3.1以及以后,对scroll + bulk做了一层封装,不需要数据源也不需要客户端
如果新的index不手头创建mapping信息 则会自动创建,可能会与原先的mapping存在差异
POST _reindex
{
"source": {
"index": "elasticsearch_test"
},
"dest": {
"index": "elasticsearch_test_new_reindex"
}
}
_reindex 支持版本信息version_type
internal : 默认值,直接拷贝到index 相同的ID,type都进行覆盖
external : 迁移到目标index,保留version版本信息,不存在的进行创建,存在的进行更新(遵循乐观锁机制)
POST _reindex
{
"source": {
"index": "elasticsearch_test"
},
"dest": {
"index": "elasticsearch_test_new_reindex",
"version_type": "external",
"op_type": "create"
},
"conflicts": "proceed"
}
“op_type”: “create” 设置为create时,表示对不存在的进行创建会提示报错。
“conflicts”: “proceed” 只展示冲突的数量。
query 迁移过滤信息
可以根据业务条件过滤查询
POST _reindex
{
"source": {
"index": "elasticsearch_test",
"query":{
"field": {
"name": {
"boost": 2
}
}
},"size": 1000,
"sort": {
"id": "desc"
}
},
"dest": {
"index": "elasticsearch_test_new_reindex",
"version_type": "external"
}
}
以上三种方案第三种相对于前两个比较简单稳定不需要其他各种第三方工具,第一二中比较灵活,但比较繁琐需要进行大量的工作,可以根据业务来选择。