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