一个 Lucene 索引 我们在 Elasticsearch 称作 分片 。 一个Elasticsearch 索引 是分片的集合。 当 Elasticsearch 在索引中搜索的时候, 他发送查询到每一个属于索引的分片(Lucene 索引),然后合并每个分片的结果到一个全局的结果集。
分片很重要,主要有两方面的原因:
1、允许水平分割 / 扩展我们的内容容量。
2、允许在分片之上进行分布式的、并行的操作,进而提高性能/吞吐量。
分片的配置必须在创建索引的时候就指定分片数量,因为这直接决定了数据的路由规则,索引不支持在运行中的索引进行动态修改,副本则可以。
Elasticsearch 允许你创建分片的一份或多份拷贝,这些拷贝叫做副本分片,目的就是解决在在某个分片或节点因出现问题时候,能提供故障转移的机制。
副本分片很重要,有两个主要原因:
1、在分片/节点失败的情况下,提供了高可用性。因为这个原因,注意到副本分片从不与主分片置于同一节点上是非常重要的。
2、扩展你的搜索量/吞吐量,因为搜索可以在所有的副本上并行运行。
在运行中的集群上是可以动态调整副本分片数目的,我们可以按需伸缩集群。让我们把
副本数从默认的 1 增加到 2。
PUT your_index/_settings
{
"number_of_replicas" : 2
}
PUT your_index
{
"mappings" : {
"properties" : {
#索引字段(略)
}
}
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 1
}
}
配置之后总共有3个主分片f1,f2,f3,并且每个分片有自己的一个副本分片,f1-back,f2-back,f3-back,总共6个分片。
1、分片肯定以为着es的集群部署,那么怎样设置分配和副本才能使得集群部署合理呢?
如果我们按照1那样配置,并且只有一台机器
集群健康值:yellow( 3 of 6 ):表示当前集群的全部主分片都正常运行,但是副本分片没有全部处在正常状态。
在同一个节点上既保存原始数据又保存副本是没有意义的,因为一旦失去了那个节点,我们也将丢失该节点 上的所有副本数据。
虽然当前集群是正常运行的,但存在丢失数据的风险。
2、当我们有3台服务器,并且在每个启动的es都配置文件中都完成了集群监听配置
#在节点1配置节点2和3的地址
discovery.seed_hosts: ["localhost:9302", "localhost:9303"]
集群健康值:green( 3 of 6 ):表示所有 6 个分片(包括 3 个主分片和 3 个副本分片)都在正常运行。
边框加粗的是主分片,没加粗的是副本分片,从中我们也可以看出es自动分片并没有强迫症,但是却严格遵守水平扩容,以及故障转移的配置规格,但节点一挂了(服务器node-1),此时,副本0(node-2)副本1(node-3)会通过选举成为主分片,保证了索引的正常运行。
当索引一个文档的时候,文档会被存储到一个主分片中。 Elasticsearch 如何知道一个文档应该存放到哪个分片中呢?当我们创建文档时,它如何决定这个文档应当被存储在分片 1 还是分片 2 中呢?首先这肯定不会是随机的,否则将来要获取文档的时候我们就不知道从何处寻找了。实际上,这个过程是根据下面这个公式决定的:
shard = hash(routing) % number_of_primary_shards
新建、删除请求都是写操作, 必须在主分片上面完成之后才能被复制到相关的副本分片。
当删除某个数据时,es并不会直接物理删除,而是将原文档的数据标记为删除,然后重新写入新的文档数据,被标记删除的文档数据,会有一定的策略进行统一收集再真正进行物理删除操作
更新一个文档的部分数据
当主分片把更改转发到副本分片时, 它不会转发更新请求。 相反,它转发完整文档的新版本。请记住,这些更改将会异步转发到副本分片,并且不能保证它们以发送它们相同的顺序到达。 如果 Elasticsearch 仅转发更改请求,则可能以错误的顺序应用更改,导致得到损坏的文档。
Lucene 在新增数据时,采用了延迟写入的策略,默认情况下索引的refresh_interval 为1 秒。
Lucene 将待写入的数据先写到内存中,超过 1 秒(默认)时就会触发一次 Refresh,然后 Refresh 会把内存中的的数据刷新到操作系统的文件缓存系统中。
如果我们对搜索的实效性要求不高,可以将 Refresh 周期延长,例如 30 秒。
这样还可以有效地减少段刷新次数,但这同时意味着需要消耗更多的 Heap 内存。
Flush 的主要目的是把文件缓存系统中的段持久化到硬盘,当 Translog 的数据量达到 512MB 或者 30 分钟时,会触发一次 Flush。
index.translog.flush_threshold_size 参数的默认值是 512MB,我们进行修改。
增加参数值意味着文件缓存系统中可能需要存储更多的数据,所以我们需要为操作系统的文件缓存系统留下足够的空间。
ES 为了保证集群的可用性,提供了 Replicas(副本)支持,然而每个副本也会执行分析、索引及可能的合并过程,所以 Replicas 的数量会严重影响写索引的效率。
当写索引时,需要把写入的数据都同步到副本节点,副本节点越多,写索引的效率就越慢。
如果我们需要大批量进行写入操作,可以先禁止Replica复制,设置
index.number_of_replicas: 0 关闭副本。在写入完成后, Replica 修改回正常的状态。