# Shard Allocation Awareness ( 分片分配意识 )

原文链接 : [https://www.elastic.co/guide/en/elasticsearch/reference/5.4/allocation-awareness.html](https://www.elastic.co/guide/en/elasticsearch/reference/5.4/allocation-awareness.html)

译文链接 : [http://www.apache.wiki/pages/viewpage.action?pageId=10029766](http://www.apache.wiki/pages/viewpage.action?pageId=10029766)

贡献者 : [小瑶](/display/~chenyao)，[ApacheCN](/display/~apachecn)，[Apache中文网](/display/~apachechina)

## Shard Allocation Awareness

当在同一物理服务器，多个机架上或跨多个感知区域上的多个虚拟机上运行节点时，同一物理服务器，同一机架中或相同感知区域中的两个节点更有可能会同时崩溃，而不是两个不相关的节点同时崩溃。

如果 **Elasticsearch** 了解硬件的物理配置，则可以确保主分片及其副本分片分布在不同的物理服务器，机架或区域之间，以尽可能减少丢失所有分片副本的风险。

分片识别设置允许您告知 **Elasticsearch** 您的硬件配置。

例如，假设我们有几个机架。 当我们启动一个节点时，我们可以通过给它指定一个名为 **rack_id** 的任意元数据属性来告知它所在的机架 - 我们可以使用任何属性名称。 例如：

```
./bin/elasticsearch -Enode.attr.rack_id=rack_one
```

此设置也可以在 **elasticsearch.yml** 配置文件中指定。

现在，我们需要通过告诉 **Elasticsearch** 使用哪些属性来设置分片分配意识。 这可以在所有主节点上的 **elasticsearch.yml** 文件中进行配置，也可以使用 **[cluster-update-settings API](/display/Elasticsearch/Cluster+Update+Settings)** 进行设置（并更改）。

对于我们的示例，我们将在配置文件中设置值：

```
cluster.routing.allocation.awareness.attributes: rack_id
```

使用此配置，假设我们启动了两个节点，其中 **node.attr.rack_id** 设置为 **rack_one** ，我们创建一个索引，其中包含 **5** 个主分片和 **1** 个每个主分片的副本。 所有原始和副本都分配在两个节点之间。

现在，如果我们再启动另外两个节点，其中 **node.attr.rack_id** 设置为 **rack_two** ， **Elasticsearch** 将把分片移动到新节点，确保（如果可能的话），同一个分片的两个副本不在同一个机架中。 但是，如果 **rack_two** 失败，则取消其两个节点， **Elasticsearch** 仍然会将丢失的分片副本分配给 **rack_one** 中的节点。

| **Prefer local shards** |
| 执行搜索或 GET 请求时，在启用分片感知的情况下， Elasticsearch 将更愿意使用同一意识组中的本地分片 - 分片来执行请求。这通常比交叉架或意识区更快。 |

可以指定多个感知属性，在这种情况下，来自每个属性的值的组合被认为是一个单独的值。

```
cluster.routing.allocation.awareness.attributes: rack_id,zone
```

注意

使用感知属性时，分片不会分配给没有为这些属性设置值的节点。

注意

在具有相同感知属性值的特定节点组上分配的分片的主/副本数由属性值的数量确定。 当组中的节点数量不平衡并且有许多副本时，副本分片可能未被分配。

## Forced Awareness ( 强迫意识 )

假设您有两个意识区域和两个区域中的足够的硬件来托管所有的主要和复制分片。 但是，也许在单个区域中的硬件，虽然足以容纳一半的碎片，但无法承载所有的碎片。

通过普遍的意识，如果一个区域与另一个区域失去联系， **Elasticsearch** 会将所有丢失的副本分片分配给单个区域。 但是在这个例子中，这个突然的额外负载会导致剩下的区域中的硬件过载。

强制意识解决了这个问题，绝不允许将同一分片的副本分配到同一个区域。

例如，让我们说一个叫做 **zone** 的意识属性，我们知道我们要有两个区域， **zone1** 和 **zone2** 。 以下是我们如何强制对节点的意识：

```
cluster.routing.allocation.awareness.force.zone.values: zone1,zone2 
cluster.routing.allocation.awareness.attributes: zone
```

我们必须列出 **zone** 属性可以具有的所有可能的值。

现在，如果我们将 **node.attr.zone** 的 **2** 个节点设置为 **zone1** ，并创建一个具有 **5** 个碎片和 **1** 个副本的索引。 将创建索引，但只会分配 **5** 个主分片（没有副本）。 只有当我们启动 **node.attr.zone** 设置为 **zone2** 的更多节点时，才能分配副本。

**cluster.routing.allocation.awareness**。***** 设置都可以在具有** [cluster-update-settings API](/display/Elasticsearch/Cluster+Update+Settings)** 的实时集群上动态更新。