Skip to content

Commit 473c4da

Browse files
authored
Resharding - Adding shards to an existing index (elastic#121082)
This POC attempts to double the number of shards of an existing index.
1 parent a9432ba commit 473c4da

File tree

6 files changed

+59
-7
lines changed

6 files changed

+59
-7
lines changed

server/src/main/java/org/elasticsearch/TransportVersions.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,8 @@ static TransportVersion def(int id) {
183183
public static final TransportVersion STORED_SCRIPT_CONTENT_LENGTH = def(9_019_0_00);
184184
public static final TransportVersion JINA_AI_EMBEDDING_TYPE_SUPPORT_ADDED = def(9_020_0_00);
185185
public static final TransportVersion RE_REMOVE_MIN_COMPATIBLE_SHARD_NODE = def(9_021_0_00);
186-
public static final TransportVersion INCLUDE_INDEX_MODE_IN_GET_DATA_STREAM = def(9_022_0_00);
186+
public static final TransportVersion UNASSIGENEDINFO_RESHARD_ADDED = def(9_022_0_00);
187+
public static final TransportVersion INCLUDE_INDEX_MODE_IN_GET_DATA_STREAM = def(9_023_0_00);
187188

188189
/*
189190
* STOP! READ THIS FIRST! No, really,

server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,6 +1947,39 @@ public Builder numberOfShards(int numberOfShards) {
19471947
return this;
19481948
}
19491949

1950+
/**
1951+
* Builder to create IndexMetadata that has an increased shard count (used for re-shard).
1952+
* The new shard count must be a multiple of the original shardcount.
1953+
* We do not support shrinking the shard count.
1954+
* @param shardCount updated shardCount
1955+
*
1956+
* TODO: Check if this.version needs to be incremented
1957+
*/
1958+
public Builder reshardAddShards(int shardCount) {
1959+
// Assert routingNumShards is null ?
1960+
// Assert numberOfShards > 0
1961+
if (shardCount % numberOfShards() != 0) {
1962+
throw new IllegalArgumentException(
1963+
"New shard count ["
1964+
+ shardCount
1965+
+ "] should be a multiple"
1966+
+ " of current shard count ["
1967+
+ numberOfShards()
1968+
+ "] for ["
1969+
+ index
1970+
+ "]"
1971+
);
1972+
}
1973+
IndexVersion indexVersionCreated = indexCreatedVersion(settings);
1974+
settings = Settings.builder().put(settings).put(SETTING_NUMBER_OF_SHARDS, shardCount).build();
1975+
var newPrimaryTerms = new long[shardCount];
1976+
Arrays.fill(newPrimaryTerms, this.primaryTerms.length, newPrimaryTerms.length, SequenceNumbers.UNASSIGNED_PRIMARY_TERM);
1977+
System.arraycopy(primaryTerms, 0, newPrimaryTerms, 0, this.primaryTerms.length);
1978+
primaryTerms = newPrimaryTerms;
1979+
routingNumShards = MetadataCreateIndexService.calculateNumRoutingShards(shardCount, indexVersionCreated);
1980+
return this;
1981+
}
1982+
19501983
/**
19511984
* Sets the number of shards that should be used for routing. This should only be used if the number of shards in
19521985
* an index has changed ie if the index is shrunk.

server/src/main/java/org/elasticsearch/cluster/routing/IndexRoutingTable.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ public Builder addShard(ShardRouting shard) {
662662
return this;
663663
}
664664

665-
void ensureShardArray(int shardCount) {
665+
public void ensureShardArray(int shardCount) {
666666
if (shards == null) {
667667
shards = new IndexShardRoutingTable.Builder[shardCount];
668668
} else if (shards.length < shardCount) {

server/src/main/java/org/elasticsearch/cluster/routing/RoutingTable.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,14 @@ public Builder(ShardRoutingRoleStrategy shardRoutingRoleStrategy, RoutingTable r
436436
this.indicesRouting = ImmutableOpenMap.builder(routingTable.indicesRouting);
437437
}
438438

439+
public IndexRoutingTable getIndexRoutingTable(String index) {
440+
return indicesRouting.get(index);
441+
}
442+
443+
public ShardRoutingRoleStrategy getShardRoutingRoleStrategy() {
444+
return shardRoutingRoleStrategy;
445+
}
446+
439447
private static void addShard(
440448
final Map<String, IndexRoutingTable.Builder> indexRoutingTableBuilders,
441449
final ShardRouting shardRoutingEntry

server/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,11 @@ public enum Reason {
175175
/**
176176
* Replica is unpromotable and the primary failed.
177177
*/
178-
UNPROMOTABLE_REPLICA
178+
UNPROMOTABLE_REPLICA,
179+
/**
180+
* New shard added as part of index re-sharding operation
181+
*/
182+
RESHARD_ADDED
179183
}
180184

181185
/**
@@ -335,9 +339,14 @@ public void writeTo(StreamOutput out) throws IOException {
335339
out.writeByte((byte) Reason.NODE_LEFT.ordinal());
336340
} else if (reason.equals(Reason.UNPROMOTABLE_REPLICA) && out.getTransportVersion().before(VERSION_UNPROMOTABLE_REPLICA_ADDED)) {
337341
out.writeByte((byte) Reason.PRIMARY_FAILED.ordinal());
338-
} else {
339-
out.writeByte((byte) reason.ordinal());
340-
}
342+
} else if (reason.equals(Reason.RESHARD_ADDED)
343+
&& out.getTransportVersion().before(TransportVersions.UNASSIGENEDINFO_RESHARD_ADDED)) {
344+
// We should have protection to ensure we do not reshard in mixed clusters
345+
assert false;
346+
out.writeByte((byte) Reason.FORCED_EMPTY_PRIMARY.ordinal());
347+
} else {
348+
out.writeByte((byte) reason.ordinal());
349+
}
341350
out.writeLong(unassignedTimeMillis);
342351
// Do not serialize unassignedTimeNanos as System.nanoTime() cannot be compared across different JVMs
343352
out.writeBoolean(delayed);

server/src/test/java/org/elasticsearch/cluster/routing/UnassignedInfoTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ public void testReasonOrdinalOrder() {
8888
UnassignedInfo.Reason.MANUAL_ALLOCATION,
8989
UnassignedInfo.Reason.INDEX_CLOSED,
9090
UnassignedInfo.Reason.NODE_RESTARTING,
91-
UnassignedInfo.Reason.UNPROMOTABLE_REPLICA };
91+
UnassignedInfo.Reason.UNPROMOTABLE_REPLICA,
92+
UnassignedInfo.Reason.RESHARD_ADDED };
9293
for (int i = 0; i < order.length; i++) {
9394
assertThat(order[i].ordinal(), equalTo(i));
9495
}

0 commit comments

Comments
 (0)