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