私たちは、のESフロント研究get api
プラグ-ESを書くときに参考として全体的なアイデアを。その時、全体のプロセス、主の理解でフォーカスshardOperation()
メソッド呼び出しの内部ロジックは、それが弱体化shards()
する方法を。実際にはshards()
構造的なレベルのES、より大きな役割を理解する上での方法。我々はまだ、get api
スタートを理解しますshards()
。
初めて目にget api
プロセスの使用:
添加文档到ES:
curl -XPUT 'http://localhost:9200/test1/type1/1' -d '{"name":"hello"}'
根据文档ID读取数据:
curl -XGET 'http://localhost:9200/test1/type1/1'
使用することは非常にシンプル。しかし、単純ではない考慮しての背後にある場合は、分散ロジック。ESクラスタは、インデックスデータは3つのフラグメント、各スライスのコピーを持っている3つのノードを、持っている場合。次のようにそのインデックスが設定されます。
{
"test1" : {
"settings" : {
"index" : {
"number_of_replicas" : "1",
"number_of_shards" : "3"
}
}
}
}
だからのそのスライスに、この分布のIDドキュメント1と?この問題は、我々が最初に簡単な結論を与える詳細な回答のブログを、必要とします。
默认情况下,ES会按照文档id计算一个hash值, 采用的是Murmur3HashFunction,然后根据这个id跟分片数取模。实现代码是MathUtils.mod(hash, indexMetaData.getNumberOfShards()); 最后的结果作为文档所在的分片id,所以ES的分片标号是从0开始的。
私はあなたが取るために知ることができるか、が存在を知りません。
そして、ソートデータへのアクセスのコアプロセスアウト:
s1: 根据文档id定位到数据所在分片。由于可以设为多个副本,所以一个分片会映射到多个节点。
s2: 根据分片节点的映射信息,选择一个节点,去获取数据。 这里重点关注的是节点的选择方式,简而言之,我们需要负载均衡,不然设置副本就没有意义了。
二段階以上のコアデータ構造に関連付けられているClusterState
、我々が使用することができ_cluster/state?pretty
、このデータ構造を表示します。
# 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"
}
} ]
}
}
}
全体の構造は、私たちはゆっくりと1つのブレイクによって、ステップバイステップで、1解体され、より複雑です。解体や使用シナリオのアイデアからスタート。
- 学習IndexMetaData
のmetaDataに次の形式を:"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" : [ ] } } }
そのメタデータは、各スライスのクラスタと部数、インデックス、インデックスマッピング、インデックスエイリアスのインデックス状態に格納されています。この構成は、その機能を提供することができ根据索引名称获取索引元数据
、以下のように、:
# 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();
ここでの私たちの懸念があることclusterState.metaData().index(index)
、このコードは、それを実装します根据索引名称获取索引元数据的功能
。ドキュメントIDを結合断片化されたメタデータの数によって、我々は文書の存在の断片を見つけることができるようになります。削除この機能は、インデックスは、APIの3つが必要です取得します。インデックスの断片化の数はES変更することはできませんなぜここでは、理解することができます:あなたが変更した場合は、ハッシュ関数がどこフラグメンテーション正しいデータを見つけることができません。
- 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_table
各インデックスのために保存された情報の断片化は、このような構造により、我々は明らかに、以下の情報を理解することができます。
1. 索引分片在各个节点的分布
2. 索引分片是否为主分片
スライスは2つのコピーを持っており、別のノードに割り当てられている場合は、get api
3つのデータ・ノードの合計は1が行うかを選択、から選択するには?ここで考慮すべきではないpreference
パラメータ。
各ノードは、かなり負荷分散の目的を達成するために選択することができようにするには、乱数が、ここで使用されています。参考RotateShuffer
/**
* 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);
}
}
それが使用されるThreadLocalRandom.current().nextInt()
種として乱数を生成し、順次回転時間がかかります。Collections.rotate()
コードが示すような効果を使用することができます。
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]
要求そのようなノードのリストが取得されるよう、B、C、A]は、ノードBの要求のリストが得られる[C、B]。これは、負荷分散の目的を達成します。
- DiscoveryNodes学習します。
以来routing_table
、時間がノードIDに格納され、その後、ターゲット・ノードに要求を送信するだけでなく、他のノードのIPアドレスとポートの設定を知っている必要があります。この情報はに格納されますnodes
。
"nodes" : {
"KnEE25tzRjaXblFJq5jqRA" : {
"name" : "Mysterio",
"transport_address" : "127.0.0.1:9300",
"attributes" : { }
}
}
これにより、nodes
取得したノード情報、要求は、通信ESの全ての内部ノードが基づいて、送信することができますtransportService.sendRequest()
。
要約すると、に基づいて、この論文get api
アウトソートはCLUSTERSTATE ESにいくつかのコア構造ビット: metadata
、nodes
、 routing_table
。ありrouting_nodes
、ここでは使用されません。舞台裏その後、櫛明確な記録を使用しています。