#Elasticsearch分布式的操做node
咱们知道在建立索引的时候咱们时能够决定建立多少个主分片(只能建立的时候指定,之后不可修改)和多少个复制分片(副分片,建立的时候能够改变,以后也能够改变)。Elasticsearch有这个规定其实是为了剪碎文档,它检索文档是基于一个简单的算法来决定的算法
shard=hash(routing)%number_of_primary_shards
复制代码
这里的routing是一个任意的字符串,默认是_id,它是能够自定义的。这个routing字符串经过哈希函数生产一个数字,而后初一主分片的数量获得一个余数(remainder),余数的范围永远是0到number_of)shards-1,这个数字就是特定文档的所在的分片(也就是解释了为何主分片在建立以后不能该的缘由)数组
咱们的请求到节点的任意一个接待你,每一个节点都有能力来处理请求。每一个节点都知道任意文档所在的节点,索引也能够将请求转发到须要的节点,这个节点也称为请求节点。网络
文档的建立,索引和删除请求都是写操做,它们都必须在主分片上完成功能才能复制到相关和的复制分片上。数据结构
它的步骤以下:async
1.客户端给Node1发送建立,索引或者删除请求。分布式
2.节点使用文档的_id肯定文档属于分片0,它转发请求到Node3,分片位于该节点上。函数
3.Node3在主分片上执行请求,若是成功,它转发请求到相应的位于Node1和Node2的复制节点上。若是Node3报告成功到请求的节点,请求节点在报告给客户端。spa
客户端在收到请求的响应的时候就已经修改为功,主分片和复制分片都已经被应用了。3d
复制默认的值是sync。这将致使主分片获得的复制分的成功响应才返回。若是将复制节点设置成async,请求在主分片上执行后就会返回客户端。请求依旧转发到复制节点,可是复制节点成功与否咱们不得而知。
默认主分片在写入时须要规定数量(quorum)或者过半的分片(可使主节点或者复制分片)可用。这是防止数据被写入到错的网络分区
int((primary+number_of_replicas)/2)+1
复制代码
consistency值 | 意义 |
---|---|
one | 只有一个主分片 |
all | 全部主分片和复制分片 |
quorum | 规定数量 |
例子:
若是只有两个节点,给索引定义了三个复制节点,那么咱们规定的数据量就是int((primary+3replicas)/2)+1=3,若是活动分片不够没那么就不可以索引或者删除任何文档。
当分片副本不足时会怎么样?Elasticsearch会等待更多的分片出现,默认是1分钟,若是须要,你能够设置timeout参数种植的更早,例如100表示100毫秒,100s表示100秒。
注意:新索引默认只有一个复制分片,可是这样没法知足quorum的要求须要两个而得到的分片。固然,这个默认设置将组织咱们在单一节点集群中进行操做。Wie了避开这个问题,规定只有数量在number_of_replicas大于1时才生效。
主分片和复制分片上检索一个文档必要的顺序步骤:
1.客户端给节点1发送请求(get) 2.节点使用文档的_id肯定文档属于分片0.分片0对应的复制负片分别在三个节点上。此时就会妆发请求给节点2. 3.节点2返回文档给节点1而后返回给客户端。
##局部更新文档
局部修改文档通常须要主节点来完成,而后同步数据到其余的复制节点。
以下例子所示:
1.客户端给Node1发送修改请求
2.转发请求到主分片所在node3
3.node3从主分片检索出文档,修改_source字段的JSON,而后在主分片上重建索引。若是有其余的进程修改了文档,它以retry_on_conflict设置的次数重复步骤3,都为成功则放弃。
4.若是node3成功则文档更新成功,它同时转发文档的新版本到node1和node2上的复制分片重建索引。当复制节点报告成功,Node3就返回成功给请求节点,而后返回给客户端。
mget和bulk API与单独的文档也是相似的,差异的地方是在于,它把多文档七八个球拆成每一个分片的对文档氢气与,而后转发请求。一旦接受每一个节点对应的答应,而后整理这些响应组合为一个单独的响应返回给客户端。
mget请求的步骤
bulk操做的步骤 1.客户端向Node1发送bulk请求 2.Node1为每一个分片构建批量请求,而后转发到这些请求所须要的主分片上。 3.住分片一个接一个的按顺序执行操做。当一个操做执行完,住分片转发新文档(或者删除部分)给对应的复制节点,而后执行下一个操做。一旦全部的复制节点报告全部的操做成功完成,节点就报告success给请求接待你,后者(请求节点)整理响应并返回给客户端。
bulk操做不一样于其余操做,不能直接使用JSON做为请求体,由于批量操做每一个引用属于不一样的主分片,每一个分片可能被分布于集群中的某个节点上。这意味这批量操做都要被妆发到对应的分片和节点上。若是单独的请求被包装到JSON数组中,那一位着咱们须要:
1.解析JSON为数组(包括文档数组,可能很是大)
2.检查每一个请求决定应该到哪一个分片上
3.为每一个分片建立一个请求的数组
4.序列化这些数组为内部传输格式
5.发送请求到每一个分片
这可行,但须要大量的RAM来承载本质上相同的数据,还要建立更多的数据结构使得JVM花更多的时间执行垃圾回收。取而代之的,Elasticsearch则是从网络缓冲区中一行一行的直接读取数据。它使用换行符识别和解析action/metadata行,以决定哪些分片来处理这个请求。这些行请求直接转发到对应的分片上。这些没有冗余复制,没有多余的数据结构。整个请求过程使用最小的内存在进行。
和SQL同样使用LIMIT分页,Elasticsearch接受from和size参数做为分页的关键字: size:结果数,默认是10, from:跳过开始的结果数,默认是0.
注意:
应该注意分页太深或者一次请求太多的结果。结果在返回以前会被排序。可是记住一个请求请求经常涉及不少分片。每一个分片生产本身排好序的结果,他们接着须要集中起来拍寻以确保总体排序正确。(例如:若是咱们有5个分片,每一个分片返回10条结果,5个分片就会返回50条结果,而后在获取总体的10条结果,这就也就是为何深度分页须要花费更多计算和内存)
Elasticsearch有两种表单:
1.一种是"简易版"的查询字符串(query string) 将全部参数经过查询字符串定义。
GET /test/_doc/_search?q=field1:value3
复制代码
2.使用JSON完整的表示请求体,这种富搜索语言叫作结构化查询语句(DSL)
GET /test/_doc/_search
{
"query":{
"match":{
"field1":"value3"
}
}
}
复制代码