暂时先忘记分片分配以及分配方式,ElasticSearch不仅提供了关于分片和分片副本各式各样的设置方式,同时也提供了指定查询命令(还有其它的操作,比如real time get)执行位置的功能。在详细了解该功能之前,先看看样例集群:
通过上图可以看到,样例集群有3个节点和一个名称为Mastering的索引。索引拆分成两个主分片,每个分片都有一个分片副本。
preference参数简介
为控制客户端发送的查询(及其它操作)命令在集群中执行的位置,我们用到了preference参数,该参数可指定如下的值:
- \_primary: 使用该属性值,发送到集群的相关操作请求只会在主分片上执行。如果发送查询命令到mastering索引时附带了值为\_primary的preference参数,该命令将只在名字为node1和node2的节点上执行。比如,如果用户集群的主分片在一个机架中,分片副本在另一个机架中,用户就可能希望命令只在主分片中执行以避免使用网络流量。
- \_primary\_first:该属性值与\_primary属性值导致相似的集群行为,但是具有容错机制。如果发送查询命令到mastering索引时附带了值为\_primary\_first的preference参数,该命令将在名称为node1和node2的节点上执行,但是如果有一个(或者更多)的主分片失效,查询命令将转到其它的分片上执行,在本例中会转到node3上执行。正如我们所说,该属性值与\_primary属性值相似,但是如果由于某些原因主分片失效了,那么命令就会回转到分片副本上执行。
- \_local: ElasticSearch会优先在本地的节点上执行相关操作。比如,如果我们向node3发送附带一条preference参数值为\_local的查询命令,最终该查询命令会在node3上执行。但是,如果我们把相同的命令发送到node2节点,那么最终该命令不仅会在编号为1的分片(分片位于本地节点)上执行,同时也会分发到node1或者node3上执行,这两个节点上有编号为0的分片。该属性值在减小网络传输时间上特别有用。只要用到了\_local preference参数值,我们就能确保查询命令会尽可能地在本地的节点上执行。(比如,从本地节点运行一个客户端连接或者发送一个查询命令到节点上)
- \_only\_node:wJq0kPSHTHCovjuCsVK0-A:这类的操作只会在指定标识(本例中是wJq0kPSHTHCovjuCsVK0-A)的节点上执行。所以在本例中,查询命令只会在node3节点上的两个分片副本上执行。需要注意的是,如果指定节点中的分片不足以覆盖到整个索引的数据,那么命令就只会在指定节点的相关分片上执行。比如,如果我们将查询命令的preference参数值设置为 \_only\_node:6GVd-ktcS2um4uM4AAJQhQ,我们就只会获取到一个分片的数据。这个属性值在如下的应用场景中非常有用:用户已经知道某个节点所在的服务器处理能力强大,希望一些特定的查询命令只在该节点上执行。
- \_prefer\_node:wJq0kPSHTHCovjuCsVK0-A:这个选项用来把preference参数值设置成\_prefer\_node:,后面附带的值是一个节点Id(本例中就是wJq0kPSHTHCovjuCsVK0-A) ,这会导致ElasticSearch优先选择指定的节点来执行查询命令,但是如果该节点上缺少索引数据的一些分片,那么查询命令会发到含有欠缺分片的节点上。这与\_only\_node选项是类似的,\_prefer\_node也可以用来选择特定的节点,但是具备容错机制。
- \_shards:0,1:这个preference值用来指定相关操作执行的某类分片(在本例中就是所有的分片,因为整个mastering索引只有id为0和1的分片)。这是唯一的一个可以结合其它属性使用的preference值。比如,如果希望命令只执行在本地节点的id为0或者1的分片上,我们可以把0,1两个值和\_local值用“;”连接起来,最终得到的preference参数值就是这样了:0,1:_local。允许用户发出的命令只在某个分片上执行这一特性用于诊断集群问题是非常有帮助的。
- custom,字符串值:这个自定义值会确保附带相同custom值的查询命令会在同样的分片上执行。比如,如果我们的查询命令附带preference参数值为mastering_elasticsearch,那么命令会在node1和node2的主分片上执行。如果我们又发送了另一个附带同样preference参数值的查询命令,该命令也只会在node1和node2的分片上执行。该功能用于应对以下应用场景:假如集群中的各个节点刷新速率不一样,我们不希望用户在重复同一个命令时看到不同的结果,就应该使用该功能。
最后还有一点没有提到,就是ElasticSearch的默认操作。默认情况下,ElasticSearch会将相关操作随机分发到分片或者分片副本上。如果往集群中发送大量的查询命令,最终每个分片和分片副本上执行的查询命令数量会大致相同。