一个索引可以存储超出单个结点硬件限制的大量数据,es提供了将索引划分为多份的能力,每一份都称之为分片.当创建索引时,可以指定想要的分片数量.每个分片本身也是一个功能完善并且相对独立的索引.这个索引可以被放在集群中的任何结点上.
分片的重要性
1.允许水平切割/扩展内容容量
2.允许在分片之上进行分布式的,并行的操作,进而提高性能/吞吐量.
而分片的分布,聚合搜索请求是完全有es管理的,对于用户来说都是透明的,无需过分关心。
容易混淆的概念:一个Lucene索引在es中称作是分片,而一个es索引是多个分片的集合.在es在索引中搜索的时候,他发送查询到每一个属于索引的分片,然后合并每个分片的结果到一个全局的结果集.
重要原因:
1.在分片/结点失败的情况下,提高了可用性,所以分片从来不和原/主要分片置于同一节点上.
2.扩展搜索量/吞吐量,因为搜索可以在所有的副本上并行进行。
默认情况下:
每个索引被分片成一个主分片和一个赋值,这意味着,如果在集群中至少两个几点,你的索引将会有一个主分片和另外一个复制分片 。
集群由多个具有相同的cluster.name配置的结点组成,他们共同承担数据和负载的压力.当有结点加入或者从集群中移除时,集群会重新平均分配所有的数据。
当一个节点被选举为主节点时,他的管理范围会相应的有所变更,比如增加,删除索引时。而主节点并不需要涉及到文档级别的变更和搜索操作,所以当集群只拥有一个主节点的情况下,即时流量的增加他也不会成为瓶颈。任何结点都能成为主节点,每个结点都知道任意文档的所处位置,并且能够将我们的请求直接转发至存储着文档的结点中,并最终返回个客户端。es对这一切的管理都是透明的。
将单节点分配成3个主分片和一个副本
- #PUT http://127.0.0.1:1001/users
- {
- "settings" : {
- "number_of_shards" : 3,
- "number_of_replicas" : 1
- }
- }
当索引一个文档的时候,文档会被存储到一个主分片中。es是如何知道这个文档应该发的那个放到那个主分片中呢?es是根据下面的这个公式来决定的:
shard = hash(routing) % number_of_primary_shards
routing是一个可变值,默认是文档的id,也可以设置成一个自定义的值,routing通过hash函数生成一个数字,然后这个数字在除以number_of_primary_shards(主分片数量)后得到余数就是我们想要寻求的文档的所在位置.也就是说,我们不能随便的修改主分片的数量,要在刚开始就指定主分片的数量.
当发送请求时,比较好的做法是轮询所有的集群中的结点,这样能更好的处理负载.
在读数据请求时,如果数据的副本已经在主分片上存在,但是还没有同步到副本分片上,这种情况下,副本分片可能会报告数据并不存在的问题,但是主分片会成功 的返回文档,一旦索引请求成功返回个用户,那么文档在主副分片都是可用的
部分更新一个文档的流程如下:
1.客户端向node1 发送更新请求
2.node1将这个请求转发到主分片所在的node3
3.node3从主分片检索文档,修改_source字段中的JSON,并且常会进行重新索引主分片的文档,如果文档已经被另一个进程修改,他会重新尝试步骤3,超过最大尝试数量retry_on_conflict后放弃尝试
4.如果node3成功创更新文档,他将新版本的文档并行转发到node1和node2上的副本分片,重新建立索引.一旦所有的副本都成功返回,那么node3向协调结点也返回成功,协调结点向客户端返回成功 .
需要注意的是,当主分片把更改转发到副本分片时,他不会转发更新请求,相反,他会转发完整的文档新版本.这些转发会以异步的形式呈现,并不能保证他们顺序抵达.如果es只转发更改请求,那么可能咦错误的顺序更改应用,导致得到损坏的文档.
mget和 bulk API的模式类似于单文档模式。**区别在于协调节点知道每个文档存在于哪个分片中。它将整个多文档请求分解成每个分片的多文档请求,并且将这些请求并行转发到每个参与节点。
协调节点一旦收到来自每个节点的应答,就将每个节点的响应收集整理成单个响应,返回给客户端。
用单个 mget 请求取回多个文档所需的步骤顺序
bulk API, 允许在单个批量请求中执行多个创建、索引、删除和更新请求。
bulk API 按如下步骤顺序执行:
1.客户端向Node 1 发送 bulk请求。
2. Node 1为每个节点创建一个批量请求,并将这些请求并行转发到每个包含主分片的节点主机。
3.主分片一个接一个按顺序执行每个操作。当每个操作成功时,主分片并行转发新文档(或删除)到副本分片,然后执行下一个操作。一旦所有的副本分片报告所有操作成功,该节点将向协调节点报告成功,协调节点将这些响应收集整理并返回给客户端。