千家信息网

elasticsearch怎么实现客户端负载均衡

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,本篇内容介绍了"elasticsearch怎么实现客户端负载均衡"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够
千家信息网最后更新 2026年11月03日elasticsearch怎么实现客户端负载均衡

本篇内容介绍了"elasticsearch怎么实现客户端负载均衡"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

客户端负载均衡技术是,客户端维护一组服务器引用,每次客户端请求的时候,会根据负载均衡算法选中一个节点,发送请求。常用的负载算法有Random,Round robin,Hash,StaticWeighted等。ES的客户端负载使用了Round robin算法。(另外Hash一致性算法还会在另一地方遇见的)一个Count请求的整个客户端模块的调用流程是

简化的调用流程
  1. client 提供了客户端的操作接口,比如count()

  2. nodesService的execute()随机一个节点出来

  3. Proxy代理通过transportService发送请求

一些初始化的事情

我们先看下创建客户端的代码,这里配置了几个配置项

Settings settings = ImmutableSettings.settingsBuilder()            .put("cluster.name", "myClusterName")            .put("client.transport.sniff", true).build();client=new TransportClient(settings)    .addTransportAddress(new InetSocketTransportAddress("localhost",9300));

谁会在乎这些配置项呢,就是TransportClientNodesService类。它负责着嗅探,维护集群节点列表。选举节点。它的构造方法里做了一些初始化工作

        this.nodesSamplerInterval = componentSettings.getAsTime("nodes_sampler_interval", timeValueSeconds(5));        this.pingTimeout = componentSettings.getAsTime("ping_timeout", timeValueSeconds(5)).millis();        this.ignoreClusterName = componentSettings.getAsBoolean("ignore_cluster_name", false);        //.....        if (componentSettings.getAsBoolean("sniff", false)) {            this.nodesSampler = new SniffNodesSampler();        } else {            this.nodesSampler = new SimpleNodeSampler();        }        this.nodesSamplerFuture = threadPool.schedule(nodesSamplerInterval, ThreadPool.Names.GENERIC, new ScheduledNodeSampler());
  • nodes_sampler_interval 嗅探集群节点的间隔,默认5秒

  • pingTimeout Ping节点的超时时间,默认是5秒

  • ignoreClusterName 忽略集群名称,集群验证的时候

  • sniff 是否开启集群嗅探

另外TransportClientNodesService维护着2个列表,集群节点列表nodes和监听列表listedNodes。其中监听列表就是通过TransportClient.addTransportAddress()增加的节点列表。

嗅探集群节点
    interface NodeSampler {        void sample();    }

NodeSampler接口很简单,只有一个sample()方法,它的实现类有2个SniffNodesSampler和SimpleNodeSampler,我们在初始化里已经看到了,如果"sniff"配置项是true的话使用SniffNodesSampler类。它们2个的实现逻辑是

  • SimpleNodeSampler

    • 循环listedNodes列表里的每一个节点

    • 没有连接就连接到这个节点

    • 发送"cluster/nodes/info"请求获取节点的集群名称,需要的话,做集群名验证。

    • 增加到nodes节点列表

  • SniffNodesSampler

    • 创建一个listedNodes和nodes去重后的列表nodesToPing

    • 循环nodesToPing里的每一个节点

    • 没有连接就连接到这个节点,如果是nodes列表的就正常连接,listedNode列表的建立个轻连接就好了

    • 发送"cluster/state"请求获取节点的状态,这里会有集群所有的数据节点dataNodes

    • 再次确认下已经和所有节点建立连接

    • 增加到nodes节点列表

我们可以发现SimpleNodeSampler最终的节点列表还是listedNodes,如果我们建立客户端的时候,只添加了一个localhost,那它所有的请求都会发送到localhost。只有SniffNodesSampler才去探测集群的所有节点。也就是SimpleNodeSampler的意图是让集群中的某些个节点,专门用于接受用户请求。SniffNodesSampler的话,所有节点都会参与负载。

class ScheduledNodeSampler implements Runnable {        @Override        public void run() {            try {                nodesSampler.sample();                if (!closed) {                    nodesSamplerFuture = threadPool.schedule(nodesSamplerInterval, ThreadPool.Names.GENERIC, this);                }            } catch (Exception e) {                logger.warn("failed to sample", e);            }        }}

ScheduledNodeSampler线程启动后,Sampler就开始忙碌起来了。

选举节点

有了集群节点列表后execute()方法就可以通过轮询调度算法Round robin,选举节点了。算法的特点是实现起来简单优雅,请求会被均衡的发送到各个节点上。

public  T execute(NodeCallback callback) throws ElasticSearchException {        ImmutableList nodes = this.nodes;        if (nodes.isEmpty()) {            throw new NoNodeAvailableException();        }        int index = randomNodeGenerator.incrementAndGet();        if (index < 0) {            index = 0;            randomNodeGenerator.set(0);        }        for (int i = 0; i < nodes.size(); i++) {            DiscoveryNode node = nodes.get((index + i) % nodes.size());            try {                return callback.doWithNode(node);            } catch (ElasticSearchException e) {                if (!(e.unwrapCause() instanceof ConnectTransportException)) {                    throw e;                }            }        }        throw new NoNodeAvailableException();}

关键是这一行代码,说那么多话,其实,我只是了为了这么,一行代码啊 ?

DiscoveryNode node = nodes.get((index + i) % nodes.size());

    "elasticsearch怎么实现客户端负载均衡"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

    节点 集群 客户 客户端 算法 均衡 配置 代码 方法 时候 端的 选举 一行 内容 只有 名称 就是 接口 更多 流程 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网黑科技 广州淘业互联网络科技 互联网科技工作委员会 互联网科技工作委员会毛军 互联网科技有限公司经营范围 工业互联网科技新基建 礼当家互联网科技 远信互联网科技 极限挑战互联网科技 滨湖区互联网智能科技产品供应 深圳市运趣互联网科技有限公司 成都互联网科技公司100强 银川新华互联网科技职业技术培训学校图片 中国互联网公司排名锤子科技 保险科技服务互联网营销体系 银行科技岗属于互联网吗 上海同邻互联网科技有限公司规模 互联网界的黑科技 互联网时代高科技布局 上海互联网科技园景观 互联网金融 金融科技 狮子座互联网科技 互联网科技视频 四川狮子座互联网科技 互联网科技如何创业 科技赋能视角下互联网保险发展 互联网界的黑科技 银川新华互联网科技学校是国营吗 互联网科技的前景 重庆科技产业互联网有哪些
    0