ElasticSearch中的分片(shards)是什么

分片概念

分片重要性

ES中所有数据均衡的存储在集群中各个节点的分片中,会影响ES的性能、安全和稳定性, 所以很有必要了解一下它。

为什么要有分片

一个索引可以存储超出单个结点硬件限制的大量数据(比如说我的电脑D盘放满了,我也可以在E盘解压一个服务器,让他们集群,可以共享索引库,就可以平均分享一下就可以了.)。比如,一个具有10亿文档的索引占据1TB的磁盘空间,而任一节点都没有这样大的磁盘空间;或者单个节点处理搜索请求,响应太慢。为了解决这个问题,Elasticsearch提供了将索引划分成多份的能力,这些份就叫做分片。当你创建一个索引的时候,你可以指定你想要的分片的数量。每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上。分片很重要,主要有两方面的原因: 1)允许你水平分割/扩展你的内容容量。 2)允许你在分片(潜在地,位于多个节点上)之上进行分布式的、并行的操作,进而提高性能/吞吐量。
至于一个分片怎样分布,它的文档怎样聚合回搜索请求,是完全由Elasticsearch管理的,对于作为用户的你来说,这些都是透明的。

分片还有副本,叫replica shard

在一个网络/云的环境里,失败随时都可能发生,在某个分片/节点不知怎么的就处于离线状态,或者由于任何原因消失了,这种情况下,有一个故障转移机制是非常有用并且是强烈推荐的。为此目的,Elasticsearch允许你创建分片的一份或多份拷贝,这些拷贝叫做复制分片,或者直接叫复制。

分片是什么?

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

实列场景:

假设 IndexA 有2个分片,我们向 IndexA 中插入10条数据 (10个文档),那么这10条数据会尽可能平均的分为5条存储在第一个分片,剩下的5条会存储在另一个分片中。

和主流关系型数据库的表分区的概念有点类似,如果你比较熟悉关系型数据库的话。

分片的设置

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

PUT indexName
{
    
    
    "settings": {
    
    
        "number_of_shards": 5
    }
}

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

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

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

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

建议:(仅参考)
1、每一个分片数据文件小于30GB
2、每一个索引中的一个分片对应一个节点
3、节点数大于等于分片数

根据建议,至少需要 10 个分片。
结果: 建10个节点 (Node),Mapping 指定分片数为 10,满足每一个节点一个分片,每一个分片数据带下在30G左右。
SN(分片数) = IS(索引大小) / 30
NN(节点数) = SN(分片数) + MNN(主节点数[无数据]) + NNN(负载节点数)

分片查询

我们可以指定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不提供此方式需要改源码。

    /** 
         * 指定分片 查询 
         */  
        @Test  
        public void testPreference()  
        {
    
      
            SearchResponse searchResponse = transportClient.prepareSearch(index)  
                    .setTypes("add")  
                    //.setPreference("_local")  
                    //.setPreference("_primary")  
                    //.setPreference("_primary_first")  
                    //.setPreference("_only_node:ZYYWXGZCSkSL7QD0bDVxYA")  
                    //.setPreference("_prefer_node:ZYYWXGZCSkSL7QD0bDVxYA")  
                    .setPreference("_shards:0,1,2")  
                    .setQuery(QueryBuilders.matchAllQuery()).setExplain(true).get();  

            SearchHits hits = searchResponse.getHits();  
            System.out.println(hits.getTotalHits());  
            SearchHit[] hits2 = hits.getHits();  
            for(SearchHit h : hits2)  
            {
    
      
                System.out.println(h.getSourceAsString());  
            }  
        }  

shard&replica机制梳理

index包含多个shard

一个index包含3T的数据,每台服务器承载1T的数据,此时我们创建index 的时候设置primaryshard有3个,那么每台服务器就会一个primaryshard, 然后每台服务器都有均匀负载1T的数据.
这就是index分片的基本原理.

每个shard都是一个最小工作单元,承载部分数据

ElasticSearch底层基于Lucene开发的,其实底层每个shard就是一个Lucene实例,每个shard都有完整的建立索引和处理请求的能力

增减节点时,shard会自动在nodes中负载均衡

就好比说有有六台机器总共七个shard, 肯定就会有一台机器有两个shard, 此时给ElasticSearch集群新增一台机器进来,那么有两个shard的那台机器会自动给一个shard分配给新加入的机器上去.

primary shard和replica shard

每个document肯定只存在于某一个primary shard以及其对应的replica shard中,一个document不可能存在于多个primary shard

replica shard是primary shard的副本,负责容错,以及承担读请求负载

如果primary shard宕机了,对应replica shard 里面数据依然是存在的,并且还对外处理读请求.

primary shard的默认数量是5,replica默认是1,

默认有10个shard,5个primary shard,5个replica shard

primary shard的数量在创建索引的时候就固定了,replica shard的数量可以随时修改

primary shard数量默认是5 ,replica shard数量默认是1,假如说我primary shard设置为3了,replica shard设置成了1, 那么默认就是3个primary shard 和3个replica shard .

如果我给replica shard设置成了2 ,那么就是每个primaryshard有两个replica shard,结果就是3个primary shard 和 6个replica shard .

primary shard不能和自己的replica shard放在同一个节点上

否则节点宕机,primary shard和副本都丢失,起不到容错的作用,但是可以和其他primary shard的replica shard放在同一个节点上,
就是可以primaryshard 1和replicashard2放在一个服务器上面, 但是primaryshard1和replicashard1不能放在一个服务器上,
如果primaryshard1和replicashard1放在一台机器上,万一宕机的话,你primaryshard1和replicashard1全部丢失.
所以ElasticSearch官方不允许primary shard不能和自己的replica shard放在同一个节点上

单node节点环境下创建index是什么样子的

单node环境下,创建一个index,有3个primary shard,3个replica shard,此时集群status是yellow,这个时候,只会将3个primary shard分配到仅有的一个node上去,另外3个replica shard是无法分配的
集群可以正常工作,但是一旦出现节点宕机,数据全部丢失,而且集群不可用,无法承接任何请求

PUT /test_index
{
    
    
   "settings" : {
    
    
      "number_of_shards" : 3,
      "number_of_replicas" : 1
   }
}

在2个node节点环境下replica shard是如何分配的

如果是一台机器当想,那么这一台机器上就会有3个primary shard,3个replica shard ,此时集群状态为yellow
如果新加入了一台机器的话.ElasticSearch会自动将3个replica shard分配到新的机器上面去.primaryshard的数据会拷贝到对应的replicashard上面去.
然后primaryshard和对应的replicashard上的数据是一模一样的

此时客户端发送读请求的时候,可以去primaryshard1,也可以去primaryshard1对应的replicashard1上去处理.

参考整理

https://blog.csdn.net/qq_38486203/article/details/80077844

中华石杉的Elasticsearch顶尖高手系列 课程

猜你喜欢

转载自blog.csdn.net/qq_41489540/article/details/113816617