在ElasticSearch Server一书中,我们探讨了如何强制改变分片的分配方式,如何取消、如何使用一条API命令在集群中转移分片。然而在谈论到分片分配时,ElasticSearch允许我们做的不止如此,我们还可以定义以系列用于分片分配的规则。例如,假定一个4-节点的集群,图示如下:
cluster.routing.allocation.awareness.attributes:group
这条配置命令用来通知Elasticsearh使用node.group属性作为集群的awareness参数。
设置cluster.routing.allocation.awareness.attributes属性的参数时,可以指定多个值。比如: cluster.routing.allocation.awareness.attributes:group,node
参数设置好以后,我们先启动两个节点,两个节点的node.group值都是groupA,并且用如下的命令创建索引:
curl -XPOST 'localhost:9200/mastering' -d '{
"settings" : {
"index" : {
"number_of_shards" : 2,
"number_of_replicas" : 1
}
}
}'
这个命令执行后,我们的2-节点集群看起来或多或少地类似于下面的图形:
注意两者的不同点:主分片并没有从原来分配的节点中移出,反而是分片副本移动到了node.grooup值不同的节点中,这正是我们所希望的结果。在集群中使用了shard allocation awareness功能后,ElasticSearch不会把决定allocation awareness的属性(在本例中是node.group值)相同的分片或者分片副本分配到同一个节点中。该功能典型的用例是把集群拓扑结构部署到物理机或者虚拟机时,确保你的集群不会出现单点故障问题。
请记住在使用allocation awareness功能时,分片不会被分配到没有设置相应属性的节点上。所在在我们的案例中,分片分配机制不会考虑分配分片到没有设置node.group属性的节点。
(文本的描述不并清晰,参考http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/modules-cluster.html,一看就懂) 当我们事先知道awareness属性的取值范围并且不希望集群中有过多的分片副本时,使用forcing allocation awareness机制会很方便。比如,不希望集群中负载了过多的分片副本,我们可以强制allocation awareness只在有确定参数值时起作用。我们可以指定cluster.routing.allocation.awareness.force.zone.values属性的值,这是一个多值属性,多个值可以用逗号区分开来。比如,如果我们希望allocation awareness只在node.group属性的值为groupA和groupB生效时,我们可以在elasticsearch.yml文件中加入如下的代码:
cluster.routing.allocation.awareness.attributes: group
cluster.routing.allocation.awareness.force.zone.values: groupA, groupB
ElasticSearch允许用户从整个集群或者索引的层面上配置allocation机制。在集群层面上配置allocation机制时,我们可以用如下的属性前缀:
cluster.routing.allocation.include.\_ip:192.168.2.1如果我们希望把group属性值为groupA的节点包括进来,我们可以设置如下的属性:
cluster.routing.allocation.include.group:groupA注意我们使用cluster.routing.allocation.include属性的方式是以它为前缀并和其它属性的名字串联起来,在本例中是group属性。
如果读者仔细观察了前面提到的参数,应该能注意到它们分为三种:
属性值可以使用简单的正则表达式。比如,如果我们包含所有group属性中属性值以字符串group开头的结点,可以设置cluster.routing.allocation.include.group的值为group*。在我们的样例集群中,它会匹配到group参数值为groupA和groupB的节点。
除了可以在elasticsearch.yml文件中设置前面讨论的属性,当集群在线时,我们也可以通过update API来实时更新这些参数。
如果想更新给定索引(比如例子中的mastering索引)的配置信息,我们就要运行运行如下的命令:
curl -XPUT 'localhost:9200/mastering/_settings' -d '{
"index.routing.allocation.require.group": "groupA"
}'
正如你所看到的,命令被发送到给定索引的_settings端点。在一条命令中可以包含多个属性。
curl -XPUT 'localhost:9200/_cluster/settings' -d '{
"transient" : {
"cluster.routing.allocation.require.group": "groupA"
}
}'
正如你所看到的,命令被发送到_cluster_settings端点。在一条命令中可以包含多个属性。请记住上面命令中transient关键字,它表示设置的属性在集群重启后就不再生效。如果希望设置的属性永久生效,用persistent属性代替transient属性就可以了。下面的命令示例将会使用用户设置在系统重启后依然生效:
curl -XPUT 'localhost:9200/_cluster/settings' -d '{
"persistent" : {
"cluster.routing.allocation.require.group": "groupA"
}
}'
请注意,在相应的结节上运行上面的命令时,会导致分片在节点间的移动。
index.routing.allocation.total\_shards\_per\_node:4
这个属性规定了每个节点中,单个索引最多允许分配4个分片。这个属性也可以通过update API在线上实时修改:
curl -XPUT 'localhost:9200/mastering/_settings' -d '{
"index.routing.allocation.total_shards_per_node": "4"
}'
现在,让我们看看在elasticsearch.yml文件中配置了allocation的相关属性后,几个单索引集群会变成什么样。
curl -XPOST 'localhost:9200/mastering' -d '{
"settings" : {
"index" : {
"number_of_shards" : 2,
"number_of_replicas" : 0
}
}
}'
创建索引后,试着执行如下的命令:
curl -XPUT 'localhost:9200/mastering/_settings' -d '{
"index.routing.allocation.include.tag": "node1",
"index.routing.allocation.include.group": "groupA",
"index.routing.allocation.total_shards_per_node": 1
}'
如果让索引状态可视化,那么集群看起来应该跟下面的图差不多.
正如你所看见的,Mastering索引的分片只分配到了tag属性值为node1或者group属性值为groupA的节点。
现在对我们的示例集群再回收利用(假定集群中已经没有任何索引存在)。我们再一次用如下的命令创建一个mastering索引:
curl -XPOST 'localhost:9200/mastering' -d '{
"settings" : {
"index" : {
"number_of_shards" : 2,
"number_of_replicas" : 0
}
}
}'
随后,试着执行下面命令:
curl -XPUT 'localhost:9200/mastering/_settings' -d '{
"index.routing.allocation.require.tag": "node1",
"index.routing.allocation.require.group": "groupA"
}'
如果让索引状态可视化,那么集应该跟如下图所示:
我们可以看到图示跟使用include属性有些不同。这是因为我们告诉ElasticSearch把Mastering索引的分片只分配到满足require参数所有设定值的节点上,在本例中只有第一个节点满足条件。
我们再一次使用示例集群,并且用如下的命令创建mastering索引:
curl -XPOST 'localhost:9200/mastering' -d '{
"settings" : {
"index" : {
"number_of_shards" : 2,
"number_of_replicas" : 0
}
}
}'
随后,试着执行下面的命令来测试allocation exclusion属性:
curl -XPUT 'localhost:9200/mastering/_settings' -d '{
"index.routing.allocation.exclude.tag": "node1",
"index.routing.allocation.require.group": "groupA"
}'
接下来,查看集群中各个节点的状态:
正如所见的那样,我们需要group属性值为groupA,但同时我们又要排除tag属性中值为node1的节点。这导致Mastering索引的分片被分配到了IP地址为192.168.2.2的节点上,这也是我们所希望的。
除了前面提到的那些属性,在配置shard allocation时,ElasticSearch还提供了其它的几个特性。下面我们一起来了解一下这些属性,看看集群中还有哪些是我们可以控制的