Commit segments only when they are covered by active locks (#15027)

* Commit segments only when they are covered by active locks
This commit is contained in:
AmatyaAvadhanula 2023-09-25 13:45:42 +05:30 committed by GitHub
parent 48b6d2abf9
commit f7a549123b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 3 deletions

View File

@ -46,6 +46,7 @@ import java.util.Map.Entry;
import java.util.NavigableMap; import java.util.NavigableMap;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.stream.Collectors;
public class TaskLocks public class TaskLocks
{ {
@ -93,6 +94,12 @@ public class TaskLocks
: DateTimes.nowUtc().toString(); : DateTimes.nowUtc().toString();
} }
/**
* Checks if the segments are covered by a non revoked lock
* @param taskLockMap task locks for a task
* @param segments segments to be checked
* @return true if each of the segments is covered by a non-revoked lock
*/
public static boolean isLockCoversSegments( public static boolean isLockCoversSegments(
NavigableMap<DateTime, List<TaskLock>> taskLockMap, NavigableMap<DateTime, List<TaskLock>> taskLockMap,
Collection<DataSegment> segments Collection<DataSegment> segments
@ -105,7 +112,11 @@ public class TaskLocks
return false; return false;
} }
final List<TaskLock> locks = entry.getValue(); // taskLockMap may contain revoked locks which need to be filtered
final List<TaskLock> locks = entry.getValue()
.stream()
.filter(lock -> !lock.isRevoked())
.collect(Collectors.toList());
return locks.stream().anyMatch( return locks.stream().anyMatch(
lock -> { lock -> {
if (lock.getGranularity() == LockGranularity.TIME_CHUNK) { if (lock.getGranularity() == LockGranularity.TIME_CHUNK) {

View File

@ -832,7 +832,7 @@ public class TaskLockbox
* @param lock lock to be revoked * @param lock lock to be revoked
*/ */
@VisibleForTesting @VisibleForTesting
protected void revokeLock(String taskId, TaskLock lock) public void revokeLock(String taskId, TaskLock lock)
{ {
giant.lock(); giant.lock();

View File

@ -22,6 +22,7 @@ package org.apache.druid.indexing.common.actions;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import org.apache.druid.indexer.TaskStatus;
import org.apache.druid.indexing.common.SegmentLock; import org.apache.druid.indexing.common.SegmentLock;
import org.apache.druid.indexing.common.TaskLock; import org.apache.druid.indexing.common.TaskLock;
import org.apache.druid.indexing.common.TaskLockType; import org.apache.druid.indexing.common.TaskLockType;
@ -34,6 +35,7 @@ import org.apache.druid.indexing.overlord.HeapMemoryTaskStorage;
import org.apache.druid.indexing.overlord.LockResult; import org.apache.druid.indexing.overlord.LockResult;
import org.apache.druid.indexing.overlord.SpecificSegmentLockRequest; import org.apache.druid.indexing.overlord.SpecificSegmentLockRequest;
import org.apache.druid.indexing.overlord.TaskLockbox; import org.apache.druid.indexing.overlord.TaskLockbox;
import org.apache.druid.indexing.overlord.TaskStorage;
import org.apache.druid.indexing.overlord.TimeChunkLockRequest; import org.apache.druid.indexing.overlord.TimeChunkLockRequest;
import org.apache.druid.indexing.test.TestIndexerMetadataStorageCoordinator; import org.apache.druid.indexing.test.TestIndexerMetadataStorageCoordinator;
import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.DateTimes;
@ -62,11 +64,13 @@ public class TaskLocksTest
@Before @Before
public void setup() public void setup()
{ {
final TaskStorage taskStorage = new HeapMemoryTaskStorage(new TaskStorageConfig(null));
lockbox = new TaskLockbox( lockbox = new TaskLockbox(
new HeapMemoryTaskStorage(new TaskStorageConfig(null)), taskStorage,
new TestIndexerMetadataStorageCoordinator() new TestIndexerMetadataStorageCoordinator()
); );
task = NoopTask.create(); task = NoopTask.create();
taskStorage.insert(task, TaskStatus.running(task.getId()));
lockbox.add(task); lockbox.add(task);
} }
@ -296,6 +300,19 @@ public class TaskLocksTest
); );
} }
@Test
public void testRevokedLocksDoNotCoverSegments()
{
final Set<DataSegment> segments = createNumberedPartitionedSegments();
final Interval interval = Intervals.of("2017-01-01/2017-01-02");
final TaskLock lock = tryTimeChunkLock(task, interval, TaskLockType.EXCLUSIVE);
Assert.assertTrue(TaskLocks.isLockCoversSegments(task, lockbox, segments));
lockbox.revokeLock(task.getId(), lock);
Assert.assertFalse(TaskLocks.isLockCoversSegments(task, lockbox, segments));
}
@Test @Test
public void testFindReplaceLocksCoveringSegments() public void testFindReplaceLocksCoveringSegments()
{ {