分片预分配

一个分片存在于单个节点,但一个节点可以持有多个分片。想象一下我们创建拥有两个主分片的索引而不是一个:

  1. PUT /my_index
  2. {
  3. "settings": {
  4. "number_of_shards": 2, <1>
  5. "number_of_replicas": 0
  6. }
  7. }

<1> 创建拥有两个主分片无副本分片的索引。

当只有一个节点时,两个分片都将被分配至相同的节点。 从我们应用程序的角度来看,一切都和之前一样运作着。应用程序和索引进行通讯,而不是分片,现在还是只有一个索引。

这时,我们加入第二个节点,Elasticsearch 会自动将其中一个分片移动至第二个节点,如 一个拥有两个分片的索引可以利用第二个节点 描绘的那样, 当重新分配完成后,每个分片都将接近至两倍于之前的计算能力。

Figure 1. 一个拥有两个分片的索引可以利用第二个节点

我们已经可以通过简单地将一个分片通过网络复制到一个新的节点来加倍我们的处理能力。 最棒的是,我们零停机地做到了这一点。在分片移动过程中,所有的索引搜索请求均在正常运行。

在 Elasticsearch 中新添加的索引默认被指定了五个主分片。 这意味着我们最多可以将那个索引分散到五个节点上,每个节点一个分片。 它具有很高的处理能力,还未等你去思考这一切就已经做到了!

分片分裂


用户经常在问,为什么 Elasticsearch 不支持 分片分裂(shard-splitting)— 将每个分片分裂为两个或更多部分的能力。(((“shard splitting”))) 原因就是分片分裂是一个糟糕的想法:

  • 分裂一个分片几乎等于重新索引你的数据。它是一个比仅仅将分片从一个节点复制到另一个节点更重量级的操作。

  • 分裂是指数的。起初你你有一个分片,然后分裂为两个,然后四个,八个,十六个,等等。分裂并不会刚好地把你的处理能力提升 50%。

  • 分片分裂需要你拥有足够的能力支撑另一份索引的拷贝。通常来说,当你意识到你需要横向扩展时,你已经没有足够的剩余空间来做分裂了。

Elasticsearch 通过另一种方式来支持分片分裂。你总是可以把你的数据重新索引至一个拥有适当分片个数的新索引(参阅 reindex)。 和移动分片比起来这依然是一个更加密集的操作,依然需要足够的剩余空间来完成,但至少你可以控制新索引的分片个数了。