ElasticSearch 问题分析:No data nodes with HTTP-enabled available

环境:ES-5.4.0版本,部署方式:3master+2client+3datanode

说明:datanode和client都配置了http.enabled: false,程序在写数据时报错:No data nodes with HTTP-enabled available

源码分析:

public static void filterNonDataNodesIfNeeded(Settings settings, Log log) {
    if (!settings.getNodesDataOnly()) {
        return;
    }

    RestClient bootstrap = new RestClient(settings);
    try  {
        String message = "No data nodes with HTTP-enabled available";
        List<NodeInfo> dataNodes = bootstrap.getHttpDataNodes();    // 找不到dataNodes就会报错
        if (dataNodes.isEmpty()) {
            throw new EsHadoopIllegalArgumentException(message);
        }
        ...
    } finally {
        bootstrap.close();
    }
}

接下来看看RestClient.getHttpDataNodes()方法的取值逻辑

public List<NodeInfo> getHttpDataNodes() {
    List<NodeInfo> nodes = getHttpNodes(false);  // 遍历上面获取到的节点
    Iterator<NodeInfo> it = nodes.iterator();
    while (it.hasNext()) {
        NodeInfo node = it.next();    // 如果不是数据节点,则移除
        if (!node.isData()) {
            it.remove();
        }
    }
    return nodes;
}
// 获取http节点_nodes/http
public List<NodeInfo> getHttpNodes(boolean clientNodeOnly) {  // 通过es接口“_nodes/http”来获取nodes的信息
    Map<String, Map<String, Object>> nodesData = get("_nodes/http", "nodes");
    List<NodeInfo> nodes = new ArrayList<NodeInfo>();

    for (Entry<String, Map<String, Object>> entry : nodesData.entrySet()) {
        NodeInfo node = new NodeInfo(entry.getKey(), entry.getValue());    // 如果不是查找client节点,则只要节点运行网络访问就可以add了;如果查找client节点,则还要通过isClient验证才能add
        if (node.hasHttp() && (!clientNodeOnly || node.isClient())) {
            nodes.add(node);
        }
    }
    return nodes;
}

最后再来看看node.hasHttp(),isClient(),isData()的方法

    private final String id;
    private final String name;
    private final String host;
    private final String ip;
    private final String publishAddress;
    private final boolean hasHttp;
    private final boolean isClient;
    private final boolean isData;
    private final boolean isIngest;

    public NodeInfo(String id, Map<String, Object> map) {
        this.id = id;
        EsMajorVersion version = EsMajorVersion.parse((String) map.get("version"));
        this.name = (String) map.get("name");
        this.host = (String) map.get("host");
        this.ip = (String) map.get("ip");    // 5.0以下版本的分支
        if (version.before(EsMajorVersion.V_5_X)) {
            Map<String, Object> attributes = (Map<String, Object>) map.get("attributes");
            if (attributes == null) {
                this.isClient = false;
                this.isData = true;
            } else {
                String data = (String) attributes.get("data");
                this.isClient = data == null ? true : !Boolean.parseBoolean(data);
                this.isData = data == null ? true : Boolean.parseBoolean(data);
            }
            this.isIngest = false;    // 5.0版本以上的分支
        } else {
            List<String> roles = (List<String>) map.get("roles");      // 如果roles列表中不包含"data",则此节点是client
            this.isClient = roles.contains("data") == false;      // 如果roles列表中包含"data",则此节点是data
            this.isData = roles.contains("data");      // 如果roles列表中包含"ingest",则此节点是ingest
            this.isIngest = roles.contains("ingest");
        }
        Map<String, Object> httpMap = (Map<String, Object>) map.get("http");    // 如果节点数据中包含key:http
        if (httpMap != null) {
            String addr = (String) httpMap.get("publish_address");      // 如果http数据中包含key:publish_address
            if (addr != null) {
                StringUtils.IpAndPort ipAndPort = StringUtils.parseIpAddress(addr);
                this.publishAddress = ipAndPort.ip + ":" + ipAndPort.port;        // 则此节点可以提供http服务,即:http.enabled: true
                this.hasHttp = true;
            } else {
                this.publishAddress = null;
                this.hasHttp = false;
            }
        } else {
            this.publishAddress = null;
            this.hasHttp = false;
        }
    }

从上面的源码分析可以得出:如果一个data节点不配置http.enabled:true,则此节点不会被getHttpDataNodes()方法搜索到,那么就会直接抛出异常:No data nodes with HTTP-enabled available

解决的方法无非两种:

第一:数据节点配置 http.enabled:true

第二:绕过filterNonDataNodesIfNeeded()校验,需要settings.getNodesDataOnly()返回false;看下面源码可知,默认es.nodes.data.only是true,在客户端中将其设置为false即可。

/** Clients only */
String ES_NODES_CLIENT_ONLY = "es.nodes.client.only";
String ES_NODES_CLIENT_ONLY_DEFAULT = "false";

/** Data only */
String ES_NODES_DATA_ONLY = "es.nodes.data.only";
String ES_NODES_DATA_ONLY_DEFAULT = "true";

/** Ingest only */
String ES_NODES_INGEST_ONLY = "es.nodes.ingest.only";
String ES_NODES_INGEST_ONLY_DEFAULT = "false";

/** WAN only */
String ES_NODES_WAN_ONLY = "es.nodes.wan.only";
String ES_NODES_WAN_ONLY_DEFAULT = "false";

...

public boolean getNodesDataOnly() {
    // by default, if not set, return a value compatible with the other settings  // 默认es.nodes.data.only是true,在客户端中将其设置为false即可
    return Booleans.parseBoolean(getProperty(ES_NODES_DATA_ONLY), !getNodesWANOnly() && !getNodesClientOnly() && !getNodesIngestOnly());
}

public boolean getNodesIngestOnly() {
    return Booleans.parseBoolean(getProperty(ES_NODES_INGEST_ONLY, ES_NODES_INGEST_ONLY_DEFAULT));
}

public boolean getNodesClientOnly() {
    return Booleans.parseBoolean(getProperty(ES_NODES_CLIENT_ONLY, ES_NODES_CLIENT_ONLY_DEFAULT));
}

public boolean getNodesWANOnly() {
    return Booleans.parseBoolean(getProperty(ES_NODES_WAN_ONLY, ES_NODES_WAN_ONLY_DEFAULT));
}
时间: 2024-10-10 05:23:21

ElasticSearch 问题分析:No data nodes with HTTP-enabled available的相关文章

docker elasticsearch挂载宿主机报 java.nio.file.AccessDeniedException: /usr/share/elasticsearch/data/nodes

① docker启动 es实例 docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \ -e "discovery.type=single-node" \ -e ES_JAVA_OPTS="-Xms64m -Xmx128m" \ -v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasti

ElasticSearch评分分析 explian 解释和一些查询理解

ElasticSearch评分分析 explian 解释和一些查询理解 按照es-ik分析器安装了ik分词器.然后创建了一个索引用来演示,创建索引:PUT /index_ik_test.索引的结构如下: GET index_ik_test/_mapping { "index_ik_test": { "mappings": { "fulltext": { "properties": { "content":

搭建办公环境ElasticSearch 日志分析系统

搭建办公环境ElasticSearch 日志分析系统 ? 计划将公司的防火墙+交换机+服务器(centos7)+ Vmware+Windows server纳入到监控范围,所以开启了ELK监控之旅. ? 本文采用ELK架构栈进行组建,万丈高楼平地起,虽然开始比较简陋,后期会不断完善这个日志分析系统. ? 全文框架如下: ? Hillstone: syslog→logstash→elasticsearch→kibana ? H3C: syslog→logstash→elasticsearch→ki

Elasticsearch启动分析与问题解决-bootstrap checks

[TOC] 0 说明 使用的es版本为5.6,Linux版本为CentOs 6.5. 1 Elasticsearch bootstrap checks 1.1 开发环境 如果在es的配置中没有配置network.host来指定一个可用的IP地址的话,默认情况下,就绑定到localhost上,此时es会认为用户只是在开发环境下使用es,基于开箱即用的原则,虽然es此时也会进行bootstrap checks,来检查用户的配置是否与es设定的安全值相匹配,如下: 如果匹配,则不会有warnning信

Elasticsearch master node、 data node、 client node的区别与各自特点

es集群里的master node.data node和client node到底是怎么个意思,分别有何特点? master节点 主要功能是维护元数据,管理集群各个节点的状态,数据的导入和查询都不会走master节点,所以master节点的压力相对较小,因此master节点的内存分配也可以相对少些:但是master节点是最重要的,如果master节点挂了或者发生脑裂了,你的元数据就会发生混乱,那样你集群里的全部数据可能会发生丢失,所以一定要保证master节点的稳定性. data node 是负

ElasticSearch Recovery 分析

上周出现了一次故障,recovery的过程比较慢,然后发现Shard 在做恢复的过程一般都是卡在TRANSLOG阶段,所以好奇这块是怎么完成的,于是有了这篇文章 这是一篇源码分析类的文章,大家需要先建立一个整体的概念,建议参看 这篇文章 另外你可能还需要了解下 Recovery 阶段迁移过程: INIT -> INDEX -> VERIFY_INDEX -> TRANSLOG -> FINALIZE -> DONE 概览 Recovery 其实有两种: Primary的迁移/

org.elasticsearch.transport.ReceiveTimeoutTransportException[cluster:monitor/nodes/liveness] request_id [31] timed out after [5000ms]

ES连接超时,异常信息 2017-09-07 10:42:45.042 [elasticsearch[Luna][generic][T#1]] INFO org.elasticsearch.client.transport - [Luna] failed to get node info for {#transport#-1}{192.168.1.100}{192.168.1.100:9300}, disconnecting... org.elasticsearch.transport.Rece

ElasticSearch 中 master、data 和 client 节点

在生产环境下,如果不修改elasticsearch节点的角色信息,在高数据量,高并发的场景下集群容易出现脑裂等问题. 默认情况下,elasticsearch 集群中每个节点都有成为主节点的资格,也都存储数据,还可以提供查询服务.这些功能是由两个属性控制的. 1. node.master 2. node.data 默认情况下这两个属性的值都是true. node.master:这个属性表示节点是否具有成为主节点的资格 注意:此属性的值为 true,并不意味着这个节点就是主节点.因为真正的主节点,是

Logstash与Elasticsearch日志分析系统搭建

logstash(1.4.2)是一个不错的日志监控与分析工具,数据通过logstash使用后端的ElasticSearch(1.1.1)集群完成数据索引,以供后续的查询.分析使用.版本必须保持兼容否则报一下错误 Upgrade Required Your version of Elasticsearch is too old. Kibana requires Elasticsearch 0.90.9 or above. Error Could not reach http://182.92.7.