Fork me on GitHub

Elasticsearch 缩减索引Shards

当对一个Index的Shards分配过多,原本数据量没有这么大造成资源浪费时。通过Shrink操作可以减少Index的Shards,以下将介绍如何shrink index

software version
elasticsearch 6.4.2

通常Shrink索引的目的是由于建立索引时对数据量预估不足,指定的shards过多真实数据量很小,导致资源浪费

基本概念

  1. 缩小索引是指将原索引分片数缩小到一定数量,但缩小的数量必须为原数量的因子(即原分片数量是新分片倍数),例如8个分片可以缩小到4、2、1个分片,如果原分片数量为素数则只能缩小到一个分片。在缩小开始时,每个分片的复制都必须在同一节点(node)存在

  2. 首先,以相同配置创建目标索引,但是主分片数量减少。然后硬链接( hard-linking ) 各部分自原索引到目标索引。(如果系统不支持硬链接,那么索引的所有部分都将复制迁移到新索引,将会花费大量时间)最终,将会恢复目标索引,因为目标索引刚被重新打开就会被关闭

  3. 为了缩小索引,索引必须被标记为只读,所有分片都会复制到一个相同的节点并且节点健康为绿色

步骤

1.将索引设置为只读模式

1
2
3
4
5
6
7
PUT /wxm_character_login_glog_two-190801/_settings
{
"settings": {
"index.routing.allocation.require._name": "your-host-name",
"index.blocks.write": true
}
}

2.并且将保证your-host-name中有所有不同分片的其中一份

如何理解所有不同分片的其中一份,例如es 有3个节点 n1、n2、n3,原始index有5个主分片,每个主分片各自有一个副本,在节点中的分布可能是这样的

1
2
3
n1(pr1,pr2,re3,re4)
n2(re1,re2,pr5)
n3(re5,pr4,pr3)

设置"index.routing.allocation.require._name": "n3",则会将(pr1、re1中一个)(pr2、re2中一个)(pr3、re3中一个)移动到n3节点上,变成如下:

1
2
3
n1(pr2,re3,re4)
n2(re1,pr5)
n3(re5,pr4,pr1,re2,pr3)

这个过程需要点时间,因为要迁移shards,可以通过_cat/recovery?v&h=i,s,t,ty,st,rep,snap,f,fp,b,bp 命令,过滤出st = index的表示正在recover的index查看进度

3.当所有recover完成后,执行如下命令进行真正的索引shrink

1
2
3
4
5
6
7
8
9
10
11
POST wxm_character_login_glog_two-190801/_shrink/wxm_character_login_glog_two-190803
{
"settings": {
"index.number_of_replicas": 1,
"index.number_of_shards": 1,
"index.codec": "best_compression"
},
"aliases": {
"wxm_character_login_glog_two": {}
}
}

也可以通过_cat/recovery?v&h=i,s,t,ty,st,rep,snap,f,fp,b,bp 查看进程

此过程会新建一个wxm_character_login_glog_two-190803的索引,然后把source index 的数据同步过去

完成后wxm_character_login_glog_two-190801 便可删除

但是发现一个问题,shrink之后doc number不会变,数据量也正确,但是index 的size 增大了,即使用了best_compression(不适用此参数默认是LZO压缩)也比之前大一些,这个问题提了一个Issue 到 Elasticsearch Discuss:

Index size increased after shrink

Shrink 的一些限制:

  • 目标索引不允许存在,即要Shrink到的那个索引不存在

  • 源索引必须具有比目标索引更多的主分片

  • 目标索引中的主分片数必须是源索引中主分片数的一个因子,源索引必须具有比目标索引更多的主分片,如果原索引的主分片是质数,无法因式分解,则shrink主分片只能是1

  • 源索引的所有分片中的文档总数不得超过2147483519个,这些分片将收缩到目标索引上的单个分片中,这是可以放入单个分片的最大文档数

  • 处理收缩过程的节点必须具有足够的可用磁盘空间,新建的shrink索引

  • Shrink API和 Create index API一样,可以有setting和aliases参数,所以可以为目标索引添加一些配置


转载请注明出处:https://github.com/imperio-wxm


Thank you for your support.