1、什么是node
ES集群中每一个节点就是一个node,或者一个Elasticsearch实例就是一个节点。
node分类:
a、主节点:主节点不接受客户端的请求,他主要控制Elasticsearch集群,负责集群中的操作,比如创建/删除一个索引,跟踪哪些节点是群集的一部分,并决定哪些分片分配给相关的节点。主节点处理集群的状态并广播到其他节点,并接收其他节点的确认响应。 默认情况下任何一个集群中的节点都有可能被选为主节点,每个节点都可以通过设定配置文件elasticsearch.yml中的node.master属性为true(默认),node.data属性设置为false,成为主节点。对于大型的生产集群来说,推荐使用一个专门的主节点来控制集群,该节点将不处理任何用户请求,稳定的主节点对集群的健康是非常重要的。
b、数据节点:该节点具有存储数据和执行数据相关的操作,如增删改查,搜索,和聚合操作。数据节点对cpu,内存,io要求较高,在优化的时候需要监控数据节点的状态,当资源不够的时候,需要在集群中添加新的节点。默认情况下,每个节点都可以通过设定配置文件elasticsearch.yml中的node.data属性为true(默认)成为数据节点。如果我们要使用一个专门的主节点,应将其node.data属性设置为false。
c、客户端节点:该节点主要将客户端的请求路由到集群中的各个节点,扮演一个负载均衡的角色。将node.master属性和node.data属性都设置为false,那么该节点就是一个客户端节点。
d、部落节点:部落节点可以跨越多个集群,它可以接收每个集群的状态,然后合并成一个全局集群的状态,它可以读写所有节点上的数据,部落节点在elasticsearch.yml中的配置如下:tribe:*:
总结:
如果将master和client独立出来,一旦出现问题,重启后几乎是瞬间就恢复的,对用户几乎没有任何影响。另外将这些角色独立出来的以后,也将对应的计算资源消耗从data node剥离出来,更容易掌握data node资源消耗与写入量和查询量之间的联系,便于做容量管理和规划。
2、什么是shard(分片)
一个 分片 是一个底层的 工作单元 ,它仅保存了全部数据中的一部分,一个分片是一个 Lucene 的实例,它本身就是一个完整的搜索引擎。我们的文档被存储和索引到分片内,但是应用程序是直接与索引而不是与分片进行交互。
Elasticsearch 是利用分片将数据分发到集群内各处的。分片是数据的容器,文档保存在分片内,分片又被分配到集群内的各个节点里。当你的集群规模扩大或者缩小时, Elasticsearch 会自动的在各节点中迁移分片,使得数据仍然均匀分布在集群里。
注意:技术上来说,一个主分片最大能够存储 Integer.MAX_VALUE - 128 个文档,但是实际最大值还需要参考你的使用场景:包括你使用的硬件,文档的大小和复杂程度,索引和查询文档的方式以及你期望的响应时长。
主分片:在索引建立的时候就已经确定了主分片数,但是副本分片数可以随时修改,索引内任意一个文档都归属于一个主分片,所以主分片的数目决定着索引能够保存的最大数据量。
副分片:一个副本分片只是一个主分片的拷贝。副本分片作为硬件故障时保护数据不丢失的冗余备份,并为搜索和返回文档等读操作提供服务。
3、什么是index(索引)
index是保存相关数据的地方,索引实际上是指向一个或者多个物理 分片的逻辑命名空间 。事实上,我们的数据被存储和索引在分片(shards)中,索引只是一个把一个或者多个分片分组在一起的逻辑空间,然而内部的一些细节不需要我们程序关心,文档存储在索引(index)中,剩下的需要的工作交由Elasticsearch关心即可。索引命名规范这个名称必须全部小写,不能以下划线开头,不能包含逗号。
4、什么是type
在Elasticsearch中,我们可以使用相同类型(type)的文档表示相同的"事物",因为他们的数据结构是相同的,每个类型都有自己的映射(mapping)或者结构定义,就像传统数据库表中的列一样,所有类型下的文档被储存在同一个索引下,但是类型的映射(mapping)会告诉Elasticsearch不同的文档如何被索引。_type的命名规范,它的名字可以是大写或者小写,不能包含下划线或逗号,后面我们将使用employee作为类型名。
5、什么是document(文档)
一条记录,类似数据库中的一列。在 Elasticsearch 中,术语 文档 有着特定的含义,它是指最顶层或者根对象, 这个根对象被序列化成 JSON 并存储到 Elasticsearch 中,指定了唯一 ID。
文档元数据:_index:文档在哪存放; _type:文档表示的对象类别; _id:文档唯一标识(可以提供自己的 _id
,也可以让 Elasticsearch 帮你生成)。通过_index、_type、_id 可以唯一确定 Elasticsearch 中的一个文档。
当然,一个文档仅仅是在检查的时候不存在,并不意味着一毫秒之后它也不存在:也许同时正好另一个进程就创建了该文档。
6、什么是documnet routing(数据路由)
当客户端发起创建document的时候,es需要确定这个document放在该index哪个shard上。这个过程就是数据路由。
路由过程:
路由算法:shard = hash(routing) % number_of_primary_shards
routing:每次增删改查一个document的时候,都会带过来一个routing number,他的默认值就是这个document的_id(可能是手动指定,也可能是自动生成)routing = _id,所以决定一个document在哪个shard上,最重要的一个值就是routing值。相同的routing值,从hash函数中,产出的hash值一定是相同的。
number_of_primary_shards:主分片。
例如:假设_id=1会将这个routing值,传入一个hash函数中,产出一个routing值的hash值,hash(routing) = 21,然后将hash函数产出的值对这个index的primaryshard的数量求余数,21 % 3 = 0 就决定了,这个document就放在P0上。
手动指定routing:PUT /index/type/id?routing=user_id
手动指定routing value,可以保证某一类document一定被路由到一个shard上去,那么在后续进行应用级别的负载均衡以及提升批量读取的性能的时候,是很有帮助的。
7、为什么primary shard数量不可变
* 假如我们的集群在初始化的时候有5个primary shard,我们望里边加入一个document id=5,假如hash(5)=23,这时该document 将被加入 (shard=23%5=3)P3这个分片上。如果随后我们给es集群添加一个primary shard ,此时就有6个primary shard,当我们GET id=5 ,这条数据的时候,es会计算该请求的路由信息找到存储他的 primary shard(shard=23%6=5) ,根据计算结果定位到P5分片上。而我们的数据在P3上。所以es集群无法添加primary shard,但是可以扩展replicas shard。 *
8、ES document增删改的处理流程
ES增删改的处理流程:增删该的请求一定作用在主分片上。
假如我们es集群有3个node,每个node上一个主分片一个复制分片。
1、客户端发起一个PUT请求,假如该请求被发送到第一个node节点,那么该节点将成为协调节点(coordinating node),如图P1所在的节点就是协调节点。他将根据该请求的路由信息计算,该document将被存储到哪个分片。
2、第二步 通过计算发现该document被存储到p0分片,那么就将请求转发到node2节点。
3、第三步 P0根据请求信息创建document,和相应的索引信息,创建完毕后将信息同步到自己的副本节点R0上。
4、第四步 P0和R0将通知我们的协调节点,任务完成情况。
5、第五部 协调节点响应客户端最终的处理结果。
9、ES document读请求流程
1、第一步客户端发送读器请求到协调节点(coordinate node)。
2、第二步协调节点(coordinate node)根据请求信息对document进行路由计算,将请求转发到对应的node,node2 或者node3。 此时会使用round-robin随机轮询算法,在primary shard以及其所有replica(副本)中随机选择一个,让读请求负载均衡。
3、第三步相应接收到请求的节点(node2或者node3)将处理结果返回给协调节点(coordinate node)。
4、协调节点将最终的结果反馈给客户端。
注意:document如果还在建立索引过程中,可能只有primary shard有,任何一个replica shard都没有,此时请求如果作用到replica shard上可能会导致无法读取到document信息。但是document完成索引建立之后,primary shard和replica shard就都有了。