iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >elasticsearch集群发现zendiscovery的Ping机制分析
  • 932
分享到

elasticsearch集群发现zendiscovery的Ping机制分析

2024-04-02 19:04:59 932人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录 zenDiscovery实现机制广播的过程nodeping处理代码ping请求的发送策略总结 zenDiscovery实现机制 ping是集群发现的基本手段

 zenDiscovery实现机制

ping是集群发现的基本手段,通过在网络上广播或者指定ping某些节点获取集群信息,从而可以找到集群的master加入集群。zenDiscovery实现了两种ping机制:广播与单播。本篇将详细分析一些这MulticastZenPing机制的实现为后面的集群发现和master选举做好铺垫。

广播的过程

首先看一下广播(MulticastZenPing),广播的原理很简单,节点启动后向网络发送广播信息,任何收到的节点只要集群名字相同都应该对此广播信息作出回应。这样该节点就获取了集群的相关信息。它定义了一个action:"internal:discovery/zen/multicast"和广播的信息头:INTERNAL_HEADER 。之前说过NettyTransport是cluster通信的基础,但是广播却没有使它。它使用了java的MulticastSocket。这里简单的介绍一下MulticastSocket的使用。它是一个UDP 机制的socket,用来进行多个数据包的广播。它可以帮到一个ip形成一个group,任何MulticastSocket都可以join进来,组内的socket发送的信息会被订阅了改组的所有机器接收到。elasticsearch对其进行了封装形成了MulticastChannel,有兴趣可以参考相关源码。 

首先看一下MulticastZenPing的几个辅助内部类:

它总共定义了4个内部类,这些内部类和它一起完成广播功能。FinalizingPinGCollection是一pingresponse的容器,所有的响应都用它来存储。MulticastPingResponseRequestHandler它是response处理类,类似于之前所说的nettytransportHandler,它虽然使用的不是netty,但是它也定义了一个messageReceived的方法,当收到请求时直接返回一个response。

MulticastPingResponse就不用细说了,它就是一个响应类。最后要着重说一下Receiver类,因为广播并不是使用NettyTransport,因此对于消息处理逻辑都在Receiver中。在初始化MulticastZenPing时会将receiver注册进去。

protected void doStart() throws ElasticsearchException {
        try {
            ....
            multicastChannel = MulticastChannel.getChannel(nodeName(), shared,
                    new MulticastChannel.Config(port, group, bufferSize, ttl, networkService.resolvePublishHostAddress(address)),
                    new Receiver());//将receiver注册到channel中
        } catch (Throwable t) {
          ....
        }
    }

Receiver类基础了Listener,实现了3个方法,消息经过onMessage方法区分,如果是内部ping则使用handleNodePingRequest方法处理,否则使用handleExternalPingRequest处理,区分方法很简单,就是读取信息都看它是否符合所定义的INTERNAL_HEADER 信息头。

nodeping处理代码

private void handleNodePingRequest(int id, DiscoveryNode requestingNodeX, ClusterName requestClusterName) {
           ....
            final DiscoveryNodes discoveryNodes = contextProvider.nodes();
            final DiscoveryNode requestingNode = requestingNodeX;
            if (requestingNode.id().equals(discoveryNodes.localNodeId())) {
                // 自身发出的ping,忽略
                return;
            }
        //只接受本集群ping
            if (!requestClusterName.equals(clusterName)) {
            ...return;
            }
            // 两个client间不需要ping
            if (!discoveryNodes.localNode().shouldConnectTo(requestingNode)) {return;
            }
        //新建一个response
            final MulticastPingResponse multicastPingResponse = new MulticastPingResponse();
            multicastPingResponse.id = id;
            multicastPingResponse.pingResponse = new PingResponse(discoveryNodes.localNode(), discoveryNodes.masterNode(), clusterName, contextProvider.nodeHasJoinedClusterOnce());
        //无法连接的情况
            if (!transportService.nodeConnected(requestingNode)) {
                // do the connect and send on a thread pool
                threadPool.generic().execute(new Runnable() {
                    @Override
                    public void run() {
                        // connect to the node if possible
                        try {
                            transportService.connectToNode(requestingNode);
                            transportService.sendRequest(requestingNode, ACTION_NAME, multicastPingResponse, new EmptyTransportResponseHandler(ThreadPool.Names.SAME) {
                                @Override
                                public void handleException(TransportException exp) {
                                    logger.warn("failed to receive confirmation on sent ping response to [{}]", exp, requestingNode);
                                }
                            });
                        } catch (Exception e) {
                            if (lifecycle.started()) {
                                logger.warn("failed to connect to requesting node {}", e, requestingNode);
                            }
                        }
                    }
                });
            } else {
                transportService.sendRequest(requestingNode, ACTION_NAME, multicastPingResponse, new EmptyTransportResponseHandler(ThreadPool.Names.SAME) {
                    @Override
                    public void handleException(TransportException exp) {
                        if (lifecycle.started()) {
                            logger.warn("failed to receive confirmation on sent ping response to [{}]", exp, requestingNode);
                        }
                    }
                });
            }
        }
    }

另外的一个方法是处理外部ping信息,处理过程是返回cluster的信息(这种外部ping的具体作用没有研究不是太清楚)。以上是响应MulticastZenPing的过程,收到其它节点的响应信息后它会把本节点及集群的master节点相关信息返回给广播节点。这样广播节点就获知了集群的相关信息。在MulticastZenPing类中还有一个类 MulticastPingResponseRequestHandler,它的作用是广播节点对其它节点对广播信息响应的回应,广播节点的第二次发送信息的过程。它跟其它TransportRequestHandler一样它有messageReceived方法,在启动时注册到transportserver中,只处理一类action:"internal:discovery/zen/multicast"。

ping请求的发送策略

代码如下:

public void ping(final PingListener listener, final TimeValue timeout) {
       ....
    //产生一个id
        final int id = pingIdGenerator.incrementAndGet();
        try {
            receivedResponses.put(id, new PingCollection());
            sendPingRequest(id);//第一次发送ping请求
            // 等待时间的1/2后再次发送一个请求
            threadPool.schedule(TimeValue.timeValueMillis(timeout.millis() / 2), ThreadPool.Names.GENERIC, new AbstractRunnable() {
                @Override
                public void onFailure(Throwable t) {
                    logger.warn("[{}] failed to send second ping request", t, id);
                    finalizePingCycle(id, listener);
                }
                @Override
                public void doRun() {
                    sendPingRequest(id);
            //再过1/2时间再次发送一个请求
                    threadPool.schedule(TimeValue.timeValueMillis(timeout.millis() / 2), ThreadPool.Names.GENERIC, new AbstractRunnable() {
                        @Override
                        public void onFailure(Throwable t) {
                            logger.warn("[{}] failed to send third ping request", t, id);
                            finalizePingCycle(id, listener);
                        }
                        @Override
                        public void doRun() {
                            // make one last ping, but finalize as soon as all nodes have responded or a timeout has past
                            PingCollection collection = receivedResponses.get(id);
                            FinalizingPingCollection finalizingPingCollection = new FinalizingPingCollection(id, collection, collection.size(), listener);
                            receivedResponses.put(id, finalizingPingCollection);
                            logger.trace("[{}] sending last pings", id);
                            sendPingRequest(id);
                //最后一次发送请求,超时的1/4后
                            threadPool.schedule(TimeValue.timeValueMillis(timeout.millis() / 4), ThreadPool.Names.GENERIC, new AbstractRunnable() {
                                @Override
                                public void onFailure(Throwable t) {
                                    logger.warn("[{}] failed to finalize ping", t, id);
                                }
                                @Override
                                protected void doRun() throws Exception {
                                    finalizePingCycle(id, listener);
                                }
                            });
                        }
                    });
                }
            });
        } catch (Exception e) {
            logger.warn("failed to ping", e);
            finalizePingCycle(id, listener);
        }
    }

发送过程主要是调用sendPingRequest(id)方法,在该方法中会将id,信息头,版本,本地节点信息一起写入到BytesStreamOutput中然后将其进行广播,这个广播信息会被其它机器上的Receiver接收并处理,并且响应该ping请求。另外一个需要关注的是以上加说明的部分,它通过链时的定期发送请求,在等待时间内可能会发出4次请求,这种发送方式会造成大量的ping请求重复,幸好ping的资源消耗小,但是好处是可以尽可能保证在timeout这个时间段内集群的新增节点都能收到这个ping信息。在单播中也采用了该策略。

总结

广播的过程:广播使用的是jdk的MulticastSocket,在timeout时间内4次发生ping请求,ping请求包括一个id,信息头,本地节点的一些信息;这些信息在其它节点中被接收到交给Receiver处理,Receiver会将集群的master和本机的相关信息通过transport返回给广播节点。广播节点收到这些信息后会理解使用transport返回一个空的response。至此一个广播过程完成。

在节点分布在多个网段时,广播就失效了,因为广播信息不可达。这个时间就需要使用单播去ping指定的节点获取cluster的相关信息。这就是单播的用处。单播使用的是NettyTransport,它会使用跟广播一样的链式请求向指定的节点发送请求。信息的处理方式是之前所介绍的NettyTransport标准的信息处理过程。

以上就是elasticsearch集群发现zendiscovery的Ping机制分析的详细内容,更多关于elasticsearch集群发现zendiscovery Ping的资料请关注编程网其它相关文章!

--结束END--

本文标题: elasticsearch集群发现zendiscovery的Ping机制分析

本文链接: https://www.lsjlt.com/news/146824.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • elasticsearch集群发现zendiscovery的Ping机制分析
    目录 zenDiscovery实现机制广播的过程nodeping处理代码ping请求的发送策略总结 zenDiscovery实现机制 ping是集群发现的基本手段...
    99+
    2024-04-02
  • elasticsearch集群zendiscovery的Ping机制是什么
    这篇文章主要介绍“elasticsearch集群zendiscovery的Ping机制是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“elasticsearch集群zendiscovery的Pi...
    99+
    2023-06-30
  • elasticsearch的zenDiscovery和master选举机制原理分析
    目录前言join的代码findMaster方法总结前言 上一篇通过 ElectMasterService源码,分析了master选举的原理的大部分内容:master候选节点...
    99+
    2024-04-02
  • elasticsearch-2.1.1集群搭建的示例分析
    这篇文章主要为大家展示了“elasticsearch-2.1.1集群搭建的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“elasticsearch-2....
    99+
    2024-04-02
  • redis主从复制、哨兵和集群的示例分析
    这篇文章主要介绍了redis主从复制、哨兵和集群的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、主从复制1. 主从同步的用处  ...
    99+
    2024-04-02
  • Redis中主从复制、哨兵、集群的示例分析
    这篇文章将为大家详细讲解有关Redis中主从复制、哨兵、集群的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、Redis 主从复制1. 主从复制的概述主从复制,...
    99+
    2024-04-02
  • elasticsearch的灵魂唯一master选举机制原理分析
    master作为cluster的灵魂必须要有,还必须要唯一,否则集群就出大问题了。因此master选举在cluster分析中尤为重要。对于这个问题我将分两篇来分析。第一篇也就是本篇,...
    99+
    2024-04-02
  • 深入剖析MongoDB的复制集与分片集群的搭建与优化
    深入剖析MongoDB的复制集与分片集群的搭建与优化概述在大规模应用程序中,数据存储和管理是至关重要的。MongoDB作为一种非关系数据库解决方案,广泛用于处理大规模数据集和高负载应用程序的需求。MongoDB的数据复制和分片功能让用户能够...
    99+
    2023-11-04
    - MongoDB - 复制集 - 分片集群
  • CocosCreator消息分发机制的示例分析
    这篇文章将为大家详细讲解有关CocosCreator消息分发机制的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。概述本篇开始介绍游戏业务架构相关的内容。在游戏业务层,所有需要隔离的系统和模块间通信...
    99+
    2023-06-14
  • PHP中垃圾收集机制的示例分析
    这篇文章主要为大家展示了“PHP中垃圾收集机制的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“PHP中垃圾收集机制的示例分析”这篇文章吧。PHP的垃圾收...
    99+
    2024-04-02
  • 从容应对高并发:MySQL主从复制作为集群技术的性能优势分析
    从容应对高并发:MySQL主从复制作为集群技术的性能优势分析随着互联网的快速发展,用户对于网站和应用的访问量呈现出爆炸性增长的趋势。在这种高并发的情况下,如何保证系统的稳定性和性能成为了每个开发人员和系统管理员的重要任务。在数据库中,MyS...
    99+
    2023-10-22
    高并发 MySQL主从复制 性能优势
  • AndroidView的事件分发机制深入分析讲解
    目录1.分发对象-MotionEvent2.如何传递事件1.传递流程2.事件分发的源码解析1.Activity对点击事件的分发过程2.顶级View对点击事件的分发过程3.主要方法4....
    99+
    2023-01-29
    Android View事件分发机制 Android事件分发
  • 解密MySQL主从复制:揭秘其集群模式下的关键实现机制
    解密MySQL主从复制:揭秘其集群模式下的关键实现机制引言:在现代数据库系统中,数据的高可用性和灵活性是非常重要的。MySQL作为一款开源的关系型数据库管理系统,在满足用户需求方面具有广泛的应用性。而MySQL的主从复制是MySQL数据库架...
    99+
    2023-10-22
    集群模式 MySQL主从复制 关键实现机制
  • CentOS 6.5下ZooKeeper3.4.6集群环境部署及单机部署的示例分析
    小编给大家分享一下CentOS 6.5下ZooKeeper3.4.6集群环境部署及单机部署的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!【系统】Cent...
    99+
    2023-06-03
  • MongoDB技术开发中遇到的集群管理问题解决方案分析
    MongoDB技术开发中遇到的集群管理问题解决方案分析摘要:随着大数据和云计算的快速发展,MongoDB作为一种流行的非关系型数据库,被广泛应用于大规模数据存储和处理的场景中。然而,在实际的开发过程中,MongoDB集群管理问题成为开发者面...
    99+
    2023-10-22
    集群管理 MongoDB技术 解决方案分析
  • 分析Android微信小程序开发的运行机制
    这篇文章主要讲解了“分析Android微信小程序开发的运行机制”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“分析Android微信小程序开发的运行机制”吧!...
    99+
    2024-04-02
  • Linux共享内存实现机制的示例分析
    这篇文章将为大家详细讲解有关Linux共享内存实现机制的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Linux共享内存实现机制的详解内存共享: 两个不同进程A、B共享内存的意思是,同一块物理内存...
    99+
    2023-06-09
  • C#开发中事件与委托机制的示例分析
    这篇文章给大家分享的是有关C#开发中事件与委托机制的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。概述C#中的委托类似于C或C++中的函数指针。使用委托使程序员可以将方法引用封装在委托对象内。然后可以将该...
    99+
    2023-06-17
  • Flex事件机制中Flex事件分发和监听的示例分析
    这篇文章给大家分享的是有关Flex事件机制中Flex事件分发和监听的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。什么是Flex事件机制Flex事件可以看作是一种触发机制,当满足了一定的条件后,会触发这个...
    99+
    2023-06-17
  • 深入浅析Android项目中的 View事件分发机制
    本篇文章为大家展示了深入浅析Android项目中的 View事件分发机制,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。具体方法如下:public class MyButton extends But...
    99+
    2023-05-31
    view roi 目中
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作