Skip to content

Commit 2b1d565

Browse files
committed
Merge branch 'main' into ignite-26722
2 parents 9c1ea01 + 31195f0 commit 2b1d565

File tree

17 files changed

+163
-94
lines changed

17 files changed

+163
-94
lines changed

docs/_docs/administrators-guide/storage/data-partitions.adoc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Data partitioning is a method of subdividing large sets of data into smaller chu
2020

2121
When the table is created, it is always assigned to a link:administrators-guide/storage/distribution-zones[distribution zone]. Based on the distribution zone parameters, the table is separated into `PARTITIONS` parts, called *partitions*, stored `REPLICAS` times across the cluster. Each partition is identified by a number from a limited set (0 to 24 for the default zone). Each individual copy of a partition is called a *replica*, and is stored on separate nodes, if possible. Partitions with the same number for all tables in the zone are always stored on the same node.
2222

23-
Apache Ignite uses the *Fair* partition distribution algorithm. It means that it stores information on partition distribution and uses this information for assigning new partitions. This information is preserved in cluster metastorage, and is recalculated only when necessary.
23+
Apache Ignite uses the *Rendezvous* partition distribution algorithm. It means that it stores information on partition distribution and uses this information for assigning new partitions. This information is preserved in cluster metastorage, and is recalculated only when necessary.
2424

2525
Once partitions and all replicas are created, they are distributed across the available cluster nodes that are included in the distribution zone following the `DATA_NODES_FILTER` parameter and according to the *partition distribution algorithm*. Thus, each key is mapped to a list of nodes owning the corresponding partition and is stored on those nodes. When data is added, it is distributed evenly between partitions.
2626

@@ -120,4 +120,12 @@ NOTE: Reset is likely to result in <<Partition Rebalance>>, which may take a lon
120120

121121
== Partition Rebalance
122122

123-
When the link:administrators-guide/storage/distribution-zones#cluster-scaling[cluster size changes], Apache Ignite waits for the timeout specified in the `AUTO SCALE UP` or `AUTO SCALE DOWN` distribution zone properties, and then redistributes partitions according to the partition distribution algorithm and transfers data to make it up-to-date with the replication group. This process is called *data rebalance*.
123+
When the link:administrators-guide/storage/distribution-zones#cluster-scaling[cluster size changes], Apache Ignite waits for the timeout specified in the `AUTO SCALE UP` or `AUTO SCALE DOWN` distribution zone properties, and then redistributes partitions according to the partition distribution algorithm and transfers data to make it up-to-date with the replication group. This process is called *data rebalance*.
124+
125+
== Old Replication Mode (Table-based Replication)
126+
127+
Ignite 3.1 introduced Zone-based Replication and uses it by default. Ignite 3.0 used Table-based Replication, so clusters created on 3.0 and upgraded to 3.1 will still use Table-based Replication.
128+
129+
Table-based Replication is deprecated in Ignite 3.1, and is planned to be removed in Ignite 3.2. It is recommended to migrate your clusters to Zone-based Replication. Currently, there is no automatic migration tool, so you will need to create a new cluster with Zone-based Replication and move your data there.
130+
131+
Current replication mode for your cluster is specified in the startup logs. Look for the following line: 'Zone based replication: true' or 'Zone based replication: false'. If it is false, you are using Table-based Replication.

modules/core/src/main/java/org/apache/ignite/internal/lang/IgniteSystemProperties.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@ public final class IgniteSystemProperties {
4444
public static final String IGNITE_SKIP_STORAGE_UPDATE_IN_BENCHMARK = "IGNITE_SKIP_STORAGE_UPDATE_IN_BENCHMARK";
4545

4646
// TODO https://issues.apache.org/jira/browse/IGNITE-22522 Remove this feature flag.
47-
/** Enables zone based replication (aka colocation) feature. */
47+
/**
48+
* Enables zone based replication (aka colocation) feature.
49+
*
50+
* @deprecated Non-colocation mode is planned to be removed in version 3.2.
51+
*/
52+
@Deprecated(since = "3.1", forRemoval = true)
4853
public static final String COLOCATION_FEATURE_FLAG = "IGNITE_ZONE_BASED_REPLICATION";
4954

5055
/**
@@ -60,8 +65,10 @@ private IgniteSystemProperties() {
6065
*
6166
* <p>Do not use in production code (apart from {@link NodeProperties} implementations). If a component needs colocation status,
6267
* it should get one from {@link NodeProperties}.
68+
*
69+
* @deprecated Non-colocation mode is planned to be removed in version 3.2.
6370
*/
64-
@Deprecated
71+
@Deprecated(since = "3.1", forRemoval = true)
6572
public static boolean colocationEnabled() {
6673
return getBoolean(COLOCATION_FEATURE_FLAG, true);
6774
}

modules/raft/src/main/java/org/apache/ignite/internal/raft/storage/segstore/GroupIndexMeta.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ IndexFileMeta indexMeta(long logIndex) {
6363
return fileMetas.find(logIndex);
6464
}
6565

66-
long firstLogIndex() {
67-
return fileMetas.get(0).firstLogIndex();
66+
long firstLogIndexInclusive() {
67+
return fileMetas.get(0).firstLogIndexInclusive();
6868
}
6969

70-
long lastLogIndex() {
70+
long lastLogIndexExclusive() {
7171
IndexFileMetaArray fileMetas = this.fileMetas;
7272

73-
return fileMetas.get(fileMetas.size() - 1).lastLogIndex();
73+
return fileMetas.get(fileMetas.size() - 1).lastLogIndexExclusive();
7474
}
7575
}

modules/raft/src/main/java/org/apache/ignite/internal/raft/storage/segstore/IndexFileManager.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,8 @@ SegmentFilePointer getSegmentFilePointer(long groupId, long logIndex) throws IOE
163163

164164
Path indexFile = baseDir.resolve(indexFileName(indexFileMeta.indexFileOrdinal(), 0));
165165

166-
// Index file payload is a 0-based array, which indices correspond to the [fileMeta.firstLogIndex, fileMeta.lastLogIndex] range.
167-
long payloadArrayIndex = logIndex - indexFileMeta.firstLogIndex();
166+
// Index file payload is a 0-based array, which indices correspond to the [fileMeta.firstLogIndex, fileMeta.lastLogIndex) range.
167+
long payloadArrayIndex = logIndex - indexFileMeta.firstLogIndexInclusive();
168168

169169
assert payloadArrayIndex >= 0 : payloadArrayIndex;
170170

@@ -192,19 +192,19 @@ SegmentFilePointer getSegmentFilePointer(long groupId, long logIndex) throws IOE
192192
/**
193193
* Returns the lowest log index for the given group across all index files or {@code -1} if no such index exists.
194194
*/
195-
long firstLogIndex(long groupId) {
195+
long firstLogIndexInclusive(long groupId) {
196196
GroupIndexMeta groupIndexMeta = groupIndexMetas.get(groupId);
197197

198-
return groupIndexMeta == null ? -1 : groupIndexMeta.firstLogIndex();
198+
return groupIndexMeta == null ? -1 : groupIndexMeta.firstLogIndexInclusive();
199199
}
200200

201201
/**
202-
* Returns the highest log index for the given group across all index files or {@code -1} if no such index exists.
202+
* Returns the highest possible log index for the given group across all index files or {@code -1} if no such index exists.
203203
*/
204-
long lastLogIndex(long groupId) {
204+
long lastLogIndexExclusive(long groupId) {
205205
GroupIndexMeta groupIndexMeta = groupIndexMetas.get(groupId);
206206

207-
return groupIndexMeta == null ? -1 : groupIndexMeta.lastLogIndex();
207+
return groupIndexMeta == null ? -1 : groupIndexMeta.lastLogIndexExclusive();
208208
}
209209

210210
private byte[] serializeHeaderAndFillMetadata(ReadModeIndexMemTable indexMemTable) {
@@ -230,20 +230,20 @@ private byte[] serializeHeaderAndFillMetadata(ReadModeIndexMemTable indexMemTabl
230230

231231
SegmentInfo segmentInfo = entry.getValue();
232232

233-
long firstLogIndex = segmentInfo.firstLogIndex();
233+
long firstLogIndexInclusive = segmentInfo.firstLogIndexInclusive();
234234

235-
long lastLogIndex = segmentInfo.lastLogIndex();
235+
long lastLogIndexExclusive = segmentInfo.lastLogIndexExclusive();
236236

237-
var indexFileMeta = new IndexFileMeta(firstLogIndex, lastLogIndex, payloadOffset, curFileOrdinal);
237+
var indexFileMeta = new IndexFileMeta(firstLogIndexInclusive, lastLogIndexExclusive, payloadOffset, curFileOrdinal);
238238

239239
putIndexFileMeta(groupId, indexFileMeta);
240240

241241
headerBuffer
242242
.putLong(groupId)
243243
.putInt(0) // Flags.
244244
.putInt(payloadOffset)
245-
.putLong(firstLogIndex)
246-
.putLong(lastLogIndex);
245+
.putLong(firstLogIndexInclusive)
246+
.putLong(lastLogIndexExclusive);
247247

248248
payloadOffset += payloadSize(segmentInfo);
249249
}

modules/raft/src/main/java/org/apache/ignite/internal/raft/storage/segstore/IndexFileMeta.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,33 +25,33 @@
2525
* @see IndexFileManager
2626
*/
2727
class IndexFileMeta {
28-
private final long firstLogIndex;
28+
private final long firstLogIndexInclusive;
2929

30-
private final long lastLogIndex;
30+
private final long lastLogIndexExclusive;
3131

3232
private final int indexFilePayloadOffset;
3333

3434
private final int indexFileOrdinal;
3535

36-
IndexFileMeta(long firstLogIndex, long lastLogIndex, int indexFilePayloadOffset, int indexFileOrdinal) {
37-
this.firstLogIndex = firstLogIndex;
38-
this.lastLogIndex = lastLogIndex;
36+
IndexFileMeta(long firstLogIndexInclusive, long lastLogIndexExclusive, int indexFilePayloadOffset, int indexFileOrdinal) {
37+
this.firstLogIndexInclusive = firstLogIndexInclusive;
38+
this.lastLogIndexExclusive = lastLogIndexExclusive;
3939
this.indexFilePayloadOffset = indexFilePayloadOffset;
4040
this.indexFileOrdinal = indexFileOrdinal;
4141
}
4242

4343
/**
4444
* Returns the inclusive lower bound of log indices stored in the index file for the Raft Group.
4545
*/
46-
long firstLogIndex() {
47-
return firstLogIndex;
46+
long firstLogIndexInclusive() {
47+
return firstLogIndexInclusive;
4848
}
4949

5050
/**
51-
* Returns the inclusive upper bound of log indices stored in the index file for the Raft Group.
51+
* Returns the exclusive upper bound of log indices stored in the index file for the Raft Group.
5252
*/
53-
long lastLogIndex() {
54-
return lastLogIndex;
53+
long lastLogIndexExclusive() {
54+
return lastLogIndexExclusive;
5555
}
5656

5757
/**
@@ -75,15 +75,15 @@ public boolean equals(Object o) {
7575
}
7676

7777
IndexFileMeta that = (IndexFileMeta) o;
78-
return firstLogIndex == that.firstLogIndex && lastLogIndex == that.lastLogIndex
78+
return firstLogIndexInclusive == that.firstLogIndexInclusive && lastLogIndexExclusive == that.lastLogIndexExclusive
7979
&& indexFilePayloadOffset == that.indexFilePayloadOffset
8080
&& indexFileOrdinal == that.indexFileOrdinal;
8181
}
8282

8383
@Override
8484
public int hashCode() {
85-
int result = Long.hashCode(firstLogIndex);
86-
result = 31 * result + Long.hashCode(lastLogIndex);
85+
int result = Long.hashCode(firstLogIndexInclusive);
86+
result = 31 * result + Long.hashCode(lastLogIndexExclusive);
8787
result = 31 * result + indexFilePayloadOffset;
8888
result = 31 * result + indexFileOrdinal;
8989
return result;

modules/raft/src/main/java/org/apache/ignite/internal/raft/storage/segstore/IndexFileMetaArray.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ private IndexFileMetaArray(IndexFileMeta[] array, int size) {
4545
}
4646

4747
IndexFileMetaArray add(IndexFileMeta indexFileMeta) {
48-
assert indexFileMeta.firstLogIndex() == array[size - 1].lastLogIndex() + 1 :
48+
assert indexFileMeta.firstLogIndexInclusive() == array[size - 1].lastLogIndexExclusive() :
4949
String.format("Index File Metas must be contiguous. Expected log index: %d, actual log index: %d",
50-
array[size - 1].lastLogIndex() + 1,
51-
indexFileMeta.firstLogIndex()
50+
array[size - 1].lastLogIndexExclusive(),
51+
indexFileMeta.firstLogIndexInclusive()
5252
);
5353

5454
// The array can be shared between multiple instances, but since it always grows and we read at most "size" elements,
@@ -72,6 +72,14 @@ int size() {
7272
return size;
7373
}
7474

75+
long firstLogIndexInclusive() {
76+
return array[0].firstLogIndexInclusive();
77+
}
78+
79+
long lastLogIndexExclusive() {
80+
return array[size - 1].lastLogIndexExclusive();
81+
}
82+
7583
/**
7684
* Returns the {@link IndexFileMeta} containing the given Raft log index or {@code null} if no such meta exists.
7785
*/
@@ -85,9 +93,9 @@ IndexFileMeta find(long logIndex) {
8593

8694
IndexFileMeta midValue = array[middleArrayIndex];
8795

88-
if (logIndex < midValue.firstLogIndex()) {
96+
if (logIndex < midValue.firstLogIndexInclusive()) {
8997
highArrayIndex = middleArrayIndex - 1;
90-
} else if (logIndex > midValue.lastLogIndex()) {
98+
} else if (logIndex >= midValue.lastLogIndexExclusive()) {
9199
lowArrayIndex = middleArrayIndex + 1;
92100
} else {
93101
return midValue;

modules/raft/src/main/java/org/apache/ignite/internal/raft/storage/segstore/RaftLogCheckpointer.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ void onRollover(SegmentFile segmentFile, ReadModeIndexMemTable indexMemTable) {
129129
/**
130130
* Returns the lowest log index for the given group present in the checkpoint queue or {@code -1} if no such index exists.
131131
*/
132-
long firstLogIndex(long groupId) {
132+
long firstLogIndexInclusive(long groupId) {
133133
Iterator<Entry> it = queue.tailIterator();
134134

135135
long firstIndex = -1;
@@ -138,24 +138,24 @@ long firstLogIndex(long groupId) {
138138
SegmentInfo segmentInfo = it.next().memTable().segmentInfo(groupId);
139139

140140
if (segmentInfo != null) {
141-
firstIndex = segmentInfo.firstLogIndex();
141+
firstIndex = segmentInfo.firstLogIndexInclusive();
142142
}
143143
}
144144

145145
return firstIndex;
146146
}
147147

148148
/**
149-
* Returns the highest log index for the given group present in the checkpoint queue or {@code -1} if no such index exists.
149+
* Returns the highest possible log index for the given group present in the checkpoint queue or {@code -1} if no such index exists.
150150
*/
151-
long lastLogIndex(long groupId) {
151+
long lastLogIndexExclusive(long groupId) {
152152
Iterator<Entry> it = queue.tailIterator();
153153

154154
while (it.hasNext()) {
155155
SegmentInfo segmentInfo = it.next().memTable().segmentInfo(groupId);
156156

157157
if (segmentInfo != null) {
158-
return segmentInfo.lastLogIndex();
158+
return segmentInfo.lastLogIndexExclusive();
159159
}
160160
}
161161

modules/raft/src/main/java/org/apache/ignite/internal/raft/storage/segstore/SegmentFileManager.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,12 @@ void appendEntry(long groupId, LogEntry entry, LogEntryEncoder encoder) throws I
219219
/**
220220
* Returns the lowest log index for the given group present in the storage or {@code -1} if no such index exists.
221221
*/
222-
long firstLogIndex(long groupId) {
222+
long firstLogIndexInclusive(long groupId) {
223223
long logIndexFromMemtable = firstLogIndexFromMemtable(groupId);
224224

225-
long logIndexFromCheckpointQueue = checkpointer.firstLogIndex(groupId);
225+
long logIndexFromCheckpointQueue = checkpointer.firstLogIndexInclusive(groupId);
226226

227-
long logIndexFromIndexFiles = indexFileManager.firstLogIndex(groupId);
227+
long logIndexFromIndexFiles = indexFileManager.firstLogIndexInclusive(groupId);
228228

229229
if (logIndexFromIndexFiles >= 0) {
230230
return logIndexFromIndexFiles;
@@ -242,34 +242,36 @@ private long firstLogIndexFromMemtable(long groupId) {
242242

243243
SegmentInfo segmentInfo = currentSegmentFile.memtable().segmentInfo(groupId);
244244

245-
return segmentInfo == null ? -1 : segmentInfo.firstLogIndex();
245+
return segmentInfo == null ? -1 : segmentInfo.firstLogIndexInclusive();
246246
}
247247

248248
/**
249-
* Returns the highest log index for the given group present in the storage or {@code -1} if no such index exists.
249+
* Returns the highest possible exclusive log index for the given group or {@code -1} if no such index exists.
250+
*
251+
* <p>The highest log index currently present in the storage can be computed as {@code lastLogIndexExclusive - 1}.
250252
*/
251-
long lastLogIndex(long groupId) {
253+
long lastLogIndexExclusive(long groupId) {
252254
long logIndexFromMemtable = lastLogIndexFromMemtable(groupId);
253255

254256
if (logIndexFromMemtable >= 0) {
255257
return logIndexFromMemtable;
256258
}
257259

258-
long logIndexFromCheckpointQueue = checkpointer.lastLogIndex(groupId);
260+
long logIndexFromCheckpointQueue = checkpointer.lastLogIndexExclusive(groupId);
259261

260262
if (logIndexFromCheckpointQueue >= 0) {
261263
return logIndexFromCheckpointQueue;
262264
}
263265

264-
return indexFileManager.lastLogIndex(groupId);
266+
return indexFileManager.lastLogIndexExclusive(groupId);
265267
}
266268

267269
private long lastLogIndexFromMemtable(long groupId) {
268270
SegmentFileWithMemtable currentSegmentFile = this.currentSegmentFile.get();
269271

270272
SegmentInfo segmentInfo = currentSegmentFile.memtable().segmentInfo(groupId);
271273

272-
return segmentInfo == null ? -1 : segmentInfo.lastLogIndex();
274+
return segmentInfo == null ? -1 : segmentInfo.lastLogIndexExclusive();
273275
}
274276

275277
/**

modules/raft/src/main/java/org/apache/ignite/internal/raft/storage/segstore/SegmentInfo.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,15 @@ int getOffset(long logIndex) {
133133
/**
134134
* Returns the inclusive lower bound of log indices stored in this memtable.
135135
*/
136-
long firstLogIndex() {
136+
long firstLogIndexInclusive() {
137137
return logIndexBase;
138138
}
139139

140140
/**
141141
* Returns the inclusive upper bound of log indices stored in this memtable.
142142
*/
143-
long lastLogIndex() {
144-
return logIndexBase + segmentFileOffsets.size() - 1;
143+
long lastLogIndexExclusive() {
144+
return logIndexBase + segmentFileOffsets.size();
145145
}
146146

147147
/**

modules/raft/src/main/java/org/apache/ignite/internal/raft/storage/segstore/SegstoreLogStorage.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,18 @@ public int appendEntries(List<LogEntry> entries) {
8383

8484
@Override
8585
public long getFirstLogIndex() {
86-
long firstLogIndex = segmentFileManager.firstLogIndex(groupId);
86+
long firstLogIndex = segmentFileManager.firstLogIndexInclusive(groupId);
8787

88+
// JRaft requires to return 1 as the first log index if there are no entries.
8889
return firstLogIndex >= 0 ? firstLogIndex : 1;
8990
}
9091

9192
@Override
9293
public long getLastLogIndex() {
93-
long lastLogIndex = segmentFileManager.lastLogIndex(groupId);
94+
long lastLogIndex = segmentFileManager.lastLogIndexExclusive(groupId);
9495

95-
return lastLogIndex >= 0 ? lastLogIndex : 0;
96+
// JRaft requires to return 0 as the last log index if there are no entries.
97+
return Math.max(lastLogIndex - 1, 0);
9698
}
9799

98100
@Override

0 commit comments

Comments
 (0)