本文主要研究一下Elasticsearch RestClient的NodeSelector

NodeSelector

elasticsearch-7.0.1/client/rest/src/main/java/org/elasticsearch/client/NodeSelector.java

public interface NodeSelector {    /**     * Select the {@link Node}s to which to send requests. This is called with     * a mutable {@link Iterable} of {@linkplain Node}s in the order that the     * rest client would prefer to use them and implementers should remove     * nodes from the that should not receive the request. Implementers may     * iterate the nodes as many times as they need.     * <p>     * This may be called twice per request: first for "living" nodes that     * have not been blacklisted by previous errors. If the selector removes     * all nodes from the list or if there aren't any living nodes then the     * {@link RestClient} will call this method with a list of "dead" nodes.     * <p>     * Implementers should not rely on the ordering of the nodes.     */    void select(Iterable<Node> nodes);    /*     * We were fairly careful with our choice of Iterable here. The caller has     * a List but reordering the list is likely to break round robin. Luckily     * Iterable doesn't allow any reordering.     */    /**     * Selector that matches any node.     */    NodeSelector ANY = new NodeSelector() {        @Override        public void select(Iterable<Node> nodes) {            // Intentionally does nothing        }        @Override        public String toString() {            return "ANY";        }    };    /**     * Selector that matches any node that has metadata and doesn't     * have the {@code master} role OR it has the data {@code data}     * role.     */    NodeSelector SKIP_DEDICATED_MASTERS = new NodeSelector() {        @Override        public void select(Iterable<Node> nodes) {            for (Iterator<Node> itr = nodes.iterator(); itr.hasNext();) {                Node node = itr.next();                if (node.getRoles() == null) continue;                if (node.getRoles().isMasterEligible()                        && false == node.getRoles().isData()                        && false == node.getRoles().isIngest()) {                    itr.remove();                }            }        }        @Override        public String toString() {            return "SKIP_DEDICATED_MASTERS";        }    };}
  • NodeSelector接口定义了select方法,它接收mutable的Iterable,然后具体实现会选择性删除node;它定义了ANY、SKIP_DEDICATED_MASTERS两个匿名实现类,其中ANY的select方法不做任何操作;SKIP_DEDICATED_MASTERS的select方法会删除date为false、ingest为false的master node;除此之外还有HasAttributeNodeSelector、PreferHasAttributeNodeSelector两个实现类

HasAttributeNodeSelector

elasticsearch-7.0.1/client/rest/src/main/java/org/elasticsearch/client/HasAttributeNodeSelector.java

public final class HasAttributeNodeSelector implements NodeSelector {    private final String key;    private final String value;    public HasAttributeNodeSelector(String key, String value) {        this.key = key;        this.value = value;    }    @Override    public void select(Iterable<Node> nodes) {        Iterator<Node> itr = nodes.iterator();        while (itr.hasNext()) {            Map<String, List<String>> allAttributes = itr.next().getAttributes();            if (allAttributes == null) continue;            List<String> values = allAttributes.get(key);            if (values == null || false == values.contains(value)) {                itr.remove();            }        }    }    @Override    public boolean equals(Object o) {        if (this == o) {            return true;        }        if (o == null || getClass() != o.getClass()) {            return false;        }        HasAttributeNodeSelector that = (HasAttributeNodeSelector) o;        return Objects.equals(key, that.key) &&                Objects.equals(value, that.value);    }    @Override    public int hashCode() {        return Objects.hash(key, value);    }    @Override    public String toString() {        return key + "=" + value;    }}
  • HasAttributeNodeSelector实现了NodeSelector接口,其构造器接收key、value参数,其select方法会删除node的attributes没有该key或者该key对应的value为null的node

PreferHasAttributeNodeSelector

elasticsearch-7.0.1/client/rest/src/main/java/org/elasticsearch/client/PreferHasAttributeNodeSelector.java

public final class PreferHasAttributeNodeSelector implements NodeSelector {    private final String key;    private final String value;    public PreferHasAttributeNodeSelector(String key, String value) {        this.key = key;        this.value = value;    }    @Override    public void select(Iterable<Node> nodes) {        boolean foundAtLeastOne = false;        for (Node node : nodes) {            Map<String, List<String>> attributes = node.getAttributes();            if (attributes == null) {                continue;            }            List<String> values = attributes.get(key);            if (values == null) {                continue;            }            if (values.contains(value)) {                foundAtLeastOne = true;                break;            }        }        if (foundAtLeastOne) {            Iterator<Node> nodeIterator = nodes.iterator();            while (nodeIterator.hasNext()) {                Map<String, List<String>> attributes = nodeIterator.next().getAttributes();                if (attributes == null) {                    continue;                }                List<String> values = attributes.get(key);                if (values == null || !values.contains(value)) {                    nodeIterator.remove();                }            }        }    }    @Override    public boolean equals(Object o) {        if (this == o) {            return true;        }        if (o == null || getClass() != o.getClass()) {            return false;        }        PreferHasAttributeNodeSelector that = (PreferHasAttributeNodeSelector) o;        return Objects.equals(key, that.key) &&            Objects.equals(value, that.value);    }    @Override    public int hashCode() {        return Objects.hash(key, value);    }    @Override    public String toString() {        return key + "=" + value;    }}
  • PreferHasAttributeNodeSelector实现了NodeSelector接口,其构造器接收key、value参数,其select方法会先遍历nodes设置foundAtLeastOne,如果foundAtLeastOne为true才会删除node的attributes没有该key或者该key对应的value为null的node

小结

  • NodeSelector接口定义了select方法,它接收mutable的Iterable,然后具体实现会选择性删除node;它定义了ANY、SKIP_DEDICATED_MASTERS两个匿名实现类,其中ANY的select方法不做任何操作;SKIP_DEDICATED_MASTERS的select方法会删除date为false、ingest为false的master node
  • HasAttributeNodeSelector实现了NodeSelector接口,其构造器接收key、value参数,其select方法会删除node的attributes没有该key或者该key对应的value为null的node
  • PreferHasAttributeNodeSelector实现了NodeSelector接口,其构造器接收key、value参数,其select方法会先遍历nodes设置foundAtLeastOne,如果foundAtLeastOne为true才会删除node的attributes没有该key或者该key对应的value为null的node

doc

  • Node selector