ES aprender notas -ClusterState de aprendizagem

Estudamos a frente ES de get apitoda a idéia como uma referência ao escrever plug-ES. Naquele tempo o foco na compreensão do processo global, principalmente shardOperation()a lógica interna da chamada do método, ele enfraqueceu shards()método. Na verdade shards()método em compreender os ES nível estrutural, papel maior. Nós ainda, get apipara entender o início shards().

Primeiro, olhe para get apio uso do processo:

 添加文档到ES:
 curl -XPUT 'http://localhost:9200/test1/type1/1' -d '{"name":"hello"}'

 根据文档ID读取数据:
 curl -XGET 'http://localhost:9200/test1/type1/1' 

Muito simples de usar. Mas se distribuídos lógica por trás tendo em conta não é simples. Se aglomerado ES tem três nós, onde o índice de dados tem três fragmentos, uma cópia de cada fatia. Esse índice é definido da seguinte forma:

{
  "test1" : {
    "settings" : {
      "index" : {
        "number_of_replicas" : "1",
        "number_of_shards" : "3"
      }
    }
  }
}

Assim, com id doc 1 desta distribuição para essa fatia dele? Esta questão precisa de um blog resposta detalhada, onde nós primeiro dar uma conclusão simples:

默认情况下,ES会按照文档id计算一个hash值, 采用的是Murmur3HashFunction,然后根据这个id跟分片数取模。实现代码是MathUtils.mod(hash, indexMetaData.getNumberOfShards()); 最后的结果作为文档所在的分片id,所以ES的分片标号是从0开始的。

Eu não sei existir, como você pode saber a tomar.

E depois resolver os principais processos de acesso aos dados:

s1: 根据文档id定位到数据所在分片。由于可以设为多个副本,所以一个分片会映射到多个节点。

s2: 根据分片节点的映射信息,选择一个节点,去获取数据。 这里重点关注的是节点的选择方式,简而言之,我们需要负载均衡,不然设置副本就没有意义了。

Os dois passos acima está associada com uma estrutura de dados de núcleo ClusterState, que pode utilizar _cluster/state?prettypara visualizar esta estrutura de dados:

# http://localhost:9200/_cluster/state?pretty

{
  "cluster_name" : "elasticsearch",
  "version" : 4,
  "state_uuid" : "b6B739p5SbanNLyKxTMHfQ",
  "master_node" : "KnEE25tzRjaXblFJq5jqRA",
  "blocks" : { },
  "nodes" : {
    "KnEE25tzRjaXblFJq5jqRA" : {
      "name" : "Mysterio",
      "transport_address" : "127.0.0.1:9300",
      "attributes" : { }
    }
  },
  "metadata" : {
    "cluster_uuid" : "ZIl7g86YRiGv8Dqz4DCoAQ",
    "templates" : { },
    "indices" : {
      "test1" : {
        "state" : "open",
        "settings" : {
          "index" : {
            "creation_date" : "1553995485603",
            "uuid" : "U7v5t_T7RG6rNU3JlGCCBQ",
            "number_of_replicas" : "1",
            "number_of_shards" : "1",
            "version" : {
              "created" : "2040599"
            }
          }
        },
        "mappings" : { },
        "aliases" : [ ]
      }
    }
  },
  "routing_table" : {
    "indices" : {
      "test1" : {
        "shards" : {
          "0" : [ {
            "state" : "STARTED",
            "primary" : true,
            "node" : "KnEE25tzRjaXblFJq5jqRA",
            "relocating_node" : null,
            "shard" : 0,
            "index" : "test1",
            "version" : 2,
            "allocation_id" : {
              "id" : "lcSHbfWDRyOKOhXAf3HXLA"
            }
          }, {
            "state" : "UNASSIGNED",
            "primary" : false,
            "node" : null,
            "relocating_node" : null,
            "shard" : 0,
            "index" : "test1",
            "version" : 2,
            "unassigned_info" : {
              "reason" : "INDEX_CREATED",
              "at" : "2019-03-31T01:24:45.845Z"
            }
          } ]
        }
      }
    }
  },
  "routing_nodes" : {
    "unassigned" : [ {
      "state" : "UNASSIGNED",
      "primary" : false,
      "node" : null,
      "relocating_node" : null,
      "shard" : 0,
      "index" : "test1",
      "version" : 2,
      "unassigned_info" : {
        "reason" : "INDEX_CREATED",
        "at" : "2019-03-31T01:24:45.845Z"
      }
    } ],
    "nodes" : {
      "KnEE25tzRjaXblFJq5jqRA" : [ {
        "state" : "STARTED",
        "primary" : true,
        "node" : "KnEE25tzRjaXblFJq5jqRA",
        "relocating_node" : null,
        "shard" : 0,
        "index" : "test1",
        "version" : 2,
        "allocation_id" : {
          "id" : "lcSHbfWDRyOKOhXAf3HXLA"
        }
      } ]
    }
  }
}

Toda a estrutura é mais complexo, que são desmontagem lentamente, passo a passo, uma por uma pausa. Partindo da idéia de desmantelamento ou a utilização de cenários.

  1. IndexMetaData aprender
    metaData o seguinte formato:
    "metadata" : {
    "cluster_uuid" : "ZIl7g86YRiGv8Dqz4DCoAQ",
    "templates" : { },
    "indices" : {
      "test1" : {
        "state" : "open",
        "settings" : {
          "index" : {
            "creation_date" : "1553995485603",
            "uuid" : "U7v5t_T7RG6rNU3JlGCCBQ",
            "number_of_replicas" : "1",
            "number_of_shards" : "1",
            "version" : {
              "created" : "2040599"
            }
          }
        },
        "mappings" : { },
        "aliases" : [ ]
      }
    }
    }

Que os metadados é armazenado num estado em que o conjunto de cada fatia e o índice do número de cópias, o índice, o mapeamento de índice, pseudónimos de índice. Esta configuração pode fornecer essa função para fora 根据索引名称获取索引元数据, como se segue:

# OperationRouting.generateShardId()

        IndexMetaData indexMetaData = clusterState.metaData().index(index);
        if (indexMetaData == null) {
            throw new IndexNotFoundException(index);
        }
        final Version createdVersion = indexMetaData.getCreationVersion();
        final HashFunction hashFunction = indexMetaData.getRoutingHashFunction();
        final boolean useType = indexMetaData.getRoutingUseType();

Nossa preocupação aqui é que clusterState.metaData().index(index)este código, ele implementa 根据索引名称获取索引元数据的功能. Pelo número de metadados fragmentados de ligação ID do documento, que será capaz de localizar os fragmentos das reside documentos. Esta função Excluir, Index, Get três da API são necessárias. Aqui podemos entender por que o número de índice de fragmentação não pode ser modificado ES: Se você tiver modificado, em seguida, a função hash não seria capaz localizar os dados corretos onde a fragmentação.

  1. aprendizagem IndexRoutingTable
"routing_table" : {
    "indices" : {
      "test1" : {
        "shards" : {
          "0" : [ {
            "state" : "STARTED",
            "primary" : true,
            "node" : "KnEE25tzRjaXblFJq5jqRA",
            "relocating_node" : null,
            "shard" : 0,
            "index" : "test1",
            "version" : 2,
            "allocation_id" : {
              "id" : "lcSHbfWDRyOKOhXAf3HXLA"
            }
          }, {
            "state" : "UNASSIGNED",
            "primary" : false,
            "node" : null,
            "relocating_node" : null,
            "shard" : 0,
            "index" : "test1",
            "version" : 2,
            "unassigned_info" : {
              "reason" : "INDEX_CREATED",
              "at" : "2019-03-31T01:24:45.845Z"
            }
          } ]
        }
      }
    }
  }

routing_tableFragmentação de informações armazenadas para cada índice, por essa estrutura, podemos entender claramente as seguintes informações:

1. 索引分片在各个节点的分布
2. 索引分片是否为主分片

Se uma fatia tem duas cópias, e são alocados em um nó diferente, get apium total de três nós de dados para escolher, escolher qual deles fazer? Aqui não considerar com preferenceparâmetros.
Para fazer com que cada nó pode razoavelmente ser selecionado para alcançar carga fins de equilíbrio, um número aleatório é usado aqui. RotateShuffer referência

/**
 * Basic {@link ShardShuffler} implementation that uses an {@link AtomicInteger} to generate seeds and uses a rotation to permute shards.
 */
public class RotationShardShuffler extends ShardShuffler {

    private final AtomicInteger seed;

    public RotationShardShuffler(int seed) {
        this.seed = new AtomicInteger(seed);
    }

    @Override
    public int nextSeed() {
        return seed.getAndIncrement();
    }

    @Override
    public List<ShardRouting> shuffle(List<ShardRouting> shards, int seed) {
        return CollectionUtils.rotate(shards, seed);
    }

}

Que é usado ThreadLocalRandom.current().nextInt()para gerar um número aleatório como uma semente, e, em seguida, tomar o tempo sequencialmente rodados.
Collections.rotate()O efeito pode ser usado como código demonstra:

    public static void main(String[] args) {

        List<String> list = Lists.newArrayList("a","b","c");
        int a = ThreadLocalRandom.current().nextInt();
        List<String> l2 = CollectionUtils.rotate(list, a );
        List<String> l3 = CollectionUtils.rotate(list, a+1);
        System.out.println(l2);
        System.out.println(l3);

    }

-----
[b, c, a]
[c, a, b]

Uma solicitação, tal como uma lista de nós é obtido [b, c, a], então a lista de pedidos de nó B é obtido [c, a, b]. Isso vai atingir o objectivo de balanceamento de carga.

  1. DiscoveryNodes aprendendo.
    Uma vez que o routing_tabletempo é armazenado na ID de nó, em seguida, envia uma solicitação para o nó de destino, mas também precisa saber o outro ip nó e configuração da porta. Esta informação é armazenada em nodeso.
  "nodes" : {
    "KnEE25tzRjaXblFJq5jqRA" : {
      "name" : "Mysterio",
      "transport_address" : "127.0.0.1:9300",
      "attributes" : { }
    }
  }

Por este nodesinformações do nó adquirida, um pedido pode ser enviado, todos os nós internos da ES de comunicação são baseadas transportService.sendRequest().

Em resumo, este trabalho baseado em get api classificar para fora um pouco a estrutura do núcleo poucos em ClusterState ES:  metadata, nodesrouting_table. Há também um routing_nodesnão usados aqui. Nos bastidores e, em seguida, usar o registro claro pente.

Publicado 298 artigos originais · ganhou elogios 107 · Exibições 140.000 +

Acho que você gosta

Origin blog.csdn.net/ywl470812087/article/details/104875127
Recomendado
Clasificación