1、分片是什么?

简单来讲就是咱们在ES中所有数据的文件块,也是数据的最小单元块,整个ES集群的核心就是对所有分片的分布、索引、负载、路由等操作

分片可以是主分片(primary shard)或者是副本分片(replica shard)

  • number_of_shards
    每个索引的主分片数,默认值是 5 。这个配置在索引创建后不能修改。
  • number_of_replicas
    每个主分片的副本数,默认值是 1 。对于活动的索引库,这个配置可以随时修改。

例子:如创建一个 blogs 的索引,五个主分片,一个副本分片

创建 IndexName 索引时候,在 Mapping 中可以如下设置分片 (curl)

PUT blogs
{
    "settings": {
        "number_of_shards":5,
        "number_of_replicas": 1
    }
}

注意

索引建立后,分片个数是不可以更改的

2、分片个数(数据节点计算)

分片个数是越多越好,还是越少越好了?根据整个索引的数据量来判断。

实列场景:

如果 blogs 所有数据文件大小是300G,改怎么定制方案了?(可以通过Head插件来查看)

建议:(仅参考)

   1、每一个分片数据文件小于30GB - 50GB 之间

   2、每一个索引中的一个分片对应一个节点

   3、节点数大于等于分片数

根据建议,至少需要 10 个分片。

结果: 建10个节点 (Node),Mapping 指定分片数为 10,满足每一个节点一个分片,每一个分片数据带下在30G左右。

SN(分片数) = IS(索引大小) / 30

NN(节点数) = SN(分片数) + MNN(主节点数[无数据]) + NNN(负载节点数)

分配分片时主要考虑的你的数据集的增长趋势.

我们也经常会看到一些不必要的过度分片场景. 从ES社区用户对这个热门主题(分片配置)的分享数据来看, 用户可能认为过度分配是个绝对安全的策略(这里讲的过度分配是指对特定数据集, 为每个索引分配了超出当前数据量(文档数)所需要的分片数).

Elastic在早期确实鼓吹过这种做法, 然后很多用户做的更为极端--例如分配1000个分片. 事实上, Elastic目前对此持有更谨慎的态度.

稍有富余是好的, 但过度分配分片却是大错特错. 具体定义多少分片很难有定论, 取决于用户的数据量和使用方式. 100个分片, 即便很少使用也可能是好的;而2个分片, 即便使用非常频繁, 也可能是多余的.

要知道, 你分配的每个分片都是有额外的成本的:

1、每个分片本质上就是一个Lucene索引, 因此会消耗相应的文件句柄, 内存和CPU资源

2、每个搜索请求会调度到索引的每个分片中. 如果分片分散在不同的节点倒是问题不太. 但当分片开始竞争相同的硬件资源时, 性能便会逐步下降

3、ES使用词频统计来计算相关性. 当然这些统计也会分配到各个分片上. 如果在大量分片上只维护了很少的数据, 则将导致最终的文档相关性较差

3、分片查询

我们可以指定es去具体的分片查询从而进一步的实现es极速查询。

  1. randomizeacross shards
    随机选择分片查询数据,es的默认方式
  2. _local
    优先在本地节点上的分片查询数据然后再去其他节点上的分片查询,本地节点没有IO问题但有可能造成负载不均问题。数据量是完整的。
  3. _primary
    只在主分片中查询不去副本查,一般数据完整。
  4. _primary_first
    优先在主分片中查,如果主分片挂了则去副本查,一般数据完整。
  5. _only_node
    只在指定id的节点中的分片中查询,数据可能不完整。
  6. _prefer_node
    优先在指定你给节点中查询,一般数据完整。
  7. _shards
    在指定分片中查询,数据可能不完整。
  8. _only_nodes
    可以自定义去指定的多个节点查询,es不提供此方式需要改源码。