Skip to content

Commit 6948e64

Browse files
HDDS-15065. Handling partial flush scenarios
1 parent 9a8d822 commit 6948e64

6 files changed

Lines changed: 356 additions & 25 deletions

File tree

hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/SCMHADBTransactionBuffer.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,14 @@ public interface SCMHADBTransactionBuffer
4444

4545
void flush() throws RocksDatabaseException, CodecException;
4646

47+
void flushIfNeeded(long snapshotWaitTime)
48+
throws RocksDatabaseException, CodecException;
49+
4750
boolean shouldFlush(long snapshotWaitTime);
4851

4952
void init() throws RocksDatabaseException, CodecException;
53+
54+
void beginApplyingTransaction();
55+
56+
void endApplyingTransaction();
5057
}

hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/SCMHADBTransactionBufferImpl.java

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static org.apache.hadoop.ozone.OzoneConsts.TRANSACTION_INFO_KEY;
2121

2222
import com.google.common.base.Preconditions;
23+
import java.util.concurrent.atomic.AtomicInteger;
2324
import java.util.concurrent.atomic.AtomicLong;
2425
import java.util.concurrent.atomic.AtomicReference;
2526
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -53,6 +54,7 @@ public class SCMHADBTransactionBufferImpl implements SCMHADBTransactionBuffer {
5354
private final AtomicReference<SnapshotInfo> latestSnapshot
5455
= new AtomicReference<>();
5556
private final AtomicLong txFlushPending = new AtomicLong(0);
57+
private final AtomicInteger applyingTransactions = new AtomicInteger(0);
5658
private long lastSnapshotTimeMs = 0;
5759
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
5860

@@ -124,30 +126,64 @@ public AtomicReference<SnapshotInfo> getLatestSnapshotRef() {
124126
public void flush() throws RocksDatabaseException, CodecException {
125127
rwLock.writeLock().lock();
126128
try {
127-
// write latest trx info into trx table in the same batch
128-
Table<String, TransactionInfo> transactionInfoTable
129-
= metadataStore.getTransactionInfoTable();
130-
transactionInfoTable.putWithBatch(currentBatchOperation,
131-
TRANSACTION_INFO_KEY, latestTrxInfo);
129+
flushUnderWriteLock();
130+
} finally {
131+
rwLock.writeLock().unlock();
132+
}
133+
}
132134

133-
metadataStore.getStore().commitBatchOperation(currentBatchOperation);
134-
currentBatchOperation.close();
135-
this.latestSnapshot.set(latestTrxInfo.toSnapshotInfo());
136-
// reset batch operation
137-
currentBatchOperation = metadataStore.getStore().initBatchOperation();
138-
139-
DeletedBlockLog deletedBlockLog = scm.getScmBlockManager()
140-
.getDeletedBlockLog();
141-
Preconditions.checkArgument(
142-
deletedBlockLog instanceof DeletedBlockLogImpl);
143-
((DeletedBlockLogImpl) deletedBlockLog).onFlush();
135+
@Override
136+
public void flushIfNeeded(long snapshotWaitTime)
137+
throws RocksDatabaseException, CodecException {
138+
rwLock.writeLock().lock();
139+
try {
140+
if (applyingTransactions.get() > 0) {
141+
return;
142+
}
143+
long timeDiff = scm.getSystemClock().millis() - lastSnapshotTimeMs;
144+
if (txFlushPending.get() > 0 && timeDiff > snapshotWaitTime) {
145+
LOG.debug("Running TransactionFlushTask");
146+
flushUnderWriteLock();
147+
}
144148
} finally {
145-
txFlushPending.set(0);
146-
lastSnapshotTimeMs = scm.getSystemClock().millis();
147149
rwLock.writeLock().unlock();
148150
}
149151
}
150152

153+
private void flushUnderWriteLock()
154+
throws RocksDatabaseException, CodecException {
155+
// write latest trx info into trx table in the same batch
156+
Table<String, TransactionInfo> transactionInfoTable
157+
= metadataStore.getTransactionInfoTable();
158+
transactionInfoTable.putWithBatch(currentBatchOperation,
159+
TRANSACTION_INFO_KEY, latestTrxInfo);
160+
161+
metadataStore.getStore().commitBatchOperation(currentBatchOperation);
162+
currentBatchOperation.close();
163+
this.latestSnapshot.set(latestTrxInfo.toSnapshotInfo());
164+
// reset batch operation
165+
currentBatchOperation = metadataStore.getStore().initBatchOperation();
166+
167+
DeletedBlockLog deletedBlockLog = scm.getScmBlockManager()
168+
.getDeletedBlockLog();
169+
Preconditions.checkArgument(
170+
deletedBlockLog instanceof DeletedBlockLogImpl);
171+
((DeletedBlockLogImpl) deletedBlockLog).onFlush();
172+
173+
txFlushPending.set(0);
174+
lastSnapshotTimeMs = scm.getSystemClock().millis();
175+
}
176+
177+
@Override
178+
public void beginApplyingTransaction() {
179+
applyingTransactions.incrementAndGet();
180+
}
181+
182+
@Override
183+
public void endApplyingTransaction() {
184+
applyingTransactions.decrementAndGet();
185+
}
186+
151187
@Override
152188
public void init() throws RocksDatabaseException, CodecException {
153189
metadataStore = scm.getScmMetadataStore();

hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/SCMHADBTransactionBufferStub.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,19 @@ public AtomicReference<SnapshotInfo> getLatestSnapshotRef() {
101101
return null;
102102
}
103103

104+
@Override
105+
public void flushIfNeeded(long snapshotWaitTime) throws RocksDatabaseException {
106+
flush();
107+
}
108+
109+
@Override
110+
public void beginApplyingTransaction() {
111+
}
112+
113+
@Override
114+
public void endApplyingTransaction() {
115+
}
116+
104117
@Override
105118
public void flush() throws RocksDatabaseException {
106119
rwLock.writeLock().lock();

hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/SCMHATransactionBufferMonitorTask.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,10 @@ public SCMHATransactionBufferMonitorTask(
4242

4343
@Override
4444
public void run() {
45-
if (transactionBuffer.shouldFlush(flushInterval)) {
46-
LOG.debug("Running TransactionFlushTask");
47-
try {
48-
transactionBuffer.flush();
49-
} catch (IOException e) {
50-
LOG.error("TransactionFlushTask is failed", e);
51-
}
45+
try {
46+
transactionBuffer.flushIfNeeded(flushInterval);
47+
} catch (IOException e) {
48+
LOG.error("TransactionFlushTask is failed", e);
5249
}
5350
}
5451
}

hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/SCMStateMachine.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ public CompletableFuture<Message> applyTransaction(
150150
final TransactionContext trx) {
151151
final CompletableFuture<Message> applyTransactionFuture =
152152
new CompletableFuture<>();
153+
transactionBuffer.beginApplyingTransaction();
153154
try {
154155
final SCMRatisRequest request = SCMRatisRequest.decode(
155156
Message.valueOf(trx.getStateMachineLogEntry().getLogData()));
@@ -182,6 +183,8 @@ public CompletableFuture<Message> applyTransaction(
182183
} catch (Exception ex) {
183184
applyTransactionFuture.completeExceptionally(ex);
184185
ExitUtils.terminate(1, ex.getMessage(), ex, StateMachine.LOG);
186+
} finally {
187+
transactionBuffer.endApplyingTransaction();
185188
}
186189
return applyTransactionFuture;
187190
}

0 commit comments

Comments
 (0)