es集群单播unicast
当Elasticsearch节点启动时,它使用发现(discovery)模块来发现同一个集群(节点的es配置文件中配置项-cluster.name: 集群名称 一样时,表示是同一个集群),并与它们连接。单播模式实现过程是,Elasticsearch节点会向自己的配置文件中配置项-discovery.zen.ping.unicast.hosts: ["host:port"]中指定的“种子节点”发送请求,以让"种子节点“发现自己
,最终拥有相同集群名称的节点就会被串联在一起,即所谓的”集群“
。
广播就像是家长找家人
,单播就想是家人主动找家长
,让家长知道自己在那儿。
Elasticsearch是如何实现master选举的
Bully算法
提到分布式选举算法,大家都知道Paxos算法,但是这个算法比较复杂,es选取的是一个很简单的Bully算法,算法描述如下:
某个进程通过广播,获取所有能够连接到的进程的ID。
如果发现自己是ID最大的进程,则广播自己成为master节点,并广播该消息。
如果进程发现有其他进程比自己的ID大,则认为自己不能成为master,等待master广播。
discovery.zen.minimum_master_nodes 最小节点数,防止脑裂
选出临时master
节点启动的时候
- ping seed list,获取节点列表(不包含本节点)
- 构建两个列表
-
activeMasters 存储当前活跃master列表,遍历1中列表 将每个节点认为的当前master加入
activeMasters 列表中,考虑到异常情况,可能各节点看到当前的master不同 -
masterCandidates 存储候选者列表,遍历第一步获取列表,去掉不具备master资格的节点,添加到这个列表中
并获取PingResponse返回结果(findMaster) 过滤出具有Master资格的节点(filterPingResponses)
- 选出临时Master。根据PingResponse结果构建两个列表:activeMasters和masterCandidates。
– 如果activeMasters非空,则从activeMasters中选择最合适的作为Master;(取列表中id最小的)
– 如果activeMasters为空,则从masterCandidates中选举,结果可能选举成功,也可能选举失败。(1.判断是否候选者足够,达到法定人数,否则失败 2.选择ID最小并把版本号高的放前面)
判断临时Master是否是本节点。
– 如果临时Master是本节点:则等待其他节点选我,默认30秒超时,成功的话就发布新的clusterState。(当选总统候选人,只等选票过半了)
– 如果临时Master是其他节点:则不再接受其他节点的join请求,并向Master节点发送加入请求。(没资格选举,就只能送人头了)
投票与得票实现
在es中,发送投票就是发送加入集群(join request)
得票就是申请加入该节点请求的数量
确立master或加入集群
判断临时Master是否是本节点。
– 如果临时Master是本节点:
1.等待足够多的master资格的节点加入(投票达到法定人数)
完成选举
2.超时30(默认)后还没有足够多的的join请求,选举失败,开始新一轮选举
3.成功后发布cluster state
– 如果临时Master是其他节点:
1.不再接受其他节点的join请求
2.并向Master节点发送加入请求。(没资格选举,就只能送人头了)超时30(默认),
如果异常3次重试
3.最终当选的master会发布集群状态,才确认客户端的join请求
节点失效检测
到此为止 轩主流程执行完毕,master身份已确认,非master节点已加入集群
节点检测会监控节点是否离线
失效检测是选主后不可或缺的步骤,不执行会产生脑裂
失效探测器
选主流程之后不可或缺的步骤,不执行失效检测可能会产生脑裂现象。
定期(默认为1s)发送ping请求探测节点是否正常,当失败达到一定次数(默认为3次),或者收到节点的离线通知时,开始处理节点离开事件。
NodesFaultDetection:在Master节点启动,简称NodesFD。定期探测加入集群的节点是否活跃。当有节点连不上时,会执行removeNode。然后需要审视此时的法定人数是否达标(没错!老坛酸菜牛肉面,仍然是那个熟悉的配方:discovery.zen.minimum_master_nodes),不达标就主动放弃Master身份执行rejoin以避免脑裂。
MasterFaultDetection:在非Master节点启动,简称MasterFD。定期探测Master节点是否活跃,Master下线则触发rejoin重新选举。
Elasticsearch 的选主是 ZenDiscovery 模块负责的,主要包含 Ping(节点之间通过这个 RPC 来发现彼此)和 Unicast(单播模块包含一个主机列表以控制哪些节点需要 ping 通)这两部分;
Elasticsearch中的节点(比如共20个),其中的10个选了一个master,另外10个选了另一个master,怎么办?
1、当集群 master 候选数量不小于 3 个时,可以通过设置最少投票通过数量(discovery.zen.minimum_master_nodes)超过所有候选节点一半以上来解决脑裂问题;
2、当候选数量为两个时,只能修改为唯一的一个 master 候选,其他作为 data节点,避免脑裂问题。
详细描述一下 Elasticsearch 索引文档的过程
协调节点默认使用文档 ID 参与计算(也支持通过 routing),以便为路由提供合适的分片。
shard = hash(document_id) % (num_of_primary_shards)
1、当分片所在的节点接收到来自协调节点的请求后,会将请求写入到 MemoryBuffer(jvm内存)
,然后定时(默认是每隔 1 秒)写入到 Filesystem Cache,这个从 MomeryBuffer 到 Filesystem Cache 的过程就叫做 refresh;
2、当然在某些情况下,存在 Momery Buffer 和 Filesystem Cache 的数据可能会丢失,ES 是通过 translog 的机制来保证数据的可靠性的。其实现机制是接收到请求后,同时也会写入到 translog 中,当 Filesystem cache 中的数据写入到磁盘中时,才会清除掉,这个过程叫做 flush;
3、在 flush 过程中,内存中的缓冲将被清除,内容被写入一个新段,段的 fsync将创建一个新的提交点,并将内容刷新到磁盘,旧的 translog 将被删除并开始一个新的 translog。
4、flush 触发的时机是定时触发(默认 30 分钟)或者 translog 变得太大(默认为 512M)时;
image补充:关于 Lucene 的 Segement:
1、Lucene 索引是由多个段组成,段本身是一个功能齐全的倒排索引。
2、段是不可变的,允许 Lucene 将新的文档增量地添加到索引中,而不用从头重建索引。
3、对于每一个搜索请求而言,索引中的所有段都会被搜索,并且每个段会消耗CPU 的时钟周、文件句柄和内存。这意味着段的数量越多,搜索性能会越低。
4、为了解决这个问题,Elasticsearch 会合并小段到一个较大的段,提交新的合并段到磁盘,并删除那些旧的小段。
6. 详细描述一下 Elasticsearch 更新和删除文档的过程。
1、删除和更新也都是写操作,但是 Elasticsearch 中的文档是不可变的,因此不能被删除或者改动以展示其变更;
2、磁盘上的每个段都有一个相应的.del 文件。当删除请求发送后,文档并没有真的被删除,而是在.del 文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。当段合并时,在.del 文件中被标记为删除的文档将不会被写入新段。
3、在新的文档被创建时,Elasticsearch 会为该文档指定一个版本号,当执行更新时,旧版本的文档在.del 文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。
7. 详细描述一下 Elasticsearch 搜索的过程?
1、搜索被执行成一个两阶段过程,我们称之为 Query Then Fetch;
2、在初始查询阶段时,查询会广播到索引中每一个分片拷贝(主分片或者副本分片)。每个分片在本地执行搜索并构建一个匹配文档的大小为 from + size 的优先队列。
PS:在搜索的时候是会查询 Filesystem Cache 的,但是有部分数据还在 MemoryBuffer,所以搜索是近实时的。
3、每个分片返回各自优先队列中 所有文档的 ID 和排序值 给协调节点,它合并这些值到自己的优先队列中来产生一个全局排序后的结果列表。
4、接下来就是 取回阶段,协调节点辨别出哪些文档需要被取回并向相关的分片提交多个 GET 请求。每个分片加载并 丰富 文档,如果有需要的话,接着返回文档给协调节点。一旦所有的文档都被取回了,协调节点返回结果给客户端
5、补充:Query Then Fetch 的搜索类型在文档相关性打分的时候参考的是本分片的数据,这样在文档数量较少的时候可能不够准确,DFS Query Then Fetch 增加了一个预查询的处理,询问 Term 和 Document frequency,这个评分更准确,但是性能会变差。
image8. 详细描述一下Elasticsearch搜索的过程?
面试官:想了解ES搜索的底层原理,不再只关注业务层面了。
p
解答:
搜索拆解为“query then fetch” 两个阶段。
query阶段的目的:定位到位置,但不取。
步骤拆解如下:
1)假设一个索引数据有5主+1副本 共10分片,一次请求会命中(主或者副本分片中)的一个。
2)每个分片在本地进行查询,结果返回到本地有序的优先队列中。
3)第2)步骤的结果发送到协调节点,协调节点产生一个全局的排序列表。
fetch阶段的目的:取数据。
路由节点获取所有文档,返回给客户端。
9. 详细描述一下Elasticsearch索引文档的过程?
面试官:想了解ES的底层原理,不再只关注业务层面了。
解答:
这里的索引文档应该理解为文档写入ES,创建索引的过程。
文档写入包含:单文档写入和批量bulk写入,这里只解释一下:单文档写入流程。
记住官方文档中的这个图。
image第一步:客户写集群某节点写入数据,发送请求。(如果没有指定路由/协调节点,请求的节点扮演路由节点的角色。)
第二步:节点1接受到请求后,使用文档_id来确定文档属于分片0。请求会被转到另外的节点,假定节点3。因此分片0的主分片分配到节点3上。
第三步:节点3在主分片上执行写操作,如果成功,则将请求并行转发到节点1和节点2的副本分片上,等待结果返回。所有的副本分片都报告成功,节点3将向协调节点(节点1)报告成功,节点1向请求客户端报告写入成功。
如果面试官再问:第二步中的文档获取分片的过程?
回答:借助路由算法获取,路由算法就是根据路由和文档id计算目标的分片id的过程。
shard = hash(_routing) % (num_of_primary_shards)
10. Elasticsearch 对于大数据量(上亿量级)的聚合如何实现?
Elasticsearch 提供的首个近似聚合是 cardinality 度量。它提供一个字段的基数,即该字段的 distinct 或者unique 值的数目。它是基于 HLL 算法的。HLL 会先对我们的输入作哈希运算,然后根据哈希运算的结果中的 bits 做概率估算从而得到基数。
其特点是:可配置的精度,用来控制内存的使用(更精确 = 更多内存);
小的数据集精度是非常高的;我们可以通过配置参数,来设置去重需要的固定内存使用量。无论数千还是数十亿的唯一值,内存使用量只与你配置的精确度相关。
11. 海量数据查询
详见https://mp.weixin.qq.com/s/fj7e1yrulW1knlSQ7F9M6g
转自
https://mp.weixin.qq.com/s/8u_S_pn7_etGsTGO7nenrg
Elasticsearch加入集群流程
https://blog.csdn.net/u011663071/article/details/83720934?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase
【Elasticsearch选主流程】https://blog.csdn.net/weixin_42257250/article/details/90230017
网友评论