Es重建索引是个比较麻烦的事情,过程繁琐且迁移数据的过程也很漫长,一下将介绍如何rebuild index
software | version |
---|---|
elasticsearch | 6.4.2 |
由于es 的mapping结构无法直接更改,所以如果需要修改mapping结构,则必须rebuild一个索引,利用alias机制将新建索引与老索引关联,然后做数据迁移
基本概念
- Es别名机制不再赘述,规定索引名为indexName-日期,如
test_index-190807
- 两个alias分别为
indexName
、indexName$
,其中indexName是每个索引都有的alias,用于提供read操作;indexName$用于提供write操作(即做到只write当前alias索引,其他alias索引均可提供read)
Alias规则如何确定,可根据实际业务需要确定
思路描述
例如indexName=
test_index-old
1.按新schema结构建立索引test_index-new
(新索引结构必须与旧的兼容,否则数据迁移会出问题)
2.暂停test_index-old
数据写入
3.移除test_index-old
的test_index$ alias;添加test_index-new
的test_index$ alias,然后恢复数据持续写入(目的是让当前写服务能迁移到新的索引,且alias的操作非常快/秒级,此过程几乎可以看做服务不中断)
此方法在数据迁移时会查出double的重复数据,想要线上业务完全不受影响,可以将当前 write/read 全部转到一个新的index,alias指向新索引;此时将旧索引当做静态数据,数据迁移完成后瞬间切换alias(即创建两个新索引,一个用于持续读写,另一个用于迁移数据)
4.test_index-old
数据迁移至 test_index-new
(此过程缓慢)
5.移除test_index-old
的test_index alias,添加test_index-new
的test_index alias
6.至此test_index-old
的数据已经 迁移到 test_index-new
,完成index的rebuild,可删除test_index-old
操作步骤
新建索引
通常用curl或者kibana devtools就可以实现,但是如果mappings、settings比较复杂建议用程序先获取old index info,再此基础上做改动,然后再新建;此步骤必须保证新索引结构可以完全兼容旧索引
1 | // 通过java rest client |
迁移index$ Write Alias
此操作前必须停止索引写入
1 | // 移除Alias |
1 | // 添加Alias |
执行结束后开启写索引
数据迁移
1 | POST _reindex?wait_for_completion=false |
此命令会返回taskId,可根据Id查询运行状态
1 | GET _tasks/{taskId} |
中途遇到什么问题可以终止task
1 | PUT _tasks/{taskID}/cancel |
迁移index Read Alias
1 | // 添加Alias |
1 | // 移除Alias |
此时
test_index-old
已经被重建为test_index-new
调优
Elasticsearch 的数据迁移过程十分缓慢,通过以下方法可以进行调优(实测:3个Es nodes,30G+数据,60m+ Docs,Task需要30—40min左右结束)
1.source中调整batch_size(defailt: 1000)
批量大小取决于数据、分析和集群配置,但一个好的起点是每批处理5-15MB
1 | "source": { |
2.slicing 配置
1 | POST _reindex?slices=5&refresh |
【slices大小设置注意事项】
- slices大小的设置可以手动指定,或者设置slices设置为auto,auto的含义是:针对单索引,slices大小=分片数;针对多索引,slices=分片的最小值
- 当slices的数量等于索引中的分片数量时,查询性能最高效。slices大小大于分片数,非但不会提升效率,反而会增加开销
- 如果这个slices数字很大(例如500),建议选择一个较低的数字,因为过大的slices 会影响性能
3.关闭刷新和副本
在数据迁移过程中关闭refresh_interval、number_of_replicas可以大幅提升性能,迁移完成后恢复默认值
1 | PUT indexName/_settings |
转载请注明出处:https://github.com/imperio-wxm