diff --git a/.idea/inspectionProfiles/Druid.xml b/.idea/inspectionProfiles/Druid.xml index 5791c1c456b3..1dd160601d90 100644 --- a/.idea/inspectionProfiles/Druid.xml +++ b/.idea/inspectionProfiles/Druid.xml @@ -28,6 +28,10 @@ + + @@ -105,6 +109,7 @@ + diff --git a/benchmarks/src/main/java/org/apache/druid/server/coordinator/NewestSegmentFirstPolicyBenchmark.java b/benchmarks/src/main/java/org/apache/druid/server/coordinator/NewestSegmentFirstPolicyBenchmark.java index af1f1fe57d6a..91c1409b4071 100644 --- a/benchmarks/src/main/java/org/apache/druid/server/coordinator/NewestSegmentFirstPolicyBenchmark.java +++ b/benchmarks/src/main/java/org/apache/druid/server/coordinator/NewestSegmentFirstPolicyBenchmark.java @@ -24,9 +24,9 @@ import org.apache.druid.client.DataSourcesSnapshot; import org.apache.druid.jackson.DefaultObjectMapper; import org.apache.druid.java.util.common.DateTimes; -import org.apache.druid.server.coordinator.helper.CompactionSegmentIterator; -import org.apache.druid.server.coordinator.helper.CompactionSegmentSearchPolicy; -import org.apache.druid.server.coordinator.helper.NewestSegmentFirstPolicy; +import org.apache.druid.server.coordinator.duty.CompactionSegmentIterator; +import org.apache.druid.server.coordinator.duty.CompactionSegmentSearchPolicy; +import org.apache.druid.server.coordinator.duty.NewestSegmentFirstPolicy; import org.apache.druid.timeline.DataSegment; import org.apache.druid.timeline.VersionedIntervalTimeline; import org.apache.druid.timeline.partition.NumberedShardSpec; diff --git a/core/src/main/java/org/apache/druid/java/util/metrics/AllocationMetricCollectors.java b/core/src/main/java/org/apache/druid/java/util/metrics/AllocationMetricCollectors.java index 36ffb09cbced..f0d1b2c78e64 100644 --- a/core/src/main/java/org/apache/druid/java/util/metrics/AllocationMetricCollectors.java +++ b/core/src/main/java/org/apache/druid/java/util/metrics/AllocationMetricCollectors.java @@ -22,7 +22,6 @@ import org.apache.druid.java.util.common.logger.Logger; import javax.annotation.Nullable; - import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; import java.lang.reflect.Method; diff --git a/core/src/main/java/org/apache/druid/metadata/MetadataStorageConnector.java b/core/src/main/java/org/apache/druid/metadata/MetadataStorageConnector.java index 7f6df4213a28..45fb6639082c 100644 --- a/core/src/main/java/org/apache/druid/metadata/MetadataStorageConnector.java +++ b/core/src/main/java/org/apache/druid/metadata/MetadataStorageConnector.java @@ -19,6 +19,7 @@ package org.apache.druid.metadata; +import javax.annotation.Nullable; import java.util.List; /** @@ -36,7 +37,11 @@ Void insertOrUpdate( byte[] value ); - byte[] lookup( + /** + * Returns the value of the valueColumn when there is only one row matched to the given key. + * This method returns null if there is no such row and throws an error if there are more than one rows. + */ + @Nullable byte[] lookup( String tableName, String keyColumn, String valueColumn, diff --git a/core/src/main/java/org/apache/druid/metadata/MetadataStorageConnectorConfig.java b/core/src/main/java/org/apache/druid/metadata/MetadataStorageConnectorConfig.java index 8c84bbf89a30..a6651074588e 100644 --- a/core/src/main/java/org/apache/druid/metadata/MetadataStorageConnectorConfig.java +++ b/core/src/main/java/org/apache/druid/metadata/MetadataStorageConnectorConfig.java @@ -21,6 +21,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.druid.java.util.common.StringUtils; + import java.util.Properties; /** diff --git a/core/src/main/java/org/apache/druid/segment/SegmentUtils.java b/core/src/main/java/org/apache/druid/segment/SegmentUtils.java index a6d98a47566f..aae1643befda 100644 --- a/core/src/main/java/org/apache/druid/segment/SegmentUtils.java +++ b/core/src/main/java/org/apache/druid/segment/SegmentUtils.java @@ -19,6 +19,7 @@ package org.apache.druid.segment; +import com.google.common.collect.Collections2; import com.google.common.hash.HashFunction; import com.google.common.hash.Hasher; import com.google.common.hash.Hashing; @@ -37,7 +38,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; /** * Utility methods useful for implementing deep storage extensions. @@ -78,16 +78,14 @@ public static int getVersionFromDir(File inDir) throws IOException } /** - * Returns a String with identifiers of "segments" comma-separated. Useful for log messages. Not useful for anything - * else, because this doesn't take special effort to escape commas that occur in identifiers (not common, but could - * potentially occur in a datasource name). + * Returns an object whose toString() returns a String with identifiers of the given segments, comma-separated. Useful + * for log messages. Not useful for anything else, because this doesn't take special effort to escape commas that + * occur in identifiers (not common, but could potentially occur in a datasource name). */ - public static String commaSeparateIdentifiers(final Collection segments) + public static Object commaSeparatedIdentifiers(final Collection segments) { - return segments - .stream() - .map(segment -> segment.getId().toString()) - .collect(Collectors.joining(", ")); + // Lazy, to avoid preliminary string creation if logging level is turned off + return Collections2.transform(segments, DataSegment::getId); } private SegmentUtils() diff --git a/core/src/main/java/org/apache/druid/timeline/VersionedIntervalTimeline.java b/core/src/main/java/org/apache/druid/timeline/VersionedIntervalTimeline.java index 2f2646846ab8..ee2a9f36f68b 100644 --- a/core/src/main/java/org/apache/druid/timeline/VersionedIntervalTimeline.java +++ b/core/src/main/java/org/apache/druid/timeline/VersionedIntervalTimeline.java @@ -38,7 +38,6 @@ import java.util.Collection; import java.util.Comparator; import java.util.HashMap; -import java.util.HashSet; import java.util.IdentityHashMap; import java.util.Iterator; import java.util.List; @@ -56,25 +55,38 @@ /** * VersionedIntervalTimeline is a data structure that manages objects on a specific timeline. * - * It associates a jodatime Interval and a generically-typed version with the object that is being stored. + * It associates an {@link Interval} and a generically-typed version with the object that is being stored. * * In the event of overlapping timeline entries, timeline intervals may be chunked. The underlying data associated * with a timeline entry remains unchanged when chunking occurs. * - * After loading objects via the add() method, the lookup(Interval) method can be used to get the list of the most - * recent objects (according to the version) that match the given interval. The intent is that objects represent - * a certain time period and when you do a lookup(), you are asking for all of the objects that you need to look - * at in order to get a correct answer about that time period. + * After loading objects via the {@link #add} method, the {@link #lookup(Interval)} method can be used to get the list + * of the most recent objects (according to the version) that match the given interval. The intent is that objects + * represent a certain time period and when you do a {@link #lookup(Interval)}, you are asking for all of the objects + * that you need to look at in order to get a correct answer about that time period. * - * The {@link #findFullyOvershadowed} method returns a list of objects that will never be returned by a call to lookup() - * because they are overshadowed by some other object. This can be used in conjunction with the add() and remove() - * methods to achieve "atomic" updates. First add new items, then check if those items caused anything to be - * overshadowed, if so, remove the overshadowed elements and you have effectively updated your data set without any user - * impact. + * The {@link #findFullyOvershadowed} method returns a list of objects that will never be returned by a call to {@link + * #lookup} because they are overshadowed by some other object. This can be used in conjunction with the {@link #add} + * and {@link #remove} methods to achieve "atomic" updates. First add new items, then check if those items caused + * anything to be overshadowed, if so, remove the overshadowed elements and you have effectively updated your data set + * without any user impact. */ public class VersionedIntervalTimeline> implements TimelineLookup { + public static VersionedIntervalTimeline forSegments(Iterable segments) + { + return forSegments(segments.iterator()); + } + + public static VersionedIntervalTimeline forSegments(Iterator segments) + { + final VersionedIntervalTimeline timeline = + new VersionedIntervalTimeline<>(Comparator.naturalOrder()); + addSegments(timeline, segments); + return timeline; + } + private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); // Below timelines stores only *visible* timelineEntries @@ -99,19 +111,6 @@ public VersionedIntervalTimeline(Comparator versionComparat this.versionComparator = versionComparator; } - public static VersionedIntervalTimeline forSegments(Iterable segments) - { - return forSegments(segments.iterator()); - } - - public static VersionedIntervalTimeline forSegments(Iterator segments) - { - final VersionedIntervalTimeline timeline = - new VersionedIntervalTimeline<>(Comparator.naturalOrder()); - addSegments(timeline, segments); - return timeline; - } - public static void addSegments( VersionedIntervalTimeline timeline, Iterator segments @@ -151,6 +150,11 @@ public Collection iterateAllObjects() ); } + public int getNumObjects() + { + return numObjects.get(); + } + /** * Computes a set with all objects falling within the specified interval which are at least partially "visible" in * this interval (that is, are not fully overshadowed within this interval). @@ -371,62 +375,69 @@ public Set> findFullyOvershadowed( lock.readLock().lock(); try { // 1. Put all timelineEntries and remove all visible entries to find out only non-visible timelineEntries. - final Map> overShadowed = new HashMap<>(); - for (Map.Entry> versionEntry : allTimelineEntries.entrySet()) { - @SuppressWarnings("unchecked") - Map versionCopy = (TreeMap) versionEntry.getValue().clone(); - overShadowed.put(versionEntry.getKey(), versionCopy); - } - - for (Entry entry : completePartitionsTimeline.entrySet()) { - Map versionEntry = overShadowed.get(entry.getValue().getTrueInterval()); - if (versionEntry != null) { - versionEntry.remove(entry.getValue().getVersion()); - if (versionEntry.isEmpty()) { - overShadowed.remove(entry.getValue().getTrueInterval()); - } - } - } - - for (Entry entry : incompletePartitionsTimeline.entrySet()) { - Map versionEntry = overShadowed.get(entry.getValue().getTrueInterval()); - if (versionEntry != null) { - versionEntry.remove(entry.getValue().getVersion()); - if (versionEntry.isEmpty()) { - overShadowed.remove(entry.getValue().getTrueInterval()); - } - } - } - - final Set> retVal = new HashSet<>(); - for (Entry> versionEntry : overShadowed.entrySet()) { - for (Entry entry : versionEntry.getValue().entrySet()) { - final TimelineEntry timelineEntry = entry.getValue(); - retVal.add(timelineEntryToObjectHolder(timelineEntry)); - } - } + final Map> overshadowedPartitionsTimeline = + computeOvershadowedPartitionsTimeline(); + + final Set> overshadowedObjects = overshadowedPartitionsTimeline + .values() + .stream() + .flatMap( + (Map entry) -> entry.values().stream().map(this::timelineEntryToObjectHolder) + ) + .collect(Collectors.toSet()); - // 2. Visible timelineEntries can also have overshadowed segments. Add them to the result too. + // 2. Visible timelineEntries can also have overshadowed objects. Add them to the result too. for (TimelineEntry entry : incompletePartitionsTimeline.values()) { - final List> entryOvershadowed = entry.partitionHolder.getOvershadowed(); - if (!entryOvershadowed.isEmpty()) { - retVal.add( + final List> overshadowedEntries = entry.partitionHolder.getOvershadowed(); + if (!overshadowedEntries.isEmpty()) { + overshadowedObjects.add( new TimelineObjectHolder<>( entry.trueInterval, entry.version, - new PartitionHolder<>(entryOvershadowed) + new PartitionHolder<>(overshadowedEntries) ) ); } } - return retVal; + return overshadowedObjects; } finally { lock.readLock().unlock(); } } + private Map> computeOvershadowedPartitionsTimeline() + { + final Map> overshadowedPartitionsTimeline = new HashMap<>(); + allTimelineEntries.forEach((Interval interval, TreeMap versionEntry) -> { + @SuppressWarnings("unchecked") + Map versionEntryCopy = (TreeMap) versionEntry.clone(); + overshadowedPartitionsTimeline.put(interval, versionEntryCopy); + }); + + for (TimelineEntry entry : completePartitionsTimeline.values()) { + overshadowedPartitionsTimeline.computeIfPresent( + entry.getTrueInterval(), + (Interval interval, Map versionEntry) -> { + versionEntry.remove(entry.getVersion()); + return versionEntry.isEmpty() ? null : versionEntry; + } + ); + } + + for (TimelineEntry entry : incompletePartitionsTimeline.values()) { + overshadowedPartitionsTimeline.computeIfPresent( + entry.getTrueInterval(), + (Interval interval, Map versionEntry) -> { + versionEntry.remove(entry.getVersion()); + return versionEntry.isEmpty() ? null : versionEntry; + } + ); + } + return overshadowedPartitionsTimeline; + } + public boolean isOvershadowed(Interval interval, VersionType version, ObjectType object) { lock.readLock().lock(); diff --git a/core/src/main/java/org/apache/druid/timeline/partition/OvershadowableManager.java b/core/src/main/java/org/apache/druid/timeline/partition/OvershadowableManager.java index d3166aeefcbb..fcc77ddcd852 100644 --- a/core/src/main/java/org/apache/druid/timeline/partition/OvershadowableManager.java +++ b/core/src/main/java/org/apache/druid/timeline/partition/OvershadowableManager.java @@ -89,14 +89,19 @@ enum State // (start partitionId, end partitionId) -> minorVersion -> atomicUpdateGroup private final TreeMap>> standbyGroups; - private final TreeMap>> visibleGroup; + /** + * The values in this map must always be {@link SingleEntryShort2ObjectSortedMap}, hence there is at most one visible + * group per range. The same type is used as in {@link #standbyGroups} and {@link #overshadowedGroups} to reuse helper + * functions across all {@link State}s. + */ + private final TreeMap>> visibleGroupPerRange; private final TreeMap>> overshadowedGroups; OvershadowableManager() { this.knownPartitionChunks = new HashMap<>(); this.standbyGroups = new TreeMap<>(); - this.visibleGroup = new TreeMap<>(); + this.visibleGroupPerRange = new TreeMap<>(); this.overshadowedGroups = new TreeMap<>(); } @@ -104,7 +109,7 @@ enum State { this.knownPartitionChunks = new HashMap<>(other.knownPartitionChunks); this.standbyGroups = new TreeMap<>(other.standbyGroups); - this.visibleGroup = new TreeMap<>(other.visibleGroup); + this.visibleGroupPerRange = new TreeMap<>(other.visibleGroupPerRange); this.overshadowedGroups = new TreeMap<>(other.overshadowedGroups); } @@ -124,7 +129,7 @@ private TreeMap>> case STANDBY: return standbyGroups; case VISIBLE: - return visibleGroup; + return visibleGroupPerRange; case OVERSHADOWED: return overshadowedGroups; default: @@ -670,7 +675,7 @@ boolean addChunk(PartitionChunk chunk) final AtomicUpdateGroup newAtomicUpdateGroup = new AtomicUpdateGroup<>(chunk); // Decide the initial state of the new atomicUpdateGroup - final boolean overshadowed = visibleGroup + final boolean overshadowed = visibleGroupPerRange .values() .stream() .flatMap(map -> map.values().stream()) @@ -786,7 +791,7 @@ private List> findLatestNonFullyAvailableAtomicUpdateGroups } final List> visibles = new ArrayList<>(); - for (Short2ObjectSortedMap> map : manager.visibleGroup.values()) { + for (Short2ObjectSortedMap> map : manager.visibleGroupPerRange.values()) { visibles.addAll(map.values()); } return visibles; @@ -808,7 +813,7 @@ private List> findLatestFullyAvailableOvershadowedAtomicUpd final OvershadowableManager manager = new OvershadowableManager<>(overshadowedGroups); final List> visibles = new ArrayList<>(); - for (Short2ObjectSortedMap> map : manager.visibleGroup.values()) { + for (Short2ObjectSortedMap> map : manager.visibleGroupPerRange.values()) { for (AtomicUpdateGroup atomicUpdateGroup : map.values()) { if (!atomicUpdateGroup.isFull()) { return Collections.emptyList(); @@ -886,12 +891,15 @@ PartitionChunk removeChunk(PartitionChunk partitionChunk) public boolean isEmpty() { - return visibleGroup.isEmpty(); + return visibleGroupPerRange.isEmpty(); } public boolean isComplete() { - return visibleGroup.values().stream().allMatch(map -> Iterables.getOnlyElement(map.values()).isFull()); + return visibleGroupPerRange + .values() + .stream() + .allMatch(map -> Iterables.getOnlyElement(map.values()).isFull()); } @Nullable @@ -916,7 +924,7 @@ PartitionChunk getChunk(int partitionId) Stream> createVisibleChunksStream() { - return visibleGroup + return visibleGroupPerRange .values() .stream() .flatMap((Short2ObjectSortedMap> map) -> map.values().stream()) @@ -959,14 +967,14 @@ public boolean equals(Object o) OvershadowableManager that = (OvershadowableManager) o; return Objects.equals(knownPartitionChunks, that.knownPartitionChunks) && Objects.equals(standbyGroups, that.standbyGroups) && - Objects.equals(visibleGroup, that.visibleGroup) && + Objects.equals(visibleGroupPerRange, that.visibleGroupPerRange) && Objects.equals(overshadowedGroups, that.overshadowedGroups); } @Override public int hashCode() { - return Objects.hash(knownPartitionChunks, standbyGroups, visibleGroup, overshadowedGroups); + return Objects.hash(knownPartitionChunks, standbyGroups, visibleGroupPerRange, overshadowedGroups); } @Override @@ -975,7 +983,7 @@ public String toString() return "OvershadowableManager{" + "knownPartitionChunks=" + knownPartitionChunks + ", standbyGroups=" + standbyGroups + - ", visibleGroup=" + visibleGroup + + ", visibleGroupPerRangePerVersion=" + visibleGroupPerRange + ", overshadowedGroups=" + overshadowedGroups + '}'; } diff --git a/core/src/test/java/org/apache/druid/timeline/VersionedIntervalTimelineTest.java b/core/src/test/java/org/apache/druid/timeline/VersionedIntervalTimelineTest.java index c946bc88bf0a..c55e11369b90 100644 --- a/core/src/test/java/org/apache/druid/timeline/VersionedIntervalTimelineTest.java +++ b/core/src/test/java/org/apache/druid/timeline/VersionedIntervalTimelineTest.java @@ -648,7 +648,7 @@ public void testOverlapLargeUnderlyingWithSmallDayAlignedOverlays() createExpected("2011-01-04/2011-01-05", "3", 3), createExpected("2011-01-05/2011-01-06", "4", 4) ), - timeline.lookup(Intervals.of("0000-01-01/3000-01-01")) + timeline.lookup(Intervals.ETERNITY) ); } diff --git a/docs/configuration/index.md b/docs/configuration/index.md index dd0acc686968..ac4396602145 100644 --- a/docs/configuration/index.md +++ b/docs/configuration/index.md @@ -674,7 +674,7 @@ These Coordinator static configurations can be defined in the `coordinator/runti |Property|Description|Default| |--------|-----------|-------| -|`druid.coordinator.period`|The run period for the Coordinator. The Coordinator’s operates by maintaining the current state of the world in memory and periodically looking at the set of segments available and segments being served to make decisions about whether any changes need to be made to the data topology. This property sets the delay between each of these runs.|PT60S| +|`druid.coordinator.period`|The run period for the Coordinator. The Coordinator operates by maintaining the current state of the world in memory and periodically looking at the set of "used" segments and segments being served to make decisions about whether any changes need to be made to the data topology. This property sets the delay between each of these runs.|PT60S| |`druid.coordinator.period.indexingPeriod`|How often to send compact/merge/conversion tasks to the indexing service. It's recommended to be longer than `druid.manager.segments.pollDuration`|PT1800S (30 mins)| |`druid.coordinator.startDelay`|The operation of the Coordinator works on the assumption that it has an up-to-date view of the state of the world when it runs, the current ZK interaction code, however, is written in a way that doesn’t allow the Coordinator to know for a fact that it’s done loading the current state of the world. This delay is a hack to give it enough time to believe that it has all the data.|PT300S| |`druid.coordinator.load.timeout`|The timeout duration for when the Coordinator assigns a segment to a Historical process.|PT15M| @@ -749,7 +749,7 @@ Issuing a GET request at the same URL will return the spec that is currently in |Property|Description|Default| |--------|-----------|-------| -|`millisToWaitBeforeDeleting`|How long does the Coordinator need to be active before it can start removing (marking unused) segments in metadata storage.|900000 (15 mins)| +|`millisToWaitBeforeDeleting`|How long does the Coordinator need to be a leader before it can start marking overshadowed segments as unused in metadata storage.|900000 (15 mins)| |`mergeBytesLimit`|The maximum total uncompressed size in bytes of segments to merge.|524288000L| |`mergeSegmentsLimit`|The maximum number of segments that can be in a single [append task](../ingestion/tasks.md).|100| |`maxSegmentsToMove`|The maximum number of segments that can be moved at any given time.|5| @@ -757,9 +757,9 @@ Issuing a GET request at the same URL will return the spec that is currently in |`replicationThrottleLimit`|The maximum number of segments that can be replicated at one time.|10| |`balancerComputeThreads`|Thread pool size for computing moving cost of segments in segment balancing. Consider increasing this if you have a lot of segments and moving segments starts to get stuck.|1| |`emitBalancingStats`|Boolean flag for whether or not we should emit balancing stats. This is an expensive operation.|false| -|`killDataSourceWhitelist`|List of dataSources for which kill tasks are sent if property `druid.coordinator.kill.on` is true. This can be a list of comma-separated dataSources or a JSON array.|none| +|`killDataSourceWhitelist`|List of specific data sources for which kill tasks are sent if property `druid.coordinator.kill.on` is true. This can be a list of comma-separated data source names or a JSON array.|none| |`killAllDataSources`|Send kill tasks for ALL dataSources if property `druid.coordinator.kill.on` is true. If this is set to true then `killDataSourceWhitelist` must not be specified or be empty list.|false| -|`killPendingSegmentsSkipList`|List of dataSources for which pendingSegments are _NOT_ cleaned up if property `druid.coordinator.kill.pendingSegments.on` is true. This can be a list of comma-separated dataSources or a JSON array.|none| +|`killPendingSegmentsSkipList`|List of data sources for which pendingSegments are _NOT_ cleaned up if property `druid.coordinator.kill.pendingSegments.on` is true. This can be a list of comma-separated data sources or a JSON array.|none| |`maxSegmentsInNodeLoadingQueue`|The maximum number of segments that could be queued for loading to any given server. This parameter could be used to speed up segments loading process, especially if there are "slow" nodes in the cluster (with low loading speed) or if too much segments scheduled to be replicated to some particular node (faster loading could be preferred to better segments distribution). Desired value depends on segments loading speed, acceptable replication time and number of nodes. Value 1000 could be a start point for a rather big cluster. Default value is 0 (loading queue is unbounded) |0| |`decommissioningNodes`| List of historical servers to 'decommission'. Coordinator will not assign new segments to 'decommissioning' servers, and segments will be moved away from them to be placed on non-decommissioning servers at the maximum rate specified by `decommissioningMaxPercentOfMaxSegmentsToMove`.|none| |`decommissioningMaxPercentOfMaxSegmentsToMove`| The maximum number of segments that may be moved away from 'decommissioning' servers to non-decommissioning (that is, active) servers during one Coordinator run. This value is relative to the total maximum segment movements allowed during one run which is determined by `maxSegmentsToMove`. If `decommissioningMaxPercentOfMaxSegmentsToMove` is 0, segments will neither be moved from _or to_ 'decommissioning' servers, effectively putting them in a sort of "maintenance" mode that will not participate in balancing or assignment by load rules. Decommissioning can also become stalled if there are no available active servers to place the segments. By leveraging the maximum percent of decommissioning segment movements, an operator can prevent active servers from overload by prioritizing balancing, or decrease decommissioning time instead. The value should be between 0 and 100.|70| @@ -993,8 +993,8 @@ Worker select strategies control how Druid assigns tasks to MiddleManagers. ###### Equal Distribution -Tasks are assigned to the MiddleManager with the most available capacity at the time the task begins running. This is -useful if you want work evenly distributed across your MiddleManagers. +Tasks are assigned to the MiddleManager with the most free slots at the time the task begins running. This is useful if +you want work evenly distributed across your MiddleManagers. |Property|Description|Default| |--------|-----------|-------| @@ -1160,7 +1160,7 @@ Middle managers pass their configurations down to their child peons. The MiddleM |`druid.indexer.runner.ports`|A JSON array of integers to specify ports that used for peon processes. If provided and non-empty, ports for peon processes will be chosen from these ports. And `druid.indexer.runner.startPort/druid.indexer.runner.endPort` will be completely ignored.|`[]`| |`druid.worker.ip`|The IP of the worker.|localhost| |`druid.worker.version`|Version identifier for the MiddleManager.|0| -|`druid.worker.capacity`|Maximum number of tasks the MiddleManager can accept.|Number of available processors - 1| +|`druid.worker.capacity`|Maximum number of tasks the MiddleManager can accept.|Number of CPUs on the machine - 1| |`druid.worker.category`|A string to name the category that the MiddleManager node belongs to.|`__default_worker_category`| #### Peon Processing @@ -1599,8 +1599,9 @@ See [cache configuration](#cache-configuration) for how to configure cache setti This section describes caching configuration that is common to Broker, Historical, and MiddleManager/Peon processes. -Caching can optionally be enabled on the Broker, Historical, and MiddleManager/Peon processes. See [Broker](#broker-caching), -[Historical](#historical-caching), and [Peon](#peon-caching) configuration options for how to enable it for different processes. +Caching could optionally be enabled on the Broker, Historical, and MiddleManager/Peon processes. See +[Broker](#broker-caching), [Historical](#historical-caching), and [Peon](#peon-caching) configuration options for how to +enable it for different processes. Druid uses a local in-memory cache by default, unless a different type of cache is specified. Use the `druid.cache.type` configuration to set a different kind of cache. diff --git a/docs/dependencies/metadata-storage.md b/docs/dependencies/metadata-storage.md index 072d00d8e92a..51551a1df010 100644 --- a/docs/dependencies/metadata-storage.md +++ b/docs/dependencies/metadata-storage.md @@ -71,18 +71,15 @@ See [BasicDataSource Configuration](https://commons.apache.org/proper/commons-db This is dictated by the `druid.metadata.storage.tables.segments` property. -This table stores metadata about the segments that are available in the system. -The table is polled by the [Coordinator](../design/coordinator.md) to -determine the set of segments that should be available for querying in the -system. The table has two main functional columns, the other columns are for -indexing purposes. - -The `used` column is a boolean "tombstone". A 1 means that the segment should -be "used" by the cluster (i.e., it should be loaded and available for requests). -A 0 means that the segment should not be actively loaded into the cluster. We -do this as a means of removing segments from the cluster without actually -removing their metadata (which allows for simpler rolling back if that is ever -an issue). +This table stores metadata about the segments that should be available in the system. (This set of segments is called +"used segments" elsewhere in the documentation and throughout the project.) The table is polled by the +[Coordinator](../design/coordinator.md) to determine the set of segments that should be available for querying in the +system. The table has two main functional columns, the other columns are for indexing purposes. + +Value 1 in the `used` column means that the segment should be "used" by the cluster (i.e., it should be loaded and +available for requests). Value 0 means that the segment should not be loaded into the cluster. We do this as a means of +unloading segments from the cluster without actually removing their metadata (which allows for simpler rolling back if +that is ever an issue). The `payload` column stores a JSON blob that has all of the metadata for the segment (some of the data stored in this payload is redundant with some of the columns in the table, that is intentional). This looks something like diff --git a/docs/design/architecture.md b/docs/design/architecture.md index a369e216db64..c801cc54154b 100644 --- a/docs/design/architecture.md +++ b/docs/design/architecture.md @@ -69,8 +69,8 @@ if every single data server is lost and re-provisioned. For more details, please see the [Deep storage](../dependencies/deep-storage.md) page. ### Metadata storage -The metadata storage holds various shared system metadata such as segment availability information and task information. -In a clustered deployment, this is typically going to be a traditional RDBMS like PostgreSQL or MySQL. In a single-server +The metadata storage holds various shared system metadata such as segment usage information and task information. In a +clustered deployment, this is typically going to be a traditional RDBMS like PostgreSQL or MySQL. In a single-server deployment, it is typically going to be a locally-stored Apache Derby database. For more details, please see the [Metadata storage](../dependencies/metadata-storage.md) page. diff --git a/docs/design/coordinator.md b/docs/design/coordinator.md index fbf5455cd0cf..faba68bcb37d 100644 --- a/docs/design/coordinator.md +++ b/docs/design/coordinator.md @@ -33,11 +33,24 @@ For a list of API endpoints supported by the Coordinator, see [Coordinator API]( ### Overview -The Druid Coordinator process is primarily responsible for segment management and distribution. More specifically, the Druid Coordinator process communicates to Historical processes to load or drop segments based on configurations. The Druid Coordinator is responsible for loading new segments, dropping outdated segments, managing segment replication, and balancing segment load. - -The Druid Coordinator runs periodically and the time between each run is a configurable parameter. Each time the Druid Coordinator runs, it assesses the current state of the cluster before deciding on the appropriate actions to take. Similar to the Broker and Historical processes, the Druid Coordinator maintains a connection to a Zookeeper cluster for current cluster information. The Coordinator also maintains a connection to a database containing information about available segments and rules. Available segments are stored in a segment table and list all segments that should be loaded in the cluster. Rules are stored in a rule table and indicate how segments should be handled. - -Before any unassigned segments are serviced by Historical processes, the available Historical processes for each tier are first sorted in terms of capacity, with least capacity servers having the highest priority. Unassigned segments are always assigned to the processes with least capacity to maintain a level of balance between processes. The Coordinator does not directly communicate with a historical process when assigning it a new segment; instead the Coordinator creates some temporary information about the new segment under load queue path of the historical process. Once this request is seen, the historical process will load the segment and begin servicing it. +The Druid Coordinator process is primarily responsible for segment management and distribution. More specifically, the +Druid Coordinator process communicates to Historical processes to load or drop segments based on configurations. The +Druid Coordinator is responsible for loading new segments, dropping outdated segments, ensuring that segments are +"replicated" (that is, loaded on multiple different Historical nodes) proper (configured) number of times, and moving +("balancing") segments between Historical nodes to keep the latter evenly loaded. + +The Druid Coordinator runs its duties periodically and the time between each run is a configurable parameter. On each +run, the Coordinator assesses the current state of the cluster before deciding on the appropriate actions to take. +Similar to the Broker and Historical processes, the Druid Coordinator maintains a connection to a Zookeeper cluster for +current cluster information. The Coordinator also maintains a connection to a database containing information about +"used" segments (that is, the segments that *should* be loaded in the cluster) and the loading rules. + +Before any unassigned segments are serviced by Historical processes, the Historical processes for each tier are first +sorted in terms of capacity, with least capacity servers having the highest priority. Unassigned segments are always +assigned to the processes with least capacity to maintain a level of balance between processes. The Coordinator does not +directly communicate with a historical process when assigning it a new segment; instead the Coordinator creates some +temporary information about the new segment under load queue path of the historical process. Once this request is seen, +the historical process will load the segment and begin servicing it. ### Running @@ -51,7 +64,12 @@ Segments can be automatically loaded and dropped from the cluster based on a set ### Cleaning up segments -Each run, the Druid coordinator compares the list of available database segments in the database with the current segments in the cluster. Segments that are not in the database but are still being served in the cluster are flagged and appended to a removal list. Segments that are overshadowed (their versions are too old and their data has been replaced by newer segments) are also dropped. +On each run, the Druid Coordinator compares the set of used segments in the database with the segments served by some +Historical nodes in the cluster. Coordinator sends requests to Historical nodes to unload unused segments or segments +that are removed from the database. + +Segments that are overshadowed (their versions are too old and their data has been replaced by newer segments) are +marked as unused. During the next Coordinator's run, they will be unloaded from Historical nodes in the cluster. ### Segment availability diff --git a/docs/operations/api-reference.md b/docs/operations/api-reference.md index 4537b5f5f47d..db11cfe6c040 100644 --- a/docs/operations/api-reference.md +++ b/docs/operations/api-reference.md @@ -146,7 +146,8 @@ Returns a list of all segments for a datasource with the full segment metadata a * `/druid/coordinator/v1/metadata/datasources/{dataSourceName}/segments/{segmentId}` -Returns full segment metadata for a specific segment as stored in the metadata store. +Returns full segment metadata for a specific segment as stored in the metadata store, if the segment is used. If the +segment is unused, or is unknown, a 404 response is returned. ##### POST diff --git a/docs/operations/metrics.md b/docs/operations/metrics.md index 5c0da46f0905..ac6bd095063f 100644 --- a/docs/operations/metrics.md +++ b/docs/operations/metrics.md @@ -203,17 +203,20 @@ These metrics are for the Druid Coordinator and are reset each time the Coordina |`segment/loadQueue/failed`|Number of segments that failed to load.|server.|0| |`segment/loadQueue/count`|Number of segments to load.|server.|Varies.| |`segment/dropQueue/count`|Number of segments to drop.|server.|Varies.| -|`segment/size`|Size in bytes of available segments.|dataSource.|Varies.| -|`segment/count`|Number of available segments.|dataSource.|< max| -|`segment/overShadowed/count`|Number of overShadowed segments.||Varies.| -|`segment/unavailable/count`|Number of segments (not including replicas) left to load until segments that should be loaded in the cluster are available for queries.|datasource.|0| -|`segment/underReplicated/count`|Number of segments (including replicas) left to load until segments that should be loaded in the cluster are available for queries.|tier, datasource.|0| +|`segment/size`|Total size of used segments in a data source. Emitted only for data sources to which at least one used segment belongs.|dataSource.|Varies.| +|`segment/count`|Number of used segments belonging to a data source. Emitted only for data sources to which at least one used segment belongs.|dataSource.|< max| +|`segment/overShadowed/count`|Number of overshadowed segments.||Varies.| +|`segment/unavailable/count`|Number of segments (not including replicas) left to load until segments that should be loaded in the cluster are available for queries.|dataSource.|0| +|`segment/underReplicated/count`|Number of segments (including replicas) left to load until segments that should be loaded in the cluster are available for queries.|tier, dataSource.|0| |`tier/historical/count`|Number of available historical nodes in each tier.|tier.|Varies.| |`tier/replication/factor`|Configured maximum replication factor in each tier.|tier.|Varies.| |`tier/required/capacity`|Total capacity in bytes required in each tier.|tier.|Varies.| |`tier/total/capacity`|Total capacity in bytes available in each tier.|tier.|Varies.| -If `emitBalancingStats` is set to `true` in the Coordinator [dynamic configuration](../configuration/index.html#dynamic-configuration), then [log entries](../configuration/logging.md) for class `org.apache.druid.server.coordinator.helper.DruidCoordinatorLogger` will have extra information on balancing decisions. +If `emitBalancingStats` is set to `true` in the Coordinator [dynamic configuration]( +../configuration/index.html#dynamic-configuration), then [log entries](../configuration/logging.md) for class +`org.apache.druid.server.coordinator.duty.EmitClusterStatsAndMetrics` will have extra information on balancing +decisions. ## General Health diff --git a/docs/operations/rule-configuration.md b/docs/operations/rule-configuration.md index e66eef02be7f..4228994a30d3 100644 --- a/docs/operations/rule-configuration.md +++ b/docs/operations/rule-configuration.md @@ -26,9 +26,12 @@ title: "Retaining or automatically dropping data" In Apache Druid, Coordinator processes use rules to determine what data should be loaded to or dropped from the cluster. Rules are used for data retention and query execution, and are set on the Coordinator console (http://coordinator_ip:port). There are three types of rules, i.e., load rules, drop rules, and broadcast rules. Load rules indicate how segments should be assigned to different historical process tiers and how many replicas of a segment should exist in each tier. -Drop rules indicate when segments should be dropped entirely from the cluster. Finally, broadcast rules indicate how segments of different data sources should be co-located in Historical processes. +Drop rules indicate when segments should be dropped entirely from the cluster. Finally, broadcast rules indicate how segments of different datasources should be co-located in Historical processes. -The Coordinator loads a set of rules from the metadata storage. Rules may be specific to a certain datasource and/or a default set of rules can be configured. Rules are read in order and hence the ordering of rules is important. The Coordinator will cycle through all available segments and match each segment with the first rule that applies. Each segment may only match a single rule. +The Coordinator loads a set of rules from the metadata storage. Rules may be specific to a certain datasource and/or a +default set of rules can be configured. Rules are read in order and hence the ordering of rules is important. The +Coordinator will cycle through all used segments and match each segment with the first rule that applies. Each segment +may only match a single rule. Note: It is recommended that the Coordinator console is used to configure rules. However, the Coordinator process does have HTTP endpoints to programmatically configure rules. @@ -167,8 +170,8 @@ The interval of a segment will be compared against the specified period. The per ## Broadcast Rules -Broadcast rules indicate how segments of different data sources should be co-located in Historical processes. -Once a broadcast rule is configured for a data source, all segments of the data source are broadcasted to the servers holding _any segments_ of the co-located data sources. +Broadcast rules indicate how segments of different datasources should be co-located in Historical processes. +Once a broadcast rule is configured for a datasource, all segments of the datasource are broadcasted to the servers holding _any segments_ of the co-located datasources. ### Forever Broadcast Rule @@ -182,7 +185,7 @@ Forever broadcast rules are of the form: ``` * `type` - this should always be "broadcastForever" -* `colocatedDataSources` - A JSON List containing data source names to be co-located. `null` and empty list means broadcasting to every process in the cluster. +* `colocatedDataSources` - A JSON List containing datasource names to be co-located. `null` and empty list means broadcasting to every process in the cluster. ### Interval Broadcast Rule @@ -197,7 +200,7 @@ Interval broadcast rules are of the form: ``` * `type` - this should always be "broadcastByInterval" -* `colocatedDataSources` - A JSON List containing data source names to be co-located. `null` and empty list means broadcasting to every process in the cluster. +* `colocatedDataSources` - A JSON List containing datasource names to be co-located. `null` and empty list means broadcasting to every process in the cluster. * `interval` - A JSON Object representing ISO-8601 Periods. Only the segments of the interval will be broadcasted. ### Period Broadcast Rule @@ -214,21 +217,24 @@ Period broadcast rules are of the form: ``` * `type` - this should always be "broadcastByPeriod" -* `colocatedDataSources` - A JSON List containing data source names to be co-located. `null` and empty list means broadcasting to every process in the cluster. +* `colocatedDataSources` - A JSON List containing datasource names to be co-located. `null` and empty list means broadcasting to every process in the cluster. * `period` - A JSON Object representing ISO-8601 Periods * `includeFuture` - A JSON Boolean indicating whether the load period should include the future. This property is optional, Default is true. The interval of a segment will be compared against the specified period. The period is from some time in the past to the future or to the current time, which depends on `includeFuture` is true or false. The rule matches if the period *overlaps* the interval. -> broadcast rules don't guarantee that segments of the data sources are always co-located because segments for the colocated data sources are not loaded together atomically. -> If you want to always co-locate the segments of some data sources together, it is recommended to leave colocatedDataSources empty. +> broadcast rules don't guarantee that segments of the datasources are always co-located because segments for the colocated datasources are not loaded together atomically. +> If you want to always co-locate the segments of some datasources together, it is recommended to leave colocatedDataSources empty. ## Permanently deleting data -Druid can fully drop data from the cluster, wipe the metadata store entry, and remove the data from deep storage for any segments that are -marked as unused (segments dropped from the cluster via rules are always marked as unused). You can submit a [kill task](../ingestion/tasks.md) to the [Overlord](../design/overlord.md) to do this. +Druid can fully drop data from the cluster, wipe the metadata store entry, and remove the data from deep storage for any +segments that are marked as unused (segments dropped from the cluster via rules are always marked as unused). You can +submit a [kill task](../ingestion/tasks.md) to the [Overlord](../design/overlord.md) to do this. ## Reloading dropped data -Data that has been dropped from a Druid cluster cannot be reloaded using only rules. To reload dropped data in Druid, you must first set your retention period (i.e. changing the retention period from 1 month to 2 months), and -then enable the datasource in the Druid Coordinator console, or through the Druid Coordinator endpoints. +Data that has been dropped from a Druid cluster cannot be reloaded using only rules. To reload dropped data in Druid, +you must first set your retention period (i.e. changing the retention period from 1 month to 2 months), and then mark as +used all segments belonging to the datasource in the Druid Coordinator console, or through the Druid Coordinator +endpoints. diff --git a/extensions-contrib/materialized-view-maintenance/src/main/java/org/apache/druid/indexing/materializedview/MaterializedViewSupervisor.java b/extensions-contrib/materialized-view-maintenance/src/main/java/org/apache/druid/indexing/materializedview/MaterializedViewSupervisor.java index bd43ac639a49..dd3db5008a97 100644 --- a/extensions-contrib/materialized-view-maintenance/src/main/java/org/apache/druid/indexing/materializedview/MaterializedViewSupervisor.java +++ b/extensions-contrib/materialized-view-maintenance/src/main/java/org/apache/druid/indexing/materializedview/MaterializedViewSupervisor.java @@ -39,7 +39,6 @@ import org.apache.druid.indexing.overlord.supervisor.SupervisorStateManager; import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.IAE; -import org.apache.druid.java.util.common.Intervals; import org.apache.druid.java.util.common.JodaUtils; import org.apache.druid.java.util.common.Pair; import org.apache.druid.java.util.common.StringUtils; @@ -48,7 +47,7 @@ import org.apache.druid.java.util.emitter.EmittingLogger; import org.apache.druid.metadata.EntryExistsException; import org.apache.druid.metadata.MetadataSupervisorManager; -import org.apache.druid.metadata.SQLMetadataSegmentManager; +import org.apache.druid.metadata.SqlSegmentsMetadataManager; import org.apache.druid.timeline.DataSegment; import org.joda.time.Duration; import org.joda.time.Interval; @@ -64,18 +63,17 @@ import java.util.SortedMap; import java.util.TreeMap; import java.util.concurrent.TimeUnit; -import java.util.function.IntSupplier; public class MaterializedViewSupervisor implements Supervisor { private static final EmittingLogger log = new EmittingLogger(MaterializedViewSupervisor.class); - private static final Interval ALL_INTERVAL = Intervals.of("0000-01-01/3000-01-01"); private static final int DEFAULT_MAX_TASK_COUNT = 1; // there is a lag between derivatives and base dataSource, to prevent repeatedly building for some delay data. - private static final long DEFAULT_MIN_DATA_LAG_MS = 24 * 3600 * 1000L; + private static final long DEFAULT_MIN_DATA_LAG_MS = TimeUnit.DAYS.toMillis(1); + private final MetadataSupervisorManager metadataSupervisorManager; private final IndexerMetadataStorageCoordinator metadataStorageCoordinator; - private final SQLMetadataSegmentManager segmentManager; + private final SqlSegmentsMetadataManager sqlSegmentsMetadataManager; private final MaterializedViewSupervisorSpec spec; private final TaskMaster taskMaster; private final TaskStorage taskStorage; @@ -102,7 +100,7 @@ public MaterializedViewSupervisor( TaskMaster taskMaster, TaskStorage taskStorage, MetadataSupervisorManager metadataSupervisorManager, - SQLMetadataSegmentManager segmentManager, + SqlSegmentsMetadataManager sqlSegmentsMetadataManager, IndexerMetadataStorageCoordinator metadataStorageCoordinator, MaterializedViewTaskConfig config, MaterializedViewSupervisorSpec spec @@ -111,7 +109,7 @@ public MaterializedViewSupervisor( this.taskMaster = taskMaster; this.taskStorage = taskStorage; this.metadataStorageCoordinator = metadataStorageCoordinator; - this.segmentManager = segmentManager; + this.sqlSegmentsMetadataManager = sqlSegmentsMetadataManager; this.metadataSupervisorManager = metadataSupervisorManager; this.config = config; this.spec = spec; @@ -132,7 +130,7 @@ public void start() synchronized (stateLock) { Preconditions.checkState(!started, "already started"); - DataSourceMetadata metadata = metadataStorageCoordinator.getDataSourceMetadata(dataSource); + DataSourceMetadata metadata = metadataStorageCoordinator.retrieveDataSourceMetadata(dataSource); if (null == metadata) { metadataStorageCoordinator.insertDataSourceMetadata( dataSource, @@ -164,7 +162,7 @@ public void run() return; } - DataSourceMetadata metadata = metadataStorageCoordinator.getDataSourceMetadata(dataSource); + DataSourceMetadata metadata = metadataStorageCoordinator.retrieveDataSourceMetadata(dataSource); if (metadata instanceof DerivativeDataSourceMetadata && spec.getBaseDataSource().equals(((DerivativeDataSourceMetadata) metadata).getBaseDataSource()) && spec.getDimensions().equals(((DerivativeDataSourceMetadata) metadata).getDimensions()) @@ -259,7 +257,7 @@ public void reset(DataSourceMetadata dataSourceMetadata) { if (dataSourceMetadata == null) { // if oldMetadata is different from spec, tasks and segments will be removed when reset. - DataSourceMetadata oldMetadata = metadataStorageCoordinator.getDataSourceMetadata(dataSource); + DataSourceMetadata oldMetadata = metadataStorageCoordinator.retrieveDataSourceMetadata(dataSource); if (oldMetadata instanceof DerivativeDataSourceMetadata) { if (!((DerivativeDataSourceMetadata) oldMetadata).getBaseDataSource().equals(spec.getBaseDataSource()) || !((DerivativeDataSourceMetadata) oldMetadata).getDimensions().equals(spec.getDimensions()) || @@ -308,7 +306,8 @@ void checkSegmentsAndSubmitTasks() //if the number of running tasks reach the max task count, supervisor won't submit new tasks. return; } - Pair, Map>> toBuildIntervalAndBaseSegments = checkSegments(); + Pair, Map>> toBuildIntervalAndBaseSegments = + checkSegments(); SortedMap sortedToBuildVersion = toBuildIntervalAndBaseSegments.lhs; Map> baseSegments = toBuildIntervalAndBaseSegments.rhs; missInterval = sortedToBuildVersion.keySet(); @@ -339,21 +338,14 @@ Pair, Map> getRunningTasks() Pair, Map>> checkSegments() { // Pair version, interval -> list> + Collection derivativeSegmentsCollection = + metadataStorageCoordinator.retrieveAllUsedSegments(dataSource, Segments.ONLY_VISIBLE); Pair, Map>> derivativeSegmentsSnapshot = - getVersionAndBaseSegments( - metadataStorageCoordinator.getUsedSegmentsForInterval( - dataSource, - ALL_INTERVAL, - Segments.ONLY_VISIBLE - ) - ); + getVersionAndBaseSegments(derivativeSegmentsCollection); // Pair max(created_date), interval -> list> Pair, Map>> baseSegmentsSnapshot = getMaxCreateDateAndBaseSegments( - metadataStorageCoordinator.getUsedSegmentAndCreatedDateForInterval( - spec.getBaseDataSource(), - ALL_INTERVAL - ) + metadataStorageCoordinator.retrieveUsedSegmentsAndCreatedDates(spec.getBaseDataSource()) ); // baseSegments are used to create HadoopIndexTask Map> baseSegments = baseSegmentsSnapshot.rhs; @@ -375,31 +367,32 @@ Pair, Map>> checkSegment final String versionOfBase = maxCreatedDate.get(entry.getKey()); final String versionOfDerivative = derivativeVersion.get(entry.getKey()); final int baseCount = baseSegments.get(entry.getKey()).size(); - final IntSupplier usedCountSupplier = () -> - metadataStorageCoordinator - .getUsedSegmentsForInterval(spec.getBaseDataSource(), entry.getKey(), Segments.ONLY_VISIBLE).size(); - if (versionOfBase.compareTo(versionOfDerivative) > 0 && baseCount == usedCountSupplier.getAsInt()) { - toBuildInterval.put(entry.getKey(), versionOfBase); + if (versionOfBase.compareTo(versionOfDerivative) > 0) { + int usedCount = metadataStorageCoordinator + .retrieveUsedSegmentsForInterval(spec.getBaseDataSource(), entry.getKey(), Segments.ONLY_VISIBLE).size(); + if (baseCount == usedCount) { + toBuildInterval.put(entry.getKey(), versionOfBase); + } } } // if some intervals are in running tasks and the versions are the same, remove it from toBuildInterval - // if some intervals are in running tasks, but the versions are different, stop the task. - for (Map.Entry version : runningVersion.entrySet()) { - final Interval interval = version.getKey(); - final String host = version.getValue(); - if (toBuildInterval.containsKey(interval) && toBuildInterval.get(interval).equals(host)) { - toBuildInterval.remove(interval); - } else if (toBuildInterval.containsKey(interval) && !toBuildInterval.get(interval).equals(host)) { - if (taskMaster.getTaskQueue().isPresent()) { - taskMaster.getTaskQueue().get().shutdown(runningTasks.get(interval).getId(), "version mismatch"); - runningTasks.remove(interval); + // if some intervals are in running tasks, but the versions are different, stop the task. + runningVersion.forEach((interval, version) -> { + if (toBuildInterval.containsKey(interval)) { + if (toBuildInterval.get(interval).equals(version)) { + toBuildInterval.remove(interval); + } else { + if (taskMaster.getTaskQueue().isPresent()) { + taskMaster.getTaskQueue().get().shutdown(runningTasks.get(interval).getId(), "version mismatch"); + runningTasks.remove(interval); + } } } - } + }); // drop derivative segments which interval equals the interval in toDeleteBaseSegments for (Interval interval : toDropInterval.keySet()) { for (DataSegment segment : derivativeSegments.get(interval)) { - segmentManager.markSegmentAsUnused(segment.getId().toString()); + sqlSegmentsMetadataManager.markSegmentAsUnused(segment.getId().toString()); } } // data of the latest interval will be built firstly. @@ -441,8 +434,7 @@ private Pair, Map>> getVersion for (DataSegment segment : snapshot) { Interval interval = segment.getInterval(); versions.put(interval, segment.getVersion()); - segments.putIfAbsent(interval, new ArrayList<>()); - segments.get(interval).add(segment); + segments.computeIfAbsent(interval, i -> new ArrayList<>()).add(segment); } return new Pair<>(versions, segments); } @@ -465,15 +457,10 @@ private Pair, Map>> getMaxCrea if (!hasEnoughLag(interval, maxAllowedToBuildInterval)) { continue; } - maxCreatedDate.put( - interval, - DateTimes.max( - DateTimes.of(createDate), - DateTimes.of(maxCreatedDate.getOrDefault(interval, DateTimes.MIN.toString())) - ).toString() - ); - segments.putIfAbsent(interval, new ArrayList<>()); - segments.get(interval).add(segment); + maxCreatedDate.merge(interval, createDate, (date1, date2) -> { + return DateTimes.max(DateTimes.of(date1), DateTimes.of(date2)).toString(); + }); + segments.computeIfAbsent(interval, i -> new ArrayList<>()).add(segment); } return new Pair<>(maxCreatedDate, segments); } @@ -506,8 +493,8 @@ private void clearTasks() private void clearSegments() { log.info("Clear all metadata of dataSource %s", dataSource); - metadataStorageCoordinator.deletePendingSegments(dataSource, ALL_INTERVAL); - segmentManager.markAsUnusedAllSegmentsInDataSource(dataSource); + metadataStorageCoordinator.deletePendingSegments(dataSource); + sqlSegmentsMetadataManager.markAsUnusedAllSegmentsInDataSource(dataSource); metadataStorageCoordinator.deleteDataSourceMetadata(dataSource); } diff --git a/extensions-contrib/materialized-view-maintenance/src/main/java/org/apache/druid/indexing/materializedview/MaterializedViewSupervisorSpec.java b/extensions-contrib/materialized-view-maintenance/src/main/java/org/apache/druid/indexing/materializedview/MaterializedViewSupervisorSpec.java index 0e25841fe3c6..dd385130c761 100644 --- a/extensions-contrib/materialized-view-maintenance/src/main/java/org/apache/druid/indexing/materializedview/MaterializedViewSupervisorSpec.java +++ b/extensions-contrib/materialized-view-maintenance/src/main/java/org/apache/druid/indexing/materializedview/MaterializedViewSupervisorSpec.java @@ -43,7 +43,7 @@ import org.apache.druid.java.util.common.StringUtils; import org.apache.druid.java.util.common.granularity.Granularities; import org.apache.druid.metadata.MetadataSupervisorManager; -import org.apache.druid.metadata.SQLMetadataSegmentManager; +import org.apache.druid.metadata.SqlSegmentsMetadataManager; import org.apache.druid.query.aggregation.AggregatorFactory; import org.apache.druid.segment.indexing.DataSchema; import org.apache.druid.segment.indexing.granularity.ArbitraryGranularitySpec; @@ -77,7 +77,7 @@ public class MaterializedViewSupervisorSpec implements SupervisorSpec private final ObjectMapper objectMapper; private final MetadataSupervisorManager metadataSupervisorManager; private final IndexerMetadataStorageCoordinator metadataStorageCoordinator; - private final SQLMetadataSegmentManager segmentManager; + private final SqlSegmentsMetadataManager sqlSegmentsMetadataManager; private final TaskMaster taskMaster; private final TaskStorage taskStorage; private final MaterializedViewTaskConfig config; @@ -101,7 +101,7 @@ public MaterializedViewSupervisorSpec( @JacksonInject TaskMaster taskMaster, @JacksonInject TaskStorage taskStorage, @JacksonInject MetadataSupervisorManager metadataSupervisorManager, - @JacksonInject SQLMetadataSegmentManager segmentManager, + @JacksonInject SqlSegmentsMetadataManager sqlSegmentsMetadataManager, @JacksonInject IndexerMetadataStorageCoordinator metadataStorageCoordinator, @JacksonInject MaterializedViewTaskConfig config, @JacksonInject AuthorizerMapper authorizerMapper, @@ -143,7 +143,7 @@ public MaterializedViewSupervisorSpec( this.taskMaster = taskMaster; this.taskStorage = taskStorage; this.metadataSupervisorManager = metadataSupervisorManager; - this.segmentManager = segmentManager; + this.sqlSegmentsMetadataManager = sqlSegmentsMetadataManager; this.metadataStorageCoordinator = metadataStorageCoordinator; this.authorizerMapper = authorizerMapper; this.chatHandlerProvider = chatHandlerProvider; @@ -353,7 +353,7 @@ public Supervisor createSupervisor() taskMaster, taskStorage, metadataSupervisorManager, - segmentManager, + sqlSegmentsMetadataManager, metadataStorageCoordinator, config, this @@ -384,7 +384,7 @@ public SupervisorSpec createSuspendedSpec() taskMaster, taskStorage, metadataSupervisorManager, - segmentManager, + sqlSegmentsMetadataManager, metadataStorageCoordinator, config, authorizerMapper, @@ -411,7 +411,7 @@ public SupervisorSpec createRunningSpec() taskMaster, taskStorage, metadataSupervisorManager, - segmentManager, + sqlSegmentsMetadataManager, metadataStorageCoordinator, config, authorizerMapper, diff --git a/extensions-contrib/materialized-view-maintenance/src/test/java/org/apache/druid/indexing/materializedview/MaterializedViewSupervisorSpecTest.java b/extensions-contrib/materialized-view-maintenance/src/test/java/org/apache/druid/indexing/materializedview/MaterializedViewSupervisorSpecTest.java index e19cb784ac7c..c82b8b8fae6a 100644 --- a/extensions-contrib/materialized-view-maintenance/src/test/java/org/apache/druid/indexing/materializedview/MaterializedViewSupervisorSpecTest.java +++ b/extensions-contrib/materialized-view-maintenance/src/test/java/org/apache/druid/indexing/materializedview/MaterializedViewSupervisorSpecTest.java @@ -32,7 +32,7 @@ import org.apache.druid.indexing.overlord.supervisor.SupervisorStateManagerConfig; import org.apache.druid.math.expr.ExprMacroTable; import org.apache.druid.metadata.MetadataSupervisorManager; -import org.apache.druid.metadata.SQLMetadataSegmentManager; +import org.apache.druid.metadata.SqlSegmentsMetadataManager; import org.apache.druid.query.aggregation.AggregatorFactory; import org.apache.druid.query.aggregation.CountAggregatorFactory; import org.apache.druid.query.aggregation.LongSumAggregatorFactory; @@ -69,7 +69,7 @@ public void setup() .addValue(ExprMacroTable.class.getName(), LookupEnabledTestExprMacroTable.INSTANCE) .addValue(ObjectMapper.class, objectMapper) .addValue(MetadataSupervisorManager.class, null) - .addValue(SQLMetadataSegmentManager.class, null) + .addValue(SqlSegmentsMetadataManager.class, null) .addValue(IndexerMetadataStorageCoordinator.class, null) .addValue(MaterializedViewTaskConfig.class, new MaterializedViewTaskConfig()) .addValue(AuthorizerMapper.class, EasyMock.createMock(AuthorizerMapper.class)) diff --git a/extensions-contrib/materialized-view-maintenance/src/test/java/org/apache/druid/indexing/materializedview/MaterializedViewSupervisorTest.java b/extensions-contrib/materialized-view-maintenance/src/test/java/org/apache/druid/indexing/materializedview/MaterializedViewSupervisorTest.java index 3ae7129f5830..ec276795ddf7 100644 --- a/extensions-contrib/materialized-view-maintenance/src/test/java/org/apache/druid/indexing/materializedview/MaterializedViewSupervisorTest.java +++ b/extensions-contrib/materialized-view-maintenance/src/test/java/org/apache/druid/indexing/materializedview/MaterializedViewSupervisorTest.java @@ -41,7 +41,7 @@ import org.apache.druid.java.util.common.Pair; import org.apache.druid.metadata.IndexerSQLMetadataStorageCoordinator; import org.apache.druid.metadata.MetadataSupervisorManager; -import org.apache.druid.metadata.SQLMetadataSegmentManager; +import org.apache.druid.metadata.SqlSegmentsMetadataManager; import org.apache.druid.metadata.TestDerbyConnector; import org.apache.druid.query.aggregation.AggregatorFactory; import org.apache.druid.query.aggregation.LongSumAggregatorFactory; @@ -79,7 +79,7 @@ public class MaterializedViewSupervisorTest private TaskMaster taskMaster; private IndexerMetadataStorageCoordinator indexerMetadataStorageCoordinator; private MetadataSupervisorManager metadataSupervisorManager; - private SQLMetadataSegmentManager sqlMetadataSegmentManager; + private SqlSegmentsMetadataManager sqlSegmentsMetadataManager; private TaskQueue taskQueue; private MaterializedViewSupervisor supervisor; private String derivativeDatasourceName; @@ -99,7 +99,7 @@ public void setUp() derbyConnector ); metadataSupervisorManager = EasyMock.createMock(MetadataSupervisorManager.class); - sqlMetadataSegmentManager = EasyMock.createMock(SQLMetadataSegmentManager.class); + sqlSegmentsMetadataManager = EasyMock.createMock(SqlSegmentsMetadataManager.class); taskQueue = EasyMock.createMock(TaskQueue.class); taskQueue.start(); objectMapper.registerSubtypes(new NamedType(HashBasedNumberedShardSpec.class, "hashed")); @@ -118,7 +118,7 @@ public void setUp() taskMaster, taskStorage, metadataSupervisorManager, - sqlMetadataSegmentManager, + sqlSegmentsMetadataManager, indexerMetadataStorageCoordinator, new MaterializedViewTaskConfig(), EasyMock.createMock(AuthorizerMapper.class), @@ -335,7 +335,7 @@ public void testSuspendedDoesntRun() taskMaster, taskStorage, metadataSupervisorManager, - sqlMetadataSegmentManager, + sqlSegmentsMetadataManager, indexerMetadataStorageCoordinator, new MaterializedViewTaskConfig(), EasyMock.createMock(AuthorizerMapper.class), @@ -344,10 +344,10 @@ public void testSuspendedDoesntRun() ); MaterializedViewSupervisor supervisor = (MaterializedViewSupervisor) suspended.createSupervisor(); - // mock IndexerSQLMetadataStorageCoordinator to ensure that getDataSourceMetadata is not called + // mock IndexerSQLMetadataStorageCoordinator to ensure that retrieveDataSourceMetadata is not called // which will be true if truly suspended, since this is the first operation of the 'run' method otherwise IndexerSQLMetadataStorageCoordinator mock = EasyMock.createMock(IndexerSQLMetadataStorageCoordinator.class); - EasyMock.expect(mock.getDataSourceMetadata(suspended.getDataSourceName())) + EasyMock.expect(mock.retrieveDataSourceMetadata(suspended.getDataSourceName())) .andAnswer(() -> { Assert.fail(); return null; diff --git a/extensions-contrib/materialized-view-selection/src/main/java/org/apache/druid/query/materializedview/DataSourceOptimizer.java b/extensions-contrib/materialized-view-selection/src/main/java/org/apache/druid/query/materializedview/DataSourceOptimizer.java index 1653539f3e36..a3c03a6245c6 100644 --- a/extensions-contrib/materialized-view-selection/src/main/java/org/apache/druid/query/materializedview/DataSourceOptimizer.java +++ b/extensions-contrib/materialized-view-selection/src/main/java/org/apache/druid/query/materializedview/DataSourceOptimizer.java @@ -94,10 +94,9 @@ public List optimize(Query query) } lock.readLock().lock(); try { - totalCount.putIfAbsent(datasourceName, new AtomicLong(0)); + totalCount.computeIfAbsent(datasourceName, dsName -> new AtomicLong(0)).incrementAndGet(); hitCount.putIfAbsent(datasourceName, new AtomicLong(0)); - costTime.putIfAbsent(datasourceName, new AtomicLong(0)); - totalCount.get(datasourceName).incrementAndGet(); + AtomicLong costTimeOfDataSource = costTime.computeIfAbsent(datasourceName, dsName -> new AtomicLong(0)); // get all fields which the query required Set requiredFields = MaterializedViewUtils.getRequiredFields(query); @@ -111,10 +110,11 @@ public List optimize(Query query) } // if no derivatives contains all required dimensions, this materialized view selection failed. if (derivativesWithRequiredFields.isEmpty()) { - missFields.putIfAbsent(datasourceName, new ConcurrentHashMap<>()); - missFields.get(datasourceName).putIfAbsent(requiredFields, new AtomicLong(0)); - missFields.get(datasourceName).get(requiredFields).incrementAndGet(); - costTime.get(datasourceName).addAndGet(System.currentTimeMillis() - start); + missFields + .computeIfAbsent(datasourceName, dsName -> new ConcurrentHashMap<>()) + .computeIfAbsent(requiredFields, rf -> new AtomicLong(0)) + .incrementAndGet(); + costTimeOfDataSource.addAndGet(System.currentTimeMillis() - start); return Collections.singletonList(query); } diff --git a/extensions-contrib/materialized-view-selection/src/main/java/org/apache/druid/query/materializedview/DerivativeDataSourceManager.java b/extensions-contrib/materialized-view-selection/src/main/java/org/apache/druid/query/materializedview/DerivativeDataSourceManager.java index 199067bb84b1..3cff0da0075a 100644 --- a/extensions-contrib/materialized-view-selection/src/main/java/org/apache/druid/query/materializedview/DerivativeDataSourceManager.java +++ b/extensions-contrib/materialized-view-selection/src/main/java/org/apache/druid/query/materializedview/DerivativeDataSourceManager.java @@ -193,8 +193,7 @@ private void updateDerivatives() ConcurrentHashMap> newDerivatives = new ConcurrentHashMap<>(); for (DerivativeDataSource derivative : derivativeDataSources) { - newDerivatives.putIfAbsent(derivative.getBaseDataSource(), new TreeSet<>()); - newDerivatives.get(derivative.getBaseDataSource()).add(derivative); + newDerivatives.computeIfAbsent(derivative.getBaseDataSource(), ds -> new TreeSet<>()).add(derivative); } ConcurrentHashMap> current; do { diff --git a/extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/BasicSecurityAuthenticationException.java b/extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/BasicSecurityAuthenticationException.java index 16b8a782f2bf..41b0c99a10a4 100644 --- a/extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/BasicSecurityAuthenticationException.java +++ b/extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/BasicSecurityAuthenticationException.java @@ -26,6 +26,7 @@ */ public class BasicSecurityAuthenticationException extends IllegalArgumentException { + public BasicSecurityAuthenticationException(String formatText, Object... arguments) { super(StringUtils.nonStrictFormat(formatText, arguments)); diff --git a/extensions-core/kafka-indexing-service/src/test/java/org/apache/druid/indexing/kafka/KafkaIndexTaskTest.java b/extensions-core/kafka-indexing-service/src/test/java/org/apache/druid/indexing/kafka/KafkaIndexTaskTest.java index 43253b067e14..d4468bd39e03 100644 --- a/extensions-core/kafka-indexing-service/src/test/java/org/apache/druid/indexing/kafka/KafkaIndexTaskTest.java +++ b/extensions-core/kafka-indexing-service/src/test/java/org/apache/druid/indexing/kafka/KafkaIndexTaskTest.java @@ -364,7 +364,7 @@ public void testRunAfterDataInserted() throws Exception ); Assert.assertEquals( new KafkaDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 5L))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -411,7 +411,7 @@ public void testRunAfterDataInsertedWithLegacyParser() throws Exception ); Assert.assertEquals( new KafkaDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 5L))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -462,7 +462,7 @@ public void testRunBeforeDataInserted() throws Exception ); Assert.assertEquals( new KafkaDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 5L))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -608,7 +608,7 @@ public void testIncrementalHandOff() throws Exception new KafkaDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 10L, 1, 2L)) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -742,14 +742,14 @@ public void testIncrementalHandOffMaxTotalRows() throws Exception new KafkaDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 10L, 1, 2L)) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); Assert.assertEquals( new KafkaDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 10L, 1, 2L)) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -834,10 +834,15 @@ public void testTimeBasedIncrementalHandOff() throws Exception new KafkaDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 2L, 1, 0L)) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } + DataSourceMetadata newDataSchemaMetadata() + { + return metadataStorageCoordinator.retrieveDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()); + } + @Test(timeout = 60_000L) public void testIncrementalHandOffReadsThroughEndOffsets() throws Exception { @@ -988,7 +993,7 @@ public void testRunWithMinimumMessageTime() throws Exception ); Assert.assertEquals( new KafkaDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 5L))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -1040,7 +1045,7 @@ public void testRunWithMaximumMessageTime() throws Exception ); Assert.assertEquals( new KafkaDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 5L))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -1094,7 +1099,7 @@ public void testRunWithTransformSpec() throws Exception assertEqualsExceptVersion(ImmutableList.of(sdd("2009/P1D", 0)), publishedDescriptors); Assert.assertEquals( new KafkaDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 5L))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); // Check segments in deep storage @@ -1182,7 +1187,7 @@ public void testHandoffConditionTimeoutWhenHandoffOccurs() throws Exception ); Assert.assertEquals( new KafkaDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 5L))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -1233,7 +1238,7 @@ public void testHandoffConditionTimeoutWhenHandoffDoesNotOccur() throws Exceptio new KafkaDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 5L)) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -1277,7 +1282,7 @@ public void testReportParseExceptions() throws Exception // Check published metadata Assert.assertEquals(ImmutableList.of(), publishedDescriptors()); - Assert.assertNull(metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource())); + Assert.assertNull(newDataSchemaMetadata()); } @Test(timeout = 60_000L) @@ -1327,7 +1332,7 @@ public void testMultipleParseExceptionsSuccess() throws Exception ); Assert.assertEquals( new KafkaDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 13L))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); IngestionStatsAndErrorsTaskReportData reportData = getTaskReportData(); @@ -1400,7 +1405,7 @@ public void testMultipleParseExceptionsFailure() throws Exception // Check published metadata Assert.assertEquals(ImmutableList.of(), publishedDescriptors()); - Assert.assertNull(metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource())); + Assert.assertNull(newDataSchemaMetadata()); IngestionStatsAndErrorsTaskReportData reportData = getTaskReportData(); @@ -1488,7 +1493,7 @@ public void testRunReplicas() throws Exception ); Assert.assertEquals( new KafkaDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 5L))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -1556,7 +1561,7 @@ public void testRunConflicting() throws Exception ); Assert.assertEquals( new KafkaDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 5L))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -1605,7 +1610,7 @@ public void testRunConflictingWithoutTransactions() throws Exception SegmentDescriptorAndExpectedDim1Values desc1 = sdd("2010/P1D", 0, ImmutableList.of("c")); SegmentDescriptorAndExpectedDim1Values desc2 = sdd("2011/P1D", 0, ImmutableList.of("d", "e")); assertEqualsExceptVersion(ImmutableList.of(desc1, desc2), publishedDescriptors()); - Assert.assertNull(metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource())); + Assert.assertNull(newDataSchemaMetadata()); // Run second task final ListenableFuture future2 = runTask(task2); @@ -1623,7 +1628,7 @@ public void testRunConflictingWithoutTransactions() throws Exception SegmentDescriptorAndExpectedDim1Values desc3 = sdd("2011/P1D", 1, ImmutableList.of("d", "e")); SegmentDescriptorAndExpectedDim1Values desc4 = sdd("2013/P1D", 0, ImmutableList.of("f")); assertEqualsExceptVersion(ImmutableList.of(desc1, desc2, desc3, desc4), publishedDescriptors()); - Assert.assertNull(metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource())); + Assert.assertNull(newDataSchemaMetadata()); } @Test(timeout = 60_000L) @@ -1670,7 +1675,7 @@ public void testRunOneTaskTwoPartitions() throws Exception new KafkaDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 5L, 1, 2L)) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -1739,7 +1744,7 @@ public void testRunTwoTasksTwoPartitions() throws Exception new KafkaDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 5L, 1, 1L)) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -1837,7 +1842,7 @@ public void testRestore() throws Exception ); Assert.assertEquals( new KafkaDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 6L))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -1953,7 +1958,7 @@ public void testRestoreAfterPersistingSequences() throws Exception ); Assert.assertEquals( new KafkaDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 10L))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -2043,7 +2048,7 @@ public void testRunWithPauseAndResume() throws Exception ); Assert.assertEquals( new KafkaDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 6L))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -2169,7 +2174,7 @@ public void testRunContextSequenceAheadOfStartingOffsets() throws Exception ); Assert.assertEquals( new KafkaDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 5L))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -2314,7 +2319,7 @@ public void testRunTransactionModeRollback() throws Exception ); Assert.assertEquals( new KafkaDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(0, 13L))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } diff --git a/extensions-core/kafka-indexing-service/src/test/java/org/apache/druid/indexing/kafka/supervisor/KafkaSupervisorTest.java b/extensions-core/kafka-indexing-service/src/test/java/org/apache/druid/indexing/kafka/supervisor/KafkaSupervisorTest.java index a50356f3e54b..0b29b65a628b 100644 --- a/extensions-core/kafka-indexing-service/src/test/java/org/apache/druid/indexing/kafka/supervisor/KafkaSupervisorTest.java +++ b/extensions-core/kafka-indexing-service/src/test/java/org/apache/druid/indexing/kafka/supervisor/KafkaSupervisorTest.java @@ -300,7 +300,7 @@ public void testNoInitialState() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.of(taskRunner)).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -355,7 +355,7 @@ public void testSkipOffsetGaps() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.of(taskRunner)).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -379,7 +379,7 @@ public void testMultiTask() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.absent()).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -434,7 +434,7 @@ public void testReplicas() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.absent()).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -489,7 +489,7 @@ public void testLateMessageRejectionPeriod() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.absent()).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -528,7 +528,7 @@ public void testEarlyMessageRejectionPeriod() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.absent()).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -570,7 +570,7 @@ public void testLatestOffset() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.absent()).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -610,7 +610,7 @@ public void testPartitionIdsUpdates() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.absent()).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -636,7 +636,7 @@ public void testAlwaysUsesEarliestOffsetForNewlyDiscoveredPartitions() throws Ex EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.absent()).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -708,7 +708,7 @@ public void testDatasourceMetadata() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.absent()).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( new SeekableStreamStartSequenceNumbers<>(topic, ImmutableMap.of(0, 10L, 1, 20L, 2, 30L), ImmutableSet.of()) ) @@ -747,7 +747,7 @@ public void testBadMetadataOffsets() throws Exception EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); // for simplicity in testing the offset availability check, we use negative stored offsets in metadata here, // because the stream's earliest offset is 0, although that would not happen in real usage. - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( new SeekableStreamStartSequenceNumbers<>( topic, @@ -797,7 +797,7 @@ public void testDontKillTasksWithMismatchedType() throws Exception EasyMock.expect(taskClient.getStartTimeAsync(EasyMock.anyString())) .andReturn(Futures.immediateFuture(DateTimes.nowUtc())) .anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -897,7 +897,7 @@ public void testKillBadPartitionAssignment() throws Exception EasyMock.expect(taskClient.getStartTimeAsync(EasyMock.anyString())) .andReturn(Futures.immediateFuture(DateTimes.nowUtc())) .anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -945,7 +945,7 @@ public void testRequeueTaskWhenFailed() throws Exception EasyMock.expect(taskClient.getStartTimeAsync(EasyMock.anyString())) .andReturn(Futures.immediateFuture(DateTimes.nowUtc())) .anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -1048,7 +1048,7 @@ public void testRequeueAdoptedTaskWhenFailed() throws Exception EasyMock.expect(taskClient.getStatusAsync("id1")).andReturn(Futures.immediateFuture(Status.READING)); EasyMock.expect(taskClient.getStartTimeAsync("id1")).andReturn(Futures.immediateFuture(now)).anyTimes(); EasyMock.expect(taskQueue.add(EasyMock.capture(captured))).andReturn(true); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -1138,7 +1138,7 @@ public void testQueueNextTasksOnSuccess() throws Exception EasyMock.expect(taskClient.getStartTimeAsync(EasyMock.anyString())) .andReturn(Futures.immediateFuture(DateTimes.nowUtc())) .anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -1235,7 +1235,7 @@ public void testBeginPublishAndQueueNextTasks() throws Exception EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.of(taskRunner)).anyTimes(); EasyMock.expect(taskRunner.getRunningTasks()).andReturn(Collections.EMPTY_LIST).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -1349,7 +1349,7 @@ public void testDiscoverExistingPublishingTask() throws Exception EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of(task)).anyTimes(); EasyMock.expect(taskStorage.getStatus("id1")).andReturn(Optional.of(TaskStatus.running("id1"))).anyTimes(); EasyMock.expect(taskStorage.getTask("id1")).andReturn(Optional.of(task)).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -1465,7 +1465,7 @@ public void testDiscoverExistingPublishingTaskWithDifferentPartitionAllocation() EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of(task)).anyTimes(); EasyMock.expect(taskStorage.getStatus("id1")).andReturn(Optional.of(TaskStatus.running("id1"))).anyTimes(); EasyMock.expect(taskStorage.getTask("id1")).andReturn(Optional.of(task)).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -1598,7 +1598,7 @@ public void testDiscoverExistingPublishingAndReadingTask() throws Exception EasyMock.expect(taskStorage.getStatus("id2")).andReturn(Optional.of(TaskStatus.running("id2"))).anyTimes(); EasyMock.expect(taskStorage.getTask("id1")).andReturn(Optional.of(id1)).anyTimes(); EasyMock.expect(taskStorage.getTask("id2")).andReturn(Optional.of(id2)).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -1672,9 +1672,9 @@ public void testKillUnresponsiveTasksWhileGettingStartTime() throws Exception Capture captured = Capture.newInstance(CaptureType.ALL); EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.of(taskRunner)).anyTimes(); - EasyMock.expect(taskRunner.getRunningTasks()).andReturn(Collections.EMPTY_LIST).anyTimes(); + EasyMock.expect(taskRunner.getRunningTasks()).andReturn(Collections.emptyList()).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -1733,7 +1733,7 @@ public void testKillUnresponsiveTasksWhilePausing() throws Exception EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.of(taskRunner)).anyTimes(); EasyMock.expect(taskRunner.getRunningTasks()).andReturn(Collections.EMPTY_LIST).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -1819,7 +1819,7 @@ public void testKillUnresponsiveTasksWhileSettingEndOffsets() throws Exception EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.of(taskRunner)).anyTimes(); EasyMock.expect(taskRunner.getRunningTasks()).andReturn(Collections.EMPTY_LIST).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -1990,7 +1990,7 @@ public void testStopGracefully() throws Exception EasyMock.expect(taskStorage.getTask("id1")).andReturn(Optional.of(id1)).anyTimes(); EasyMock.expect(taskStorage.getTask("id2")).andReturn(Optional.of(id2)).anyTimes(); EasyMock.expect(taskStorage.getTask("id3")).andReturn(Optional.of(id3)).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -2094,7 +2094,7 @@ public void testResetDataSourceMetadata() throws Exception new SeekableStreamStartSequenceNumbers<>(topic, ImmutableMap.of(0, 1000L), ImmutableSet.of())); EasyMock.reset(indexerMetadataStorageCoordinator); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)) + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)) .andReturn(kafkaDataSourceMetadata); EasyMock.expect(indexerMetadataStorageCoordinator.resetDataSourceMetadata( EasyMock.capture(captureDataSource), @@ -2141,7 +2141,7 @@ public void testResetNoDataSourceMetadata() EasyMock.reset(indexerMetadataStorageCoordinator); // no DataSourceMetadata in metadata store - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn(null); + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn(null); EasyMock.replay(indexerMetadataStorageCoordinator); supervisor.resetInternal(resetMetadata); @@ -2163,7 +2163,7 @@ public void testGetOffsetFromStorageForPartitionWithResetOffsetAutomatically() t // unknown DataSourceMetadata in metadata store // for simplicity in testing the offset availability check, we use negative stored offsets in metadata here, // because the stream's earliest offset is 0, although that would not happen in real usage. - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)) + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)) .andReturn( new KafkaDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(topic, ImmutableMap.of(1, -100L, 2, 200L)) @@ -2257,7 +2257,7 @@ public void testResetRunningTasks() throws Exception EasyMock.expect(taskStorage.getTask("id1")).andReturn(Optional.of(id1)).anyTimes(); EasyMock.expect(taskStorage.getTask("id2")).andReturn(Optional.of(id2)).anyTimes(); EasyMock.expect(taskStorage.getTask("id3")).andReturn(Optional.of(id3)).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -2357,7 +2357,7 @@ public void testNoDataIngestionTasks() EasyMock.expect(taskStorage.getTask("id1")).andReturn(Optional.of(id1)).anyTimes(); EasyMock.expect(taskStorage.getTask("id2")).andReturn(Optional.of(id2)).anyTimes(); EasyMock.expect(taskStorage.getTask("id3")).andReturn(Optional.of(id3)).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -2470,7 +2470,7 @@ public void testCheckpointForInactiveTaskGroup() EasyMock.expect(taskStorage.getTask("id2")).andReturn(Optional.of(id2)).anyTimes(); EasyMock.expect(taskStorage.getTask("id3")).andReturn(Optional.of(id3)).anyTimes(); EasyMock.expect( - indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn(new KafkaDataSourceMetadata(null) + indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn(new KafkaDataSourceMetadata(null) ).anyTimes(); EasyMock.expect(taskClient.getStatusAsync("id1")).andReturn(Futures.immediateFuture(Status.READING)); EasyMock.expect(taskClient.getStatusAsync("id2")).andReturn(Futures.immediateFuture(Status.READING)); @@ -2579,7 +2579,7 @@ public void testCheckpointForUnknownTaskGroup() EasyMock.expect(taskStorage.getTask("id2")).andReturn(Optional.of(id2)).anyTimes(); EasyMock.expect(taskStorage.getTask("id3")).andReturn(Optional.of(id3)).anyTimes(); EasyMock.expect( - indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn(new KafkaDataSourceMetadata(null) + indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn(new KafkaDataSourceMetadata(null) ).anyTimes(); replayAll(); @@ -2622,7 +2622,7 @@ public void testSuspendedNoRunningTasks() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.of(taskRunner)).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -2711,7 +2711,7 @@ public void testSuspendedRunningTasks() throws Exception EasyMock.expect(taskStorage.getTask("id1")).andReturn(Optional.of(id1)).anyTimes(); EasyMock.expect(taskStorage.getTask("id2")).andReturn(Optional.of(id2)).anyTimes(); EasyMock.expect(taskStorage.getTask("id3")).andReturn(Optional.of(id3)).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -2796,7 +2796,7 @@ public void testFailedInitializationAndRecovery() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.of(taskRunner)).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -2822,7 +2822,7 @@ public void testFailedInitializationAndRecovery() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.of(taskRunner)).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -2979,7 +2979,7 @@ public void testDoNotKillCompatibleTasks() EasyMock.expect(taskClient.getStartTimeAsync(EasyMock.anyString())) .andReturn(Futures.immediateFuture(DateTimes.nowUtc())) .anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) @@ -3048,7 +3048,7 @@ public void testKillIncompatibleTasks() EasyMock.expect(taskClient.getStartTimeAsync(EasyMock.anyString())) .andReturn(Futures.immediateFuture(DateTimes.nowUtc())) .anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KafkaDataSourceMetadata( null ) diff --git a/extensions-core/kinesis-indexing-service/src/test/java/org/apache/druid/indexing/kinesis/KinesisIndexTaskTest.java b/extensions-core/kinesis-indexing-service/src/test/java/org/apache/druid/indexing/kinesis/KinesisIndexTaskTest.java index aef7accc7099..7867522a54eb 100644 --- a/extensions-core/kinesis-indexing-service/src/test/java/org/apache/druid/indexing/kinesis/KinesisIndexTaskTest.java +++ b/extensions-core/kinesis-indexing-service/src/test/java/org/apache/druid/indexing/kinesis/KinesisIndexTaskTest.java @@ -373,7 +373,7 @@ public void testRunAfterDataInserted() throws Exception new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "4")) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -440,10 +440,15 @@ public void testRunAfterDataInsertedWithLegacyParser() throws Exception new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "4")) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } + DataSourceMetadata newDataSchemaMetadata() + { + return metadataStorageCoordinator.retrieveDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()); + } + @Test(timeout = 120_000L) public void testRunBeforeDataInserted() throws Exception { @@ -510,7 +515,7 @@ public void testRunBeforeDataInserted() throws Exception new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID0, "1")) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -622,7 +627,7 @@ public void testIncrementalHandOff() throws Exception ImmutableMap.of(SHARD_ID1, "9", SHARD_ID0, "1") ) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -757,7 +762,7 @@ public void testIncrementalHandOffMaxTotalRows() throws Exception ); Assert.assertEquals( new KinesisDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "10"))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -827,7 +832,7 @@ public void testRunWithMinimumMessageTime() throws Exception ); Assert.assertEquals( new KinesisDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "4"))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -899,7 +904,7 @@ public void testRunWithMaximumMessageTime() throws Exception Assert.assertEquals( new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "4"))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -972,7 +977,7 @@ public void testRunWithTransformSpec() throws Exception Assert.assertEquals( new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "4"))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); // Check segments in deep storage @@ -1103,7 +1108,7 @@ public void testHandoffConditionTimeoutWhenHandoffOccurs() throws Exception new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "4")) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -1173,7 +1178,7 @@ public void testHandoffConditionTimeoutWhenHandoffDoesNotOccur() throws Exceptio new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "4")) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -1236,7 +1241,7 @@ public void testReportParseExceptions() throws Exception // Check published metadata Assert.assertEquals(ImmutableList.of(), publishedDescriptors()); - Assert.assertNull(metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource())); + Assert.assertNull(newDataSchemaMetadata()); } @@ -1307,7 +1312,7 @@ public void testMultipleParseExceptionsSuccess() throws Exception new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "12")) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); IngestionStatsAndErrorsTaskReportData reportData = getTaskReportData(); @@ -1399,7 +1404,7 @@ public void testMultipleParseExceptionsFailure() throws Exception // Check published metadata Assert.assertEquals(ImmutableList.of(), publishedDescriptors()); - Assert.assertNull(metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource())); + Assert.assertNull(newDataSchemaMetadata()); IngestionStatsAndErrorsTaskReportData reportData = getTaskReportData(); @@ -1513,7 +1518,7 @@ public void testRunReplicas() throws Exception new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "4")) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -1605,7 +1610,7 @@ public void testRunConflicting() throws Exception ); Assert.assertEquals( new KinesisDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "4"))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -1678,7 +1683,7 @@ public void testRunConflictingWithoutTransactions() throws Exception SegmentDescriptorAndExpectedDim1Values desc1 = sdd("2010/P1D", 0, ImmutableList.of("c")); SegmentDescriptorAndExpectedDim1Values desc2 = sdd("2011/P1D", 0, ImmutableList.of("d", "e")); assertEqualsExceptVersion(ImmutableList.of(desc1, desc2), publishedDescriptors()); - Assert.assertNull(metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource())); + Assert.assertNull(newDataSchemaMetadata()); // Run second task final ListenableFuture future2 = runTask(task2); @@ -1698,7 +1703,7 @@ public void testRunConflictingWithoutTransactions() throws Exception SegmentDescriptorAndExpectedDim1Values desc3 = sdd("2011/P1D", 1, ImmutableList.of("d", "e")); SegmentDescriptorAndExpectedDim1Values desc4 = sdd("2013/P1D", 0, ImmutableList.of("f")); assertEqualsExceptVersion(ImmutableList.of(desc1, desc2, desc3, desc4), publishedDescriptors()); - Assert.assertNull(metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource())); + Assert.assertNull(newDataSchemaMetadata()); } @@ -1774,7 +1779,7 @@ public void testRunOneTaskTwoPartitions() throws Exception new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "4", SHARD_ID0, "1")) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -1870,7 +1875,7 @@ public void testRunTwoTasksTwoPartitions() throws Exception new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "4", SHARD_ID0, "1")) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -1995,7 +2000,7 @@ public void testRestore() throws Exception Assert.assertEquals( new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "5"))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -2144,7 +2149,7 @@ public void testRestoreAfterPersistingSequences() throws Exception new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "6")) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -2248,7 +2253,7 @@ public void testRunWithPauseAndResume() throws Exception STREAM, ImmutableMap.of(SHARD_ID1, currentOffsets.get(SHARD_ID1)) )), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -2327,7 +2332,7 @@ public void testRunContextSequenceAheadOfStartingOffsets() throws Exception ); Assert.assertEquals( new KinesisDataSourceMetadata(new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "4"))), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -2484,7 +2489,7 @@ public void testIncrementalHandOffReadsThroughEndOffsets() throws Exception new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "9")) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } @@ -2640,7 +2645,7 @@ public void testEndOfShard() throws Exception ImmutableMap.of(SHARD_ID1, KinesisSequenceNumber.END_OF_SHARD_MARKER) ) ), - metadataStorageCoordinator.getDataSourceMetadata(NEW_DATA_SCHEMA.getDataSource()) + newDataSchemaMetadata() ); } diff --git a/extensions-core/kinesis-indexing-service/src/test/java/org/apache/druid/indexing/kinesis/supervisor/KinesisSupervisorTest.java b/extensions-core/kinesis-indexing-service/src/test/java/org/apache/druid/indexing/kinesis/supervisor/KinesisSupervisorTest.java index 5ce8f3659daf..ad267e8a1eaa 100644 --- a/extensions-core/kinesis-indexing-service/src/test/java/org/apache/druid/indexing/kinesis/supervisor/KinesisSupervisorTest.java +++ b/extensions-core/kinesis-indexing-service/src/test/java/org/apache/druid/indexing/kinesis/supervisor/KinesisSupervisorTest.java @@ -235,7 +235,7 @@ public void testNoInitialState() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.of(taskRunner)).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -302,9 +302,10 @@ public void testMultiTask() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.absent()).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( - new KinesisDataSourceMetadata(null) - ).anyTimes(); + EasyMock + .expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)) + .andReturn(new KinesisDataSourceMetadata(null)) + .anyTimes(); EasyMock.expect(taskQueue.add(EasyMock.capture(captured))).andReturn(true).times(2); replayAll(); @@ -360,7 +361,7 @@ public void testReplicas() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.absent()).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -437,7 +438,7 @@ public void testLateMessageRejectionPeriod() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.absent()).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -489,7 +490,7 @@ public void testEarlyMessageRejectionPeriod() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.absent()).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -548,7 +549,7 @@ public void testDatasourceMetadata() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.absent()).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( new SeekableStreamStartSequenceNumbers<>( STREAM, @@ -601,7 +602,7 @@ public void testBadMetadataOffsets() throws Exception EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.absent()).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( new SeekableStreamStartSequenceNumbers<>( STREAM, @@ -665,7 +666,7 @@ public void testDontKillTasksWithMismatchedType() throws Exception EasyMock.expect(taskClient.getStartTimeAsync(EasyMock.anyString())) .andReturn(Futures.immediateFuture(DateTimes.nowUtc())) .anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -767,7 +768,7 @@ public void testKillBadPartitionAssignment() throws Exception EasyMock.expect(taskClient.getStartTimeAsync(EasyMock.anyString())) .andReturn(Futures.immediateFuture(DateTimes.nowUtc())) .anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -831,7 +832,7 @@ public void testRequeueTaskWhenFailed() throws Exception EasyMock.expect(taskClient.getStartTimeAsync(EasyMock.anyString())) .andReturn(Futures.immediateFuture(DateTimes.nowUtc())) .anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -968,7 +969,7 @@ public void testRequeueAdoptedTaskWhenFailed() throws Exception .andReturn(Futures.immediateFuture(SeekableStreamIndexTaskRunner.Status.READING)); EasyMock.expect(taskClient.getStartTimeAsync("id1")).andReturn(Futures.immediateFuture(now)).anyTimes(); EasyMock.expect(taskQueue.add(EasyMock.capture(captured))).andReturn(true); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -1079,7 +1080,7 @@ public void testQueueNextTasksOnSuccess() throws Exception EasyMock.expect(taskClient.getStartTimeAsync(EasyMock.anyString())) .andReturn(Futures.immediateFuture(DateTimes.nowUtc())) .anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -1199,7 +1200,7 @@ public void testBeginPublishAndQueueNextTasks() throws Exception EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.of(taskRunner)).anyTimes(); EasyMock.expect(taskRunner.getRunningTasks()).andReturn(Collections.EMPTY_LIST).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata(null) ).anyTimes(); EasyMock.expect(taskQueue.add(EasyMock.capture(firstTasks))).andReturn(true).times(4); @@ -1355,7 +1356,7 @@ public void testDiscoverExistingPublishingTask() throws Exception EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of(task)).anyTimes(); EasyMock.expect(taskStorage.getStatus("id1")).andReturn(Optional.of(TaskStatus.running("id1"))).anyTimes(); EasyMock.expect(taskStorage.getTask("id1")).andReturn(Optional.of(task)).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -1512,7 +1513,7 @@ public void testDiscoverExistingPublishingTaskWithDifferentPartitionAllocation() EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of(task)).anyTimes(); EasyMock.expect(taskStorage.getStatus("id1")).andReturn(Optional.of(TaskStatus.running("id1"))).anyTimes(); EasyMock.expect(taskStorage.getTask("id1")).andReturn(Optional.of(task)).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -1683,7 +1684,7 @@ public void testDiscoverExistingPublishingAndReadingTask() throws Exception EasyMock.expect(taskStorage.getStatus("id2")).andReturn(Optional.of(TaskStatus.running("id2"))).anyTimes(); EasyMock.expect(taskStorage.getTask("id1")).andReturn(Optional.of(id1)).anyTimes(); EasyMock.expect(taskStorage.getTask("id2")).andReturn(Optional.of(id2)).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -1808,7 +1809,7 @@ public void testKillUnresponsiveTasksWhileGettingStartTime() throws Exception EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.of(taskRunner)).anyTimes(); EasyMock.expect(taskRunner.getRunningTasks()).andReturn(Collections.EMPTY_LIST).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -1890,7 +1891,7 @@ public void testKillUnresponsiveTasksWhilePausing() throws Exception EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.of(taskRunner)).anyTimes(); EasyMock.expect(taskRunner.getRunningTasks()).andReturn(Collections.EMPTY_LIST).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -1998,7 +1999,7 @@ public void testKillUnresponsiveTasksWhileSettingEndOffsets() throws Exception EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.of(taskRunner)).anyTimes(); EasyMock.expect(taskRunner.getRunningTasks()).andReturn(Collections.EMPTY_LIST).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -2226,7 +2227,7 @@ public void testStopGracefully() throws Exception EasyMock.expect(taskStorage.getTask("id1")).andReturn(Optional.of(id1)).anyTimes(); EasyMock.expect(taskStorage.getTask("id2")).andReturn(Optional.of(id2)).anyTimes(); EasyMock.expect(taskStorage.getTask("id3")).andReturn(Optional.of(id3)).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -2382,7 +2383,7 @@ public void testResetDataSourceMetadata() throws Exception ); EasyMock.reset(indexerMetadataStorageCoordinator); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)) + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)) .andReturn(kinesisDataSourceMetadata); EasyMock.expect(indexerMetadataStorageCoordinator.resetDataSourceMetadata( EasyMock.capture(captureDataSource), @@ -2432,7 +2433,7 @@ public void testResetNoDataSourceMetadata() EasyMock.reset(indexerMetadataStorageCoordinator); // no DataSourceMetadata in metadata store - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn(null); + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn(null); EasyMock.replay(indexerMetadataStorageCoordinator); supervisor.resetInternal(resetMetadata); @@ -2467,46 +2468,56 @@ public void testGetOffsetFromStorageForPartitionWithResetOffsetAutomatically() t EasyMock.reset(indexerMetadataStorageCoordinator); // unknown DataSourceMetadata in metadata store - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)) - .andReturn( - new KinesisDataSourceMetadata( - new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "100", SHARD_ID2, "200")) - ) - ).times(2); + EasyMock + .expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)) + .andReturn( + new KinesisDataSourceMetadata( + new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "100", SHARD_ID2, "200")) + ) + ) + .times(2); // Since shard 2 was in metadata before but is not in the list of shards returned by the record supplier, // it gets deleted from metadata (it is an expired shard) - EasyMock.expect( - indexerMetadataStorageCoordinator.resetDataSourceMetadata( - DATASOURCE, - new KinesisDataSourceMetadata( - new SeekableStreamEndSequenceNumbers<>( - STREAM, - ImmutableMap.of(SHARD_ID1, "100", SHARD_ID2, KinesisSequenceNumber.EXPIRED_MARKER) + EasyMock + .expect( + indexerMetadataStorageCoordinator.resetDataSourceMetadata( + DATASOURCE, + new KinesisDataSourceMetadata( + new SeekableStreamEndSequenceNumbers<>( + STREAM, + ImmutableMap.of(SHARD_ID1, "100", SHARD_ID2, KinesisSequenceNumber.EXPIRED_MARKER) + ) ) ) ) - ).andReturn(true).times(1); + .andReturn(true) + .times(1); // getOffsetFromStorageForPartition() throws an exception when the offsets are automatically reset. // Since getOffsetFromStorageForPartition() is called per partition, all partitions can't be reset at the same time. // Instead, subsequent partitions will be reset in the following supervisor runs. - EasyMock.expect( - indexerMetadataStorageCoordinator.resetDataSourceMetadata( - DATASOURCE, - new KinesisDataSourceMetadata( - // Only one partition is reset in a single supervisor run. - new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of()) + EasyMock + .expect( + indexerMetadataStorageCoordinator.resetDataSourceMetadata( + DATASOURCE, + new KinesisDataSourceMetadata( + // Only one partition is reset in a single supervisor run. + new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of()) + ) ) ) - ).andReturn(true).times(1); + .andReturn(true) + .times(1); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)) - .andReturn( - new KinesisDataSourceMetadata( - new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "100")) - ) - ).times(2); + EasyMock + .expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)) + .andReturn( + new KinesisDataSourceMetadata( + new SeekableStreamEndSequenceNumbers<>(STREAM, ImmutableMap.of(SHARD_ID1, "100")) + ) + ) + .times(2); replayAll(); @@ -2619,7 +2630,7 @@ public void testResetRunningTasks() throws Exception EasyMock.expect(taskStorage.getTask("id1")).andReturn(Optional.of(id1)).anyTimes(); EasyMock.expect(taskStorage.getTask("id2")).andReturn(Optional.of(id2)).anyTimes(); EasyMock.expect(taskStorage.getTask("id3")).andReturn(Optional.of(id3)).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -2773,7 +2784,7 @@ public void testNoDataIngestionTasks() throws Exception EasyMock.expect(taskStorage.getTask("id1")).andReturn(Optional.of(id1)).anyTimes(); EasyMock.expect(taskStorage.getTask("id2")).andReturn(Optional.of(id2)).anyTimes(); EasyMock.expect(taskStorage.getTask("id3")).andReturn(Optional.of(id3)).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -2930,7 +2941,7 @@ public void testCheckpointForInactiveTaskGroup() throws InterruptedException EasyMock.expect(taskStorage.getTask("id2")).andReturn(Optional.of(id2)).anyTimes(); EasyMock.expect(taskStorage.getTask("id3")).andReturn(Optional.of(id3)).anyTimes(); EasyMock.expect( - indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn(new KinesisDataSourceMetadata( + indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn(new KinesisDataSourceMetadata( null) ).anyTimes(); EasyMock.expect(taskClient.getStatusAsync("id1")) @@ -3082,7 +3093,7 @@ public void testCheckpointForUnknownTaskGroup() EasyMock.expect(taskStorage.getTask("id2")).andReturn(Optional.of(id2)).anyTimes(); EasyMock.expect(taskStorage.getTask("id3")).andReturn(Optional.of(id3)).anyTimes(); EasyMock.expect( - indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn(new KinesisDataSourceMetadata( + indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn(new KinesisDataSourceMetadata( null) ).anyTimes(); @@ -3127,7 +3138,7 @@ public void testSuspendedNoRunningTasks() throws Exception EasyMock.expect(taskMaster.getTaskQueue()).andReturn(Optional.of(taskQueue)).anyTimes(); EasyMock.expect(taskMaster.getTaskRunner()).andReturn(Optional.of(taskRunner)).anyTimes(); EasyMock.expect(taskStorage.getActiveTasksByDatasource(DATASOURCE)).andReturn(ImmutableList.of()).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -3253,7 +3264,7 @@ public void testSuspendedRunningTasks() throws Exception EasyMock.expect(taskStorage.getTask("id1")).andReturn(Optional.of(id1)).anyTimes(); EasyMock.expect(taskStorage.getTask("id2")).andReturn(Optional.of(id2)).anyTimes(); EasyMock.expect(taskStorage.getTask("id3")).andReturn(Optional.of(id3)).anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -3459,7 +3470,7 @@ public void testDoNotKillCompatibleTasks() throws InterruptedException, EntryExi EasyMock.expect(taskClient.getStartTimeAsync(EasyMock.anyString())) .andReturn(Futures.immediateFuture(DateTimes.nowUtc())) .anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -3555,7 +3566,7 @@ public void testKillIncompatibleTasks() throws InterruptedException, EntryExists EasyMock.expect(taskClient.getStartTimeAsync(EasyMock.anyString())) .andReturn(Futures.immediateFuture(DateTimes.nowUtc())) .anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -3769,7 +3780,7 @@ private List testShardSplitPhaseOne() throws Exception EasyMock.expect(taskClient.getStartTimeAsync(EasyMock.anyString())) .andReturn(Futures.immediateFuture(DateTimes.nowUtc())) .anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -3837,7 +3848,7 @@ private List testShardSplitPhaseTwo(List phaseOneTasks) throws Excep EasyMock.reset(supervisorRecordSupplier); // first task ran, its shard 0 has reached EOS - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers( STREAM, @@ -3994,7 +4005,7 @@ private void testShardSplitPhaseThree(List phaseTwoTasks) throws Exception EasyMock.reset(supervisorRecordSupplier); // second set of tasks ran, shard 0 has expired, but shard 1 and 2 have data - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers( STREAM, @@ -4215,7 +4226,7 @@ private List testShardMergePhaseOne() throws Exception EasyMock.expect(taskClient.getStartTimeAsync(EasyMock.anyString())) .andReturn(Futures.immediateFuture(DateTimes.nowUtc())) .anyTimes(); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( null ) @@ -4291,7 +4302,7 @@ private List testShardMergePhaseTwo(List phaseOneTasks) throws Excep EasyMock.reset(supervisorRecordSupplier); // first tasks ran, both shard 0 and shard 1 have reached EOS, merged into shard 2 - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers( STREAM, @@ -4432,7 +4443,7 @@ private void testShardMergePhaseThree(List phaseTwoTasks) throws Exception EasyMock.reset(supervisorRecordSupplier); // second set of tasks ran, shard 0 has expired, but shard 1 and 2 have data - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn( + EasyMock.expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn( new KinesisDataSourceMetadata( new SeekableStreamEndSequenceNumbers( STREAM, diff --git a/extensions-core/s3-extensions/src/test/java/org/apache/druid/storage/s3/S3DataSegmentMoverTest.java b/extensions-core/s3-extensions/src/test/java/org/apache/druid/storage/s3/S3DataSegmentMoverTest.java index 66a61db70158..e3695ab1cdfc 100644 --- a/extensions-core/s3-extensions/src/test/java/org/apache/druid/storage/s3/S3DataSegmentMoverTest.java +++ b/extensions-core/s3-extensions/src/test/java/org/apache/druid/storage/s3/S3DataSegmentMoverTest.java @@ -85,7 +85,10 @@ public void testMove() throws Exception ); Map targetLoadSpec = movedSegment.getLoadSpec(); - Assert.assertEquals("targetBaseKey/test/2013-01-01T00:00:00.000Z_2013-01-02T00:00:00.000Z/1/0/index.zip", MapUtils.getString(targetLoadSpec, "key")); + Assert.assertEquals( + "targetBaseKey/test/2013-01-01T00:00:00.000Z_2013-01-02T00:00:00.000Z/1/0/index.zip", + MapUtils.getString(targetLoadSpec, "key") + ); Assert.assertEquals("archive", MapUtils.getString(targetLoadSpec, "bucket")); Assert.assertTrue(mockS3Client.didMove()); } @@ -108,7 +111,10 @@ public void testMoveNoop() throws Exception Map targetLoadSpec = movedSegment.getLoadSpec(); - Assert.assertEquals("targetBaseKey/test/2013-01-01T00:00:00.000Z_2013-01-02T00:00:00.000Z/1/0/index.zip", MapUtils.getString(targetLoadSpec, "key")); + Assert.assertEquals( + "targetBaseKey/test/2013-01-01T00:00:00.000Z_2013-01-02T00:00:00.000Z/1/0/index.zip", + MapUtils.getString(targetLoadSpec, "key") + ); Assert.assertEquals("archive", MapUtils.getString(targetLoadSpec, "bucket")); Assert.assertFalse(mockS3Client.didMove()); } @@ -261,8 +267,7 @@ public PutObjectResult putObject(String bucketName, String key) @Override public PutObjectResult putObject(String bucketName, String key, File file) { - storage.putIfAbsent(bucketName, new HashSet<>()); - storage.get(bucketName).add(key); + storage.computeIfAbsent(bucketName, bName -> new HashSet<>()).add(key); return new PutObjectResult(); } } diff --git a/indexing-hadoop/src/main/java/org/apache/druid/indexer/HadoopIngestionSpec.java b/indexing-hadoop/src/main/java/org/apache/druid/indexer/HadoopIngestionSpec.java index 7d3a04999aba..2aa91e24578b 100644 --- a/indexing-hadoop/src/main/java/org/apache/druid/indexer/HadoopIngestionSpec.java +++ b/indexing-hadoop/src/main/java/org/apache/druid/indexer/HadoopIngestionSpec.java @@ -139,7 +139,7 @@ public HadoopIngestionSpec withTuningConfig(HadoopTuningConfig config) ); } - public static HadoopIngestionSpec updateSegmentListIfDatasourcePathSpecIsUsed( + public static void updateSegmentListIfDatasourcePathSpecIsUsed( HadoopIngestionSpec spec, ObjectMapper jsonMapper, UsedSegmentsRetriever segmentsRetriever @@ -173,7 +173,7 @@ public static HadoopIngestionSpec updateSegmentListIfDatasourcePathSpecIsUsed( DatasourceIngestionSpec.class ); - Collection usedVisibleSegments = segmentsRetriever.getUsedSegmentsForIntervals( + Collection usedVisibleSegments = segmentsRetriever.retrieveUsedSegmentsForIntervals( ingestionSpecObj.getDataSource(), ingestionSpecObj.getIntervals(), Segments.ONLY_VISIBLE @@ -213,8 +213,6 @@ public static HadoopIngestionSpec updateSegmentListIfDatasourcePathSpecIsUsed( datasourcePathSpec.put(segments, windowedSegments); } } - - return spec; } } diff --git a/indexing-hadoop/src/main/java/org/apache/druid/indexer/path/MetadataStoreBasedUsedSegmentsRetriever.java b/indexing-hadoop/src/main/java/org/apache/druid/indexer/path/MetadataStoreBasedUsedSegmentsRetriever.java index b4fe44f7bbcf..e1afb4cb6b62 100644 --- a/indexing-hadoop/src/main/java/org/apache/druid/indexer/path/MetadataStoreBasedUsedSegmentsRetriever.java +++ b/indexing-hadoop/src/main/java/org/apache/druid/indexer/path/MetadataStoreBasedUsedSegmentsRetriever.java @@ -33,7 +33,7 @@ */ public class MetadataStoreBasedUsedSegmentsRetriever implements UsedSegmentsRetriever { - private IndexerMetadataStorageCoordinator indexerMetadataStorageCoordinator; + private final IndexerMetadataStorageCoordinator indexerMetadataStorageCoordinator; @Inject public MetadataStoreBasedUsedSegmentsRetriever(IndexerMetadataStorageCoordinator indexerMetadataStorageCoordinator) @@ -45,12 +45,12 @@ public MetadataStoreBasedUsedSegmentsRetriever(IndexerMetadataStorageCoordinator } @Override - public Collection getUsedSegmentsForIntervals( + public Collection retrieveUsedSegmentsForIntervals( String dataSource, List intervals, Segments visibility ) { - return indexerMetadataStorageCoordinator.getUsedSegmentsForIntervals(dataSource, intervals, visibility); + return indexerMetadataStorageCoordinator.retrieveUsedSegmentsForIntervals(dataSource, intervals, visibility); } } diff --git a/indexing-hadoop/src/main/java/org/apache/druid/indexer/path/UsedSegmentsRetriever.java b/indexing-hadoop/src/main/java/org/apache/druid/indexer/path/UsedSegmentsRetriever.java index 428569f709c4..e1370e613563 100644 --- a/indexing-hadoop/src/main/java/org/apache/druid/indexer/path/UsedSegmentsRetriever.java +++ b/indexing-hadoop/src/main/java/org/apache/druid/indexer/path/UsedSegmentsRetriever.java @@ -32,7 +32,8 @@ public interface UsedSegmentsRetriever { /** - * Get all segments which may include any data in the interval and are marked as used. + * Retrieve (potentially, from a remote node) all segments which may include any data in the interval and are marked + * as used. * * The order of segments within the returned collection is unspecified, but each segment is guaranteed to appear in * the collection only once. @@ -48,9 +49,12 @@ public interface UsedSegmentsRetriever * requested interval. * * @implNote This method doesn't return a {@link java.util.Set} because it's implemented via {@link - * org.apache.druid.indexing.overlord.IndexerMetadataStorageCoordinator#getUsedSegmentsForIntervals} and which returns - * a collection. Producing a {@link java.util.Set} would require an unnecessary copy of segments collection. + * org.apache.druid.indexing.overlord.IndexerMetadataStorageCoordinator#retrieveUsedSegmentsForIntervals} and which + * returns a collection. Producing a {@link java.util.Set} would require an unnecessary copy of segments collection. */ - Collection getUsedSegmentsForIntervals(String dataSource, List intervals, Segments visibility) - throws IOException; + Collection retrieveUsedSegmentsForIntervals( + String dataSource, + List intervals, + Segments visibility + ) throws IOException; } diff --git a/indexing-hadoop/src/test/java/org/apache/druid/indexer/HadoopIngestionSpecUpdateDatasourcePathSpecSegmentsTest.java b/indexing-hadoop/src/test/java/org/apache/druid/indexer/HadoopIngestionSpecUpdateDatasourcePathSpecSegmentsTest.java index dfe667e83880..6402721e73c6 100644 --- a/indexing-hadoop/src/test/java/org/apache/druid/indexer/HadoopIngestionSpecUpdateDatasourcePathSpecSegmentsTest.java +++ b/indexing-hadoop/src/test/java/org/apache/druid/indexer/HadoopIngestionSpecUpdateDatasourcePathSpecSegmentsTest.java @@ -45,6 +45,7 @@ import org.junit.Assert; import org.junit.Test; +import javax.annotation.Nullable; import java.io.IOException; import java.util.Collections; import java.util.Map; @@ -268,7 +269,7 @@ public void testUpdateSegmentListIfDatasourcePathSpecIsUsedWithMultiplePathSpec( private HadoopDruidIndexerConfig testRunUpdateSegmentListIfDatasourcePathSpecIsUsed( PathSpec datasourcePathSpec, - Interval jobInterval + @Nullable Interval jobInterval ) throws Exception { @@ -300,25 +301,29 @@ private HadoopDruidIndexerConfig testRunUpdateSegmentListIfDatasourcePathSpecIsU UsedSegmentsRetriever segmentsRetriever = EasyMock.createMock(UsedSegmentsRetriever.class); - EasyMock.expect( - segmentsRetriever.getUsedSegmentsForIntervals( - TEST_DATA_SOURCE, - Collections.singletonList(jobInterval != null ? jobInterval.overlap(TEST_DATA_SOURCE_INTERVAL) : null), - Segments.ONLY_VISIBLE + EasyMock + .expect( + segmentsRetriever.retrieveUsedSegmentsForIntervals( + TEST_DATA_SOURCE, + Collections.singletonList(jobInterval != null ? jobInterval.overlap(TEST_DATA_SOURCE_INTERVAL) : null), + Segments.ONLY_VISIBLE + ) ) - ).andReturn(ImmutableList.of(SEGMENT)); + .andReturn(ImmutableList.of(SEGMENT)); - EasyMock.expect( - segmentsRetriever.getUsedSegmentsForIntervals( - TEST_DATA_SOURCE2, - Collections.singletonList(jobInterval != null ? jobInterval.overlap(TEST_DATA_SOURCE_INTERVAL2) : null), - Segments.ONLY_VISIBLE + EasyMock + .expect( + segmentsRetriever.retrieveUsedSegmentsForIntervals( + TEST_DATA_SOURCE2, + Collections.singletonList(jobInterval != null ? jobInterval.overlap(TEST_DATA_SOURCE_INTERVAL2) : null), + Segments.ONLY_VISIBLE + ) ) - ).andReturn(ImmutableList.of(SEGMENT2)); + .andReturn(ImmutableList.of(SEGMENT2)); EasyMock.replay(segmentsRetriever); - spec = HadoopIngestionSpec.updateSegmentListIfDatasourcePathSpecIsUsed(spec, jsonMapper, segmentsRetriever); + HadoopIngestionSpec.updateSegmentListIfDatasourcePathSpecIsUsed(spec, jsonMapper, segmentsRetriever); return HadoopDruidIndexerConfig.fromString(jsonMapper.writeValueAsString(spec)); } } diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/appenderator/ActionBasedUsedSegmentChecker.java b/indexing-service/src/main/java/org/apache/druid/indexing/appenderator/ActionBasedUsedSegmentChecker.java index 04a026b50fed..984058895e3c 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/appenderator/ActionBasedUsedSegmentChecker.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/appenderator/ActionBasedUsedSegmentChecker.java @@ -27,6 +27,7 @@ import org.apache.druid.segment.realtime.appenderator.SegmentIdWithShardSpec; import org.apache.druid.segment.realtime.appenderator.UsedSegmentChecker; import org.apache.druid.timeline.DataSegment; +import org.apache.druid.timeline.SegmentId; import org.joda.time.Interval; import java.io.IOException; @@ -47,34 +48,33 @@ public ActionBasedUsedSegmentChecker(TaskActionClient taskActionClient) } @Override - public Set findUsedSegments(Set identifiers) throws IOException + public Set findUsedSegments(Set segmentIds) throws IOException { // Group by dataSource - final Map> identifiersByDataSource = new TreeMap<>(); - for (SegmentIdWithShardSpec identifier : identifiers) { - identifiersByDataSource.computeIfAbsent(identifier.getDataSource(), k -> new HashSet<>()); - - identifiersByDataSource.get(identifier.getDataSource()).add(identifier); + final Map> idsByDataSource = new TreeMap<>(); + for (SegmentIdWithShardSpec segmentId : segmentIds) { + idsByDataSource.computeIfAbsent(segmentId.getDataSource(), i -> new HashSet<>()).add(segmentId.asSegmentId()); } - final Set retVal = new HashSet<>(); + final Set usedSegments = new HashSet<>(); - for (Map.Entry> entry : identifiersByDataSource.entrySet()) { + for (Map.Entry> entry : idsByDataSource.entrySet()) { + String dataSource = entry.getKey(); + Set segmentIdsInDataSource = entry.getValue(); final List intervals = JodaUtils.condenseIntervals( - Iterables.transform(entry.getValue(), input -> input.getInterval()) + Iterables.transform(segmentIdsInDataSource, SegmentId::getInterval) ); - final Collection usedSegmentsForIntervals = taskActionClient.submit( - new RetrieveUsedSegmentsAction(entry.getKey(), null, intervals, Segments.ONLY_VISIBLE) - ); + final Collection usedSegmentsForIntervals = taskActionClient + .submit(new RetrieveUsedSegmentsAction(dataSource, null, intervals, Segments.ONLY_VISIBLE)); for (DataSegment segment : usedSegmentsForIntervals) { - if (identifiers.contains(SegmentIdWithShardSpec.fromDataSegment(segment))) { - retVal.add(segment); + if (segmentIdsInDataSource.contains(segment.getId())) { + usedSegments.add(segment); } } } - return retVal; + return usedSegments; } } diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/RetrieveUnusedSegmentsAction.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/RetrieveUnusedSegmentsAction.java index 2c54106d4fd4..f114ec456465 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/RetrieveUnusedSegmentsAction.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/RetrieveUnusedSegmentsAction.java @@ -68,7 +68,7 @@ public TypeReference> getReturnTypeReference() @Override public List perform(Task task, TaskActionToolbox toolbox) { - return toolbox.getIndexerMetadataStorageCoordinator().getUnusedSegmentsForInterval(dataSource, interval); + return toolbox.getIndexerMetadataStorageCoordinator().retrieveUnusedSegmentsForInterval(dataSource, interval); } @Override diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/RetrieveUsedSegmentsAction.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/RetrieveUsedSegmentsAction.java index 60411195debf..fab8c4846894 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/RetrieveUsedSegmentsAction.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/RetrieveUsedSegmentsAction.java @@ -44,7 +44,7 @@ * the collection only once. * * @implNote This action doesn't produce a {@link java.util.Set} because it's implemented via {@link - * org.apache.druid.indexing.overlord.IndexerMetadataStorageCoordinator#getUsedSegmentsForIntervals} which returns + * org.apache.druid.indexing.overlord.IndexerMetadataStorageCoordinator#retrieveUsedSegmentsForIntervals} which returns * a collection. Producing a {@link java.util.Set} would require an unnecessary copy of segments collection. */ public class RetrieveUsedSegmentsAction implements TaskAction> @@ -115,7 +115,7 @@ public TypeReference> getReturnTypeReference() public Collection perform(Task task, TaskActionToolbox toolbox) { return toolbox.getIndexerMetadataStorageCoordinator() - .getUsedSegmentsForIntervals(dataSource, intervals, visibility); + .retrieveUsedSegmentsForIntervals(dataSource, intervals, visibility); } @Override diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentAllocateAction.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentAllocateAction.java index 678144999e5c..b547f356d66b 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentAllocateAction.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentAllocateAction.java @@ -23,7 +23,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.type.TypeReference; import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableSet; import org.apache.druid.indexing.common.LockGranularity; import org.apache.druid.indexing.common.TaskLockType; import org.apache.druid.indexing.common.task.Task; @@ -88,7 +87,8 @@ public SegmentAllocateAction( @JsonProperty("sequenceName") String sequenceName, @JsonProperty("previousSegmentId") String previousSegmentId, @JsonProperty("skipSegmentLineageCheck") boolean skipSegmentLineageCheck, - @JsonProperty("shardSpecFactory") @Nullable ShardSpecFactory shardSpecFactory, // nullable for backward compatibility + // nullable for backward compatibility + @JsonProperty("shardSpecFactory") @Nullable ShardSpecFactory shardSpecFactory, @JsonProperty("lockGranularity") @Nullable LockGranularity lockGranularity // nullable for backward compatibility ) { @@ -189,28 +189,26 @@ public SegmentIdWithShardSpec perform( final Interval rowInterval = queryGranularity.bucket(timestamp); - final Set usedSegmentsForRow = new HashSet<>( - msc.getUsedSegmentsForInterval(dataSource, rowInterval, Segments.ONLY_VISIBLE) - ); + final Set usedSegmentsForRow = + new HashSet<>(msc.retrieveUsedSegmentsForInterval(dataSource, rowInterval, Segments.ONLY_VISIBLE)); - final SegmentIdWithShardSpec identifier = usedSegmentsForRow.isEmpty() ? - tryAllocateFirstSegment(toolbox, task, rowInterval) : - tryAllocateSubsequentSegment( - toolbox, - task, - rowInterval, - usedSegmentsForRow.iterator().next() - ); + final SegmentIdWithShardSpec identifier; + if (usedSegmentsForRow.isEmpty()) { + identifier = tryAllocateFirstSegment(toolbox, task, rowInterval); + } else { + identifier = tryAllocateSubsequentSegment(toolbox, task, rowInterval, usedSegmentsForRow.iterator().next()); + } if (identifier != null) { return identifier; } // Could not allocate a pending segment. There's a chance that this is because someone else inserted a segment - // overlapping with this row between when we called "mdc.getUsedSegmentsForInterval" and now. Check it again, + // overlapping with this row between when we called "msc.retrieveUsedSegmentsForInterval" and now. Check it again, // and if it's different, repeat. - if (!ImmutableSet.copyOf(msc.getUsedSegmentsForInterval(dataSource, rowInterval, Segments.ONLY_VISIBLE)) - .equals(usedSegmentsForRow)) { + Set newUsedSegmentsForRow = + new HashSet<>(msc.retrieveUsedSegmentsForInterval(dataSource, rowInterval, Segments.ONLY_VISIBLE)); + if (!newUsedSegmentsForRow.equals(usedSegmentsForRow)) { if (attempt < MAX_ATTEMPTS) { final long shortRandomSleep = 50 + (long) (ThreadLocalRandom.current().nextDouble() * 450); log.debug( diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentInsertAction.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentInsertAction.java index e7804564ef8a..b8f27389aaca 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentInsertAction.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentInsertAction.java @@ -23,8 +23,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.type.TypeReference; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import org.apache.druid.indexing.common.task.Task; +import org.apache.druid.segment.SegmentUtils; import org.apache.druid.timeline.DataSegment; import java.util.Set; @@ -84,7 +84,7 @@ public boolean isAudited() public String toString() { return "SegmentInsertAction{" + - "segments=" + Iterables.transform(segments, DataSegment::getId) + + "segments=" + SegmentUtils.commaSeparatedIdentifiers(segments) + '}'; } } diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentMetadataUpdateAction.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentMetadataUpdateAction.java index 83e8bb96bb23..143805c82d4b 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentMetadataUpdateAction.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentMetadataUpdateAction.java @@ -24,13 +24,13 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.type.TypeReference; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import org.apache.druid.indexing.common.task.IndexTaskUtils; import org.apache.druid.indexing.common.task.Task; import org.apache.druid.indexing.overlord.CriticalAction; import org.apache.druid.java.util.common.ISE; import org.apache.druid.java.util.emitter.service.ServiceMetricEvent; import org.apache.druid.query.DruidMetrics; +import org.apache.druid.segment.SegmentUtils; import org.apache.druid.timeline.DataSegment; import java.util.Set; @@ -111,7 +111,7 @@ public boolean isAudited() public String toString() { return "SegmentMetadataUpdateAction{" + - "segments=" + Iterables.transform(segments, DataSegment::getId) + + "segments=" + SegmentUtils.commaSeparatedIdentifiers(segments) + '}'; } } diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentNukeAction.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentNukeAction.java index 4197a2167d3f..562e8681c761 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentNukeAction.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/actions/SegmentNukeAction.java @@ -24,13 +24,13 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.type.TypeReference; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import org.apache.druid.indexing.common.task.IndexTaskUtils; import org.apache.druid.indexing.common.task.Task; import org.apache.druid.indexing.overlord.CriticalAction; import org.apache.druid.java.util.common.ISE; import org.apache.druid.java.util.emitter.service.ServiceMetricEvent; import org.apache.druid.query.DruidMetrics; +import org.apache.druid.segment.SegmentUtils; import org.apache.druid.timeline.DataSegment; import java.util.Set; @@ -113,7 +113,7 @@ public boolean isAudited() public String toString() { return "SegmentNukeAction{" + - "segments=" + Iterables.transform(segments, DataSegment::getId) + + "segments=" + SegmentUtils.commaSeparatedIdentifiers(segments) + '}'; } } diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/AbstractFixedIntervalTask.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/AbstractFixedIntervalTask.java index 3b117de942fe..9194838f53e1 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/AbstractFixedIntervalTask.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/AbstractFixedIntervalTask.java @@ -22,12 +22,17 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.base.Preconditions; +import com.google.common.collect.Iterables; +import org.apache.druid.indexing.common.TaskLock; import org.apache.druid.indexing.common.TaskLockType; +import org.apache.druid.indexing.common.TaskToolbox; import org.apache.druid.indexing.common.actions.TaskActionClient; import org.apache.druid.indexing.common.actions.TimeChunkLockTryAcquireAction; import org.apache.druid.indexing.common.config.TaskConfig; +import org.apache.druid.java.util.common.ISE; import org.joda.time.Interval; +import java.io.IOException; import java.util.Map; public abstract class AbstractFixedIntervalTask extends AbstractTask @@ -86,4 +91,19 @@ public Interval getInterval() public void stopGracefully(TaskConfig taskConfig) { } + + TaskLock getAndCheckLock(TaskToolbox toolbox) throws IOException + { + // Confirm we have a lock (will throw if there isn't exactly one element) + final TaskLock myLock = Iterables.getOnlyElement(getTaskLocks(toolbox.getTaskActionClient())); + + if (!myLock.getDataSource().equals(getDataSource())) { + throw new ISE("Lock dataSource[%s] != task dataSource[%s]", myLock.getDataSource(), getDataSource()); + } + + if (!myLock.getInterval().equals(getInterval())) { + throw new ISE("Lock interval[%s] != task interval[%s]", myLock.getInterval(), getInterval()); + } + return myLock; + } } diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/AppenderatorDriverRealtimeIndexTask.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/AppenderatorDriverRealtimeIndexTask.java index daaec1ba5fab..d8e975f44589 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/AppenderatorDriverRealtimeIndexTask.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/AppenderatorDriverRealtimeIndexTask.java @@ -79,7 +79,7 @@ import org.apache.druid.segment.realtime.appenderator.Appenderator; import org.apache.druid.segment.realtime.appenderator.AppenderatorDriverAddResult; import org.apache.druid.segment.realtime.appenderator.AppenderatorsManager; -import org.apache.druid.segment.realtime.appenderator.SegmentsAndMetadata; +import org.apache.druid.segment.realtime.appenderator.SegmentsAndCommitMetadata; import org.apache.druid.segment.realtime.appenderator.StreamAppenderatorDriver; import org.apache.druid.segment.realtime.appenderator.TransactionalSegmentPublisher; import org.apache.druid.segment.realtime.firehose.ChatHandler; @@ -136,7 +136,7 @@ private static String makeTaskId(RealtimeAppenderatorIngestionSpec spec) private final RealtimeAppenderatorIngestionSpec spec; @JsonIgnore - private final Queue> pendingHandoffs; + private final Queue> pendingHandoffs; @JsonIgnore private volatile Appenderator appenderator = null; @@ -677,7 +677,7 @@ private void publishSegments( String sequenceName ) { - final ListenableFuture publishFuture = driver.publish( + final ListenableFuture publishFuture = driver.publish( publisher, committerSupplier.get(), Collections.singletonList(sequenceName) diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/ArchiveTask.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/ArchiveTask.java index a53e63106d73..9779989a2d1e 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/ArchiveTask.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/ArchiveTask.java @@ -21,7 +21,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import org.apache.druid.indexer.TaskStatus; import org.apache.druid.indexing.common.TaskLock; import org.apache.druid.indexing.common.TaskToolbox; @@ -63,16 +62,7 @@ public String getType() @Override public TaskStatus run(TaskToolbox toolbox) throws Exception { - // Confirm we have a lock (will throw if there isn't exactly one element) - final TaskLock myLock = Iterables.getOnlyElement(getTaskLocks(toolbox.getTaskActionClient())); - - if (!myLock.getDataSource().equals(getDataSource())) { - throw new ISE("WTF?! Lock dataSource[%s] != task dataSource[%s]", myLock.getDataSource(), getDataSource()); - } - - if (!myLock.getInterval().equals(getInterval())) { - throw new ISE("WTF?! Lock interval[%s] != task interval[%s]", myLock.getInterval(), getInterval()); - } + final TaskLock myLock = getAndCheckLock(toolbox); // List unused segments final List unusedSegments = toolbox diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/CompactionIOConfig.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/CompactionIOConfig.java index e107d2e4a38b..60972de2673a 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/CompactionIOConfig.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/CompactionIOConfig.java @@ -27,7 +27,8 @@ import java.util.Objects; /** - * {@link IOConfig} for {@link CompactionTask}. + * {@link IOConfig} for {@link CompactionTask}. Should be synchronized with {@link + * org.apache.druid.client.indexing.ClientCompactionIOConfig}. * * @see CompactionInputSpec */ diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/CompactionTask.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/CompactionTask.java index 679e6c53d85c..1fa963684320 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/CompactionTask.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/CompactionTask.java @@ -30,7 +30,9 @@ import com.google.common.collect.HashBiMap; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; +import org.apache.curator.shaded.com.google.common.base.Verify; import org.apache.druid.client.coordinator.CoordinatorClient; +import org.apache.druid.client.indexing.ClientCompactionTaskQuery; import org.apache.druid.client.indexing.IndexingServiceClient; import org.apache.druid.data.input.impl.DimensionSchema; import org.apache.druid.data.input.impl.DimensionSchema.MultiValueHandling; @@ -81,6 +83,7 @@ import org.apache.druid.segment.loading.SegmentLoadingException; import org.apache.druid.segment.realtime.appenderator.AppenderatorsManager; import org.apache.druid.segment.realtime.firehose.ChatHandlerProvider; +import org.apache.druid.server.coordinator.duty.CompactSegments; import org.apache.druid.server.security.AuthorizerMapper; import org.apache.druid.timeline.DataSegment; import org.apache.druid.timeline.TimelineObjectHolder; @@ -104,8 +107,15 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +/** + * The client representation of this task is {@link ClientCompactionTaskQuery}. JSON + * serialization fields of this class must correspond to those of {@link + * ClientCompactionTaskQuery}. + */ public class CompactionTask extends AbstractBatchIndexTask { + private static final Logger log = new Logger(CompactionTask.class); + /** * The CompactionTask creates and runs multiple IndexTask instances. When the {@link AppenderatorsManager} * is asked to clean up, it does so on a per-task basis keyed by task ID. However, the subtask IDs of the @@ -118,9 +128,12 @@ public class CompactionTask extends AbstractBatchIndexTask */ public static final String CTX_KEY_APPENDERATOR_TRACKING_TASK_ID = "appenderatorTrackingTaskId"; - private static final Logger log = new Logger(CompactionTask.class); private static final String TYPE = "compact"; + static { + Verify.verify(TYPE.equals(CompactSegments.COMPACTION_TASK_TYPE)); + } + private final CompactionIOConfig ioConfig; @Nullable private final DimensionsSpec dimensionsSpec; diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/HadoopIndexTask.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/HadoopIndexTask.java index 33f7b9d3c527..353790770675 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/HadoopIndexTask.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/HadoopIndexTask.java @@ -313,7 +313,7 @@ private TaskStatus runInternal(TaskToolbox toolbox) throws Exception final ClassLoader loader = buildClassLoader(toolbox); boolean determineIntervals = !spec.getDataSchema().getGranularitySpec().bucketIntervals().isPresent(); - spec = HadoopIngestionSpec.updateSegmentListIfDatasourcePathSpecIsUsed( + HadoopIngestionSpec.updateSegmentListIfDatasourcePathSpecIsUsed( spec, jsonMapper, new OverlordActionBasedUsedSegmentsRetriever(toolbox) diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/IndexTask.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/IndexTask.java index 4d39df4c1cc6..12d75dab8bf8 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/IndexTask.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/IndexTask.java @@ -31,7 +31,6 @@ import com.google.common.base.Preconditions; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; import com.google.common.hash.HashFunction; import com.google.common.hash.Hashing; import com.google.common.util.concurrent.ListenableFuture; @@ -80,6 +79,7 @@ import org.apache.druid.java.util.common.parsers.ParseException; import org.apache.druid.query.aggregation.AggregatorFactory; import org.apache.druid.segment.IndexSpec; +import org.apache.druid.segment.SegmentUtils; import org.apache.druid.segment.indexing.BatchIOConfig; import org.apache.druid.segment.indexing.DataSchema; import org.apache.druid.segment.indexing.IngestionSpec; @@ -94,7 +94,7 @@ import org.apache.druid.segment.realtime.appenderator.AppenderatorsManager; import org.apache.druid.segment.realtime.appenderator.BaseAppenderatorDriver; import org.apache.druid.segment.realtime.appenderator.BatchAppenderatorDriver; -import org.apache.druid.segment.realtime.appenderator.SegmentsAndMetadata; +import org.apache.druid.segment.realtime.appenderator.SegmentsAndCommitMetadata; import org.apache.druid.segment.realtime.appenderator.TransactionalSegmentPublisher; import org.apache.druid.segment.realtime.firehose.ChatHandler; import org.apache.druid.segment.realtime.firehose.ChatHandlerProvider; @@ -930,7 +930,8 @@ private TaskStatus generateAndPublishSegments( ? getSegmentLockHelper().getLockedExistingSegments() : null; // Probably we can publish atomicUpdateGroup along with segments. - final SegmentsAndMetadata published = awaitPublish(driver.publishAll(inputSegments, publisher), pushTimeout); + final SegmentsAndCommitMetadata published = + awaitPublish(driver.publishAll(inputSegments, publisher), pushTimeout); appenderator.close(); ingestionState = IngestionState.COMPLETED; @@ -949,7 +950,7 @@ private TaskStatus generateAndPublishSegments( buildSegmentsMeters.getUnparseable(), buildSegmentsMeters.getThrownAway() ); - log.info("Published segments: %s", Lists.transform(published.getSegments(), DataSegment::getId)); + log.info("Published segments: %s", SegmentUtils.commaSeparatedIdentifiers(published.getSegments())); toolbox.getTaskReportFileWriter().write(getId(), getTaskCompletionReports()); return TaskStatus.success(getId()); @@ -972,8 +973,8 @@ private TaskStatus generateAndPublishSegments( } } - private static SegmentsAndMetadata awaitPublish( - ListenableFuture publishFuture, + private static SegmentsAndCommitMetadata awaitPublish( + ListenableFuture publishFuture, long publishTimeout ) throws ExecutionException, InterruptedException, TimeoutException { diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/InputSourceProcessor.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/InputSourceProcessor.java index f20cf50bed3b..51f3b0f47ff7 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/InputSourceProcessor.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/InputSourceProcessor.java @@ -40,7 +40,7 @@ import org.apache.druid.segment.indexing.granularity.GranularitySpec; import org.apache.druid.segment.realtime.appenderator.AppenderatorDriverAddResult; import org.apache.druid.segment.realtime.appenderator.BatchAppenderatorDriver; -import org.apache.druid.segment.realtime.appenderator.SegmentsAndMetadata; +import org.apache.druid.segment.realtime.appenderator.SegmentsAndCommitMetadata; import org.apache.druid.utils.CircularBuffer; import org.joda.time.Interval; @@ -87,9 +87,9 @@ public InputSourceProcessor( * All read data is consumed by {@link BatchAppenderatorDriver} which creates new segments. * All created segments are pushed when all input data is processed successfully. * - * @return {@link SegmentsAndMetadata} for the pushed segments. + * @return {@link SegmentsAndCommitMetadata} for the pushed segments. */ - public SegmentsAndMetadata process( + public SegmentsAndCommitMetadata process( DataSchema dataSchema, BatchAppenderatorDriver driver, PartitionsSpec partitionsSpec, @@ -155,8 +155,8 @@ public SegmentsAndMetadata process( // in the future. // If those segments are not pushed here, the remaining available space in appenderator will be kept // small which could lead to smaller segments. - final SegmentsAndMetadata pushed = driver.pushAllAndClear(pushTimeout); - LOG.debug("Pushed segments: %s", SegmentUtils.commaSeparateIdentifiers(pushed.getSegments())); + final SegmentsAndCommitMetadata pushed = driver.pushAllAndClear(pushTimeout); + LOG.debug("Pushed segments: %s", SegmentUtils.commaSeparatedIdentifiers(pushed.getSegments())); } } } else { @@ -174,9 +174,9 @@ public SegmentsAndMetadata process( } } - final SegmentsAndMetadata pushed = driver.pushAllAndClear(pushTimeout); + final SegmentsAndCommitMetadata pushed = driver.pushAllAndClear(pushTimeout); - LOG.debug("Pushed segments: %s", SegmentUtils.commaSeparateIdentifiers(pushed.getSegments())); + LOG.debug("Pushed segments: %s", SegmentUtils.commaSeparatedIdentifiers(pushed.getSegments())); return pushed; } diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/KillTask.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/KillUnusedSegmentsTask.java similarity index 91% rename from indexing-service/src/main/java/org/apache/druid/indexing/common/task/KillTask.java rename to indexing-service/src/main/java/org/apache/druid/indexing/common/task/KillUnusedSegmentsTask.java index b7439d66de06..602c21e72a32 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/KillTask.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/KillUnusedSegmentsTask.java @@ -21,7 +21,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; -import org.apache.druid.client.indexing.ClientKillQuery; +import org.apache.druid.client.indexing.ClientKillUnusedSegmentsTaskQuery; import org.apache.druid.indexer.TaskStatus; import org.apache.druid.indexing.common.TaskLock; import org.apache.druid.indexing.common.TaskToolbox; @@ -44,14 +44,15 @@ import java.util.stream.Collectors; /** - * The client representation of this task is {@link ClientKillQuery}. + * The client representation of this task is {@link ClientKillUnusedSegmentsTaskQuery}. * JSON serialization fields of this class must correspond to those of {@link - * ClientKillQuery}, except for "id" and "context" fields. + * ClientKillUnusedSegmentsTaskQuery}, except for "id" and "context" fields. */ -public class KillTask extends AbstractFixedIntervalTask +public class KillUnusedSegmentsTask extends AbstractFixedIntervalTask { + @JsonCreator - public KillTask( + public KillUnusedSegmentsTask( @JsonProperty("id") String id, @JsonProperty("dataSource") String dataSource, @JsonProperty("interval") Interval interval, diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/MoveTask.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/MoveTask.java index 1985c1299c7a..4a0b3ac7a386 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/MoveTask.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/MoveTask.java @@ -22,7 +22,6 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import org.apache.druid.indexer.TaskStatus; import org.apache.druid.indexing.common.TaskLock; import org.apache.druid.indexing.common.TaskToolbox; @@ -71,16 +70,7 @@ public String getType() @Override public TaskStatus run(TaskToolbox toolbox) throws Exception { - // Confirm we have a lock (will throw if there isn't exactly one element) - final TaskLock myLock = Iterables.getOnlyElement(getTaskLocks(toolbox.getTaskActionClient())); - - if (!myLock.getDataSource().equals(getDataSource())) { - throw new ISE("WTF?! Lock dataSource[%s] != task dataSource[%s]", myLock.getDataSource(), getDataSource()); - } - - if (!myLock.getInterval().equals(getInterval())) { - throw new ISE("WTF?! Lock interval[%s] != task interval[%s]", myLock.getInterval(), getInterval()); - } + final TaskLock myLock = getAndCheckLock(toolbox); // List unused segments final List unusedSegments = toolbox diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/RestoreTask.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/RestoreTask.java index 4e3960a6dab6..45ae99a72bda 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/RestoreTask.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/RestoreTask.java @@ -21,7 +21,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import org.apache.druid.indexer.TaskStatus; import org.apache.druid.indexing.common.TaskLock; import org.apache.druid.indexing.common.TaskToolbox; @@ -64,16 +63,7 @@ public String getType() @Override public TaskStatus run(TaskToolbox toolbox) throws Exception { - // Confirm we have a lock (will throw if there isn't exactly one element) - final TaskLock myLock = Iterables.getOnlyElement(getTaskLocks(toolbox.getTaskActionClient())); - - if (!myLock.getDataSource().equals(getDataSource())) { - throw new ISE("WTF?! Lock dataSource[%s] != task dataSource[%s]", myLock.getDataSource(), getDataSource()); - } - - if (!myLock.getInterval().equals(getInterval())) { - throw new ISE("WTF?! Lock interval[%s] != task interval[%s]", myLock.getInterval(), getInterval()); - } + final TaskLock myLock = getAndCheckLock(toolbox); // List unused segments final List unusedSegments = toolbox diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/SegmentLockHelper.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/SegmentLockHelper.java index 020f29efa3ae..546fd65089d1 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/SegmentLockHelper.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/SegmentLockHelper.java @@ -29,6 +29,7 @@ import org.apache.druid.java.util.common.ISE; import org.apache.druid.java.util.common.granularity.Granularity; import org.apache.druid.java.util.common.io.Closer; +import org.apache.druid.segment.SegmentUtils; import org.apache.druid.timeline.DataSegment; import org.joda.time.Interval; @@ -141,16 +142,16 @@ private void verifySegmentGranularity(List segments) if (!nonAlignedSegments.isEmpty()) { throw new ISE( - "Non-aligned segments[%s] for granularity[%s]", - nonAlignedSegments.stream().map(DataSegment::getId).collect(Collectors.toList()), + "Non-aligned segments %s for granularity[%s]", + SegmentUtils.commaSeparatedIdentifiers(nonAlignedSegments), knownSegmentGranularity ); } } } else { throw new ISE( - "Found different granularities in segments[%s]", - segments.stream().map(DataSegment::getId).collect(Collectors.toList()) + "Found different granularities in segments %s", + SegmentUtils.commaSeparatedIdentifiers(segments) ); } } @@ -167,8 +168,8 @@ private boolean tryLockSegments(TaskActionClient actionClient, List .allMatch(segment -> segment.getVersion().equals(segmentsInInterval.get(0).getVersion())); Preconditions.checkState( hasSameVersion, - "Segments[%s] should have same version", - segmentsInInterval.stream().map(DataSegment::getId).collect(Collectors.toList()) + "Segments %s should have same version", + SegmentUtils.commaSeparatedIdentifiers(segmentsInInterval) ); final List lockResults = actionClient.submit( new SegmentLockTryAcquireAction( diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/Task.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/Task.java index a5db7586439b..c069c73cec70 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/Task.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/Task.java @@ -53,14 +53,15 @@ */ @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") @JsonSubTypes(value = { - @Type(name = "kill", value = KillTask.class), + @Type(name = "kill", value = KillUnusedSegmentsTask.class), @Type(name = "move", value = MoveTask.class), @Type(name = "archive", value = ArchiveTask.class), @Type(name = "restore", value = RestoreTask.class), @Type(name = "index", value = IndexTask.class), @Type(name = ParallelIndexSupervisorTask.TYPE, value = ParallelIndexSupervisorTask.class), @Type(name = SinglePhaseSubTask.TYPE, value = SinglePhaseSubTask.class), - @Type(name = SinglePhaseSubTask.OLD_TYPE_NAME, value = LegacySinglePhaseSubTask.class), // for backward compatibility + // for backward compatibility + @Type(name = SinglePhaseSubTask.OLD_TYPE_NAME, value = LegacySinglePhaseSubTask.class), @Type(name = PartialHashSegmentGenerateTask.TYPE, value = PartialHashSegmentGenerateTask.class), @Type(name = PartialHashSegmentMergeTask.TYPE, value = PartialHashSegmentMergeTask.class), @Type(name = PartialRangeSegmentGenerateTask.TYPE, value = PartialRangeSegmentGenerateTask.class), diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/Tasks.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/Tasks.java index ada53eedd1d3..e16e52ecd05d 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/Tasks.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/Tasks.java @@ -19,8 +19,11 @@ package org.apache.druid.indexing.common.task; +import org.apache.curator.shaded.com.google.common.base.Verify; import org.apache.druid.java.util.common.JodaUtils; import org.apache.druid.java.util.common.guava.Comparators; +import org.apache.druid.server.coordinator.DataSourceCompactionConfig; +import org.apache.druid.server.coordinator.duty.CompactSegments; import org.joda.time.Interval; import java.util.ArrayList; @@ -34,6 +37,11 @@ public class Tasks public static final int DEFAULT_REALTIME_TASK_PRIORITY = 75; public static final int DEFAULT_BATCH_INDEX_TASK_PRIORITY = 50; public static final int DEFAULT_MERGE_TASK_PRIORITY = 25; + + static { + Verify.verify(DEFAULT_MERGE_TASK_PRIORITY == DataSourceCompactionConfig.DEFAULT_COMPACTION_TASK_PRIORITY); + } + public static final int DEFAULT_TASK_PRIORITY = 0; public static final long DEFAULT_LOCK_TIMEOUT_MILLIS = TimeUnit.MINUTES.toMillis(5); public static final boolean DEFAULT_FORCE_TIME_CHUNK_LOCK = true; @@ -42,14 +50,21 @@ public class Tasks public static final String PRIORITY_KEY = "priority"; public static final String LOCK_TIMEOUT_KEY = "taskLockTimeout"; public static final String FORCE_TIME_CHUNK_LOCK_KEY = "forceTimeChunkLock"; - // This context is used in auto compaction. When it is set in the context, the segments created by the task - // will fill 'lastCompactionState' in its metadata. This will be used to track what segments are compacted or not. - // See DataSegment and NewestSegmentFirstIterator for more details. + /** + *This context is used in auto compaction. When it is set in the context, the segments created by the task + * will fill 'lastCompactionState' in its metadata. This will be used to track what segments are compacted or not. + * See {@link org.apache.druid.timeline.DataSegment} and {@link + * org.apache.druid.server.coordinator.duty.NewestSegmentFirstIterator} for more details. + */ public static final String STORE_COMPACTION_STATE_KEY = "storeCompactionState"; - public static SortedSet computeCompactIntervals(SortedSet intervals) + static { + Verify.verify(STORE_COMPACTION_STATE_KEY.equals(CompactSegments.STORE_COMPACTION_STATE_KEY)); + } + + public static SortedSet computeCondensedIntervals(SortedSet intervals) { - final SortedSet compactIntervals = new TreeSet<>(Comparators.intervalsByStartThenEnd()); + final SortedSet condensedIntervals = new TreeSet<>(Comparators.intervalsByStartThenEnd()); List toBeAccumulated = new ArrayList<>(); for (Interval interval : intervals) { if (toBeAccumulated.size() == 0) { @@ -58,15 +73,15 @@ public static SortedSet computeCompactIntervals(SortedSet in if (toBeAccumulated.get(toBeAccumulated.size() - 1).abuts(interval)) { toBeAccumulated.add(interval); } else { - compactIntervals.add(JodaUtils.umbrellaInterval(toBeAccumulated)); + condensedIntervals.add(JodaUtils.umbrellaInterval(toBeAccumulated)); toBeAccumulated.clear(); toBeAccumulated.add(interval); } } } if (toBeAccumulated.size() > 0) { - compactIntervals.add(JodaUtils.umbrellaInterval(toBeAccumulated)); + condensedIntervals.add(JodaUtils.umbrellaInterval(toBeAccumulated)); } - return compactIntervals; + return condensedIntervals; } } diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/ParallelIndexSupervisorTask.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/ParallelIndexSupervisorTask.java index ed307145b073..ab43f61f4c14 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/ParallelIndexSupervisorTask.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/ParallelIndexSupervisorTask.java @@ -812,8 +812,7 @@ private static void publishSegments(TaskToolbox toolbox, Map report.getNewSegments().stream()) .map(SegmentIdWithShardSpec::fromDataSegment) .collect(Collectors.toSet()); - if (usedSegmentChecker.findUsedSegments(segmentsIdentifiers) - .equals(newSegments)) { + if (usedSegmentChecker.findUsedSegments(segmentsIdentifiers).equals(newSegments)) { LOG.info("Our segments really do exist, awaiting handoff."); } else { throw new ISE("Failed to publish segments[%s]", newSegments); diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/PartialSegmentGenerateTask.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/PartialSegmentGenerateTask.java index 642936109660..7d41dfaeff1b 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/PartialSegmentGenerateTask.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/PartialSegmentGenerateTask.java @@ -45,7 +45,7 @@ import org.apache.druid.segment.realtime.appenderator.Appenderator; import org.apache.druid.segment.realtime.appenderator.AppenderatorsManager; import org.apache.druid.segment.realtime.appenderator.BatchAppenderatorDriver; -import org.apache.druid.segment.realtime.appenderator.SegmentsAndMetadata; +import org.apache.druid.segment.realtime.appenderator.SegmentsAndCommitMetadata; import org.apache.druid.timeline.DataSegment; import java.io.File; @@ -188,7 +188,7 @@ private List generateSegments( pushTimeout, inputRowIteratorBuilder ); - final SegmentsAndMetadata pushed = inputSourceProcessor.process( + final SegmentsAndCommitMetadata pushed = inputSourceProcessor.process( dataSchema, driver, partitionsSpec, diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/SinglePhaseSubTask.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/SinglePhaseSubTask.java index 8bf40136eafe..e94af771e41a 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/SinglePhaseSubTask.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/SinglePhaseSubTask.java @@ -70,7 +70,7 @@ import org.apache.druid.segment.realtime.appenderator.BatchAppenderatorDriver; import org.apache.druid.segment.realtime.appenderator.SegmentAllocator; import org.apache.druid.segment.realtime.appenderator.SegmentIdWithShardSpec; -import org.apache.druid.segment.realtime.appenderator.SegmentsAndMetadata; +import org.apache.druid.segment.realtime.appenderator.SegmentsAndCommitMetadata; import org.apache.druid.timeline.DataSegment; import org.apache.druid.timeline.VersionedIntervalTimeline; import org.apache.druid.timeline.partition.NumberedOverwritingShardSpecFactory; @@ -484,7 +484,7 @@ private Set generateAndPushSegments( // There can be some segments waiting for being published even though any rows won't be added to them. // If those segments are not published here, the available space in appenderator will be kept to be small // which makes the size of segments smaller. - final SegmentsAndMetadata pushed = driver.pushAllAndClear(pushTimeout); + final SegmentsAndCommitMetadata pushed = driver.pushAllAndClear(pushTimeout); pushedSegments.addAll(pushed.getSegments()); LOG.info("Pushed segments[%s]", pushed.getSegments()); } @@ -503,7 +503,7 @@ private Set generateAndPushSegments( } } - final SegmentsAndMetadata pushed = driver.pushAllAndClear(pushTimeout); + final SegmentsAndCommitMetadata pushed = driver.pushAllAndClear(pushTimeout); pushedSegments.addAll(pushed.getSegments()); LOG.info("Pushed segments[%s]", pushed.getSegments()); appenderator.close(); diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/TaskMonitor.java b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/TaskMonitor.java index f4a7889c51f3..588f1628d770 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/TaskMonitor.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/common/task/batch/parallel/TaskMonitor.java @@ -90,12 +90,12 @@ public class TaskMonitor @GuardedBy("taskCountLock") private int numFailedTasks; /** - * This metric is used only for unit tests because the current task status system doesn't track the killed task - * status. Currently, this metric only represents number of killed tasks by {@link ParallelIndexTaskRunner}. + * This metric is used only for unit tests because the current task status system doesn't track the canceled task + * status. Currently, this metric only represents the number of canceled tasks by {@link ParallelIndexTaskRunner}. * See {@link #stop()}, {@link ParallelIndexPhaseRunner#run()}, and * {@link ParallelIndexPhaseRunner#stopGracefully()}. */ - private int numKilledTasks; + private int numCanceledTasks; @GuardedBy("startStopLock") private boolean running = false; @@ -185,7 +185,7 @@ public void start(long taskStatusCheckingPeriod) } /** - * Stop task monitoring and kill all running tasks. + * Stop task monitoring and cancel all running tasks. */ public void stop() { @@ -194,6 +194,7 @@ public void stop() running = false; taskStatusChecker.shutdownNow(); + synchronized (taskCountLock) { if (numRunningTasks > 0) { final Iterator iterator = runningTasks.values().iterator(); @@ -201,15 +202,15 @@ public void stop() final MonitorEntry entry = iterator.next(); iterator.remove(); final String taskId = entry.runningTask.getId(); - log.info("Request to kill subtask[%s]", taskId); - indexingServiceClient.killTask(taskId); + log.info("Request to cancel subtask[%s]", taskId); + indexingServiceClient.cancelTask(taskId); numRunningTasks--; - numKilledTasks++; + numCanceledTasks++; } if (numRunningTasks > 0) { log.warn( - "Inconsistent state: numRunningTasks[%d] is still not zero after trying to kill all running tasks.", + "Inconsistent state: numRunningTasks[%d] is still not zero after trying to cancel all running tasks.", numRunningTasks ); } @@ -343,9 +344,9 @@ int getNumRunningTasks() } @VisibleForTesting - int getNumKilledTasks() + int getNumCanceledTasks() { - return numKilledTasks; + return numCanceledTasks; } ParallelIndexingPhaseProgress getProgress() diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/hadoop/OverlordActionBasedUsedSegmentsRetriever.java b/indexing-service/src/main/java/org/apache/druid/indexing/hadoop/OverlordActionBasedUsedSegmentsRetriever.java index 0ae705e1f30e..73bc411fb01d 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/hadoop/OverlordActionBasedUsedSegmentsRetriever.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/hadoop/OverlordActionBasedUsedSegmentsRetriever.java @@ -45,7 +45,7 @@ public OverlordActionBasedUsedSegmentsRetriever(TaskToolbox toolbox) } @Override - public Collection getUsedSegmentsForIntervals( + public Collection retrieveUsedSegmentsForIntervals( String dataSource, List intervals, Segments visibility diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/input/DruidInputSource.java b/indexing-service/src/main/java/org/apache/druid/indexing/input/DruidInputSource.java index 4d4d0f30ad16..bc07f02d008b 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/input/DruidInputSource.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/input/DruidInputSource.java @@ -370,8 +370,10 @@ public static List> getTimelineForInte Collection usedSegments; while (true) { try { - usedSegments = - coordinatorClient.getDatabaseSegmentDataSourceSegments(dataSource, Collections.singletonList(interval)); + usedSegments = coordinatorClient.fetchUsedSegmentsInDataSourceForIntervals( + dataSource, + Collections.singletonList(interval) + ); break; } catch (Throwable e) { @@ -405,7 +407,7 @@ public static List> getTimelineForSegm Comparators.intervalsByStartThenEnd() ); for (WindowedSegmentId windowedSegmentId : Preconditions.checkNotNull(segmentIds, "segmentIds")) { - final DataSegment segment = coordinatorClient.getDatabaseSegmentDataSourceSegment( + final DataSegment segment = coordinatorClient.fetchUsedSegment( dataSource, windowedSegmentId.getSegmentId() ); diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/overlord/IndexerMetadataStorageAdapter.java b/indexing-service/src/main/java/org/apache/druid/indexing/overlord/IndexerMetadataStorageAdapter.java index cd550c2ad7bf..4671c5bb7a96 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/overlord/IndexerMetadataStorageAdapter.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/overlord/IndexerMetadataStorageAdapter.java @@ -64,6 +64,6 @@ public int deletePendingSegments(String dataSource, Interval deleteInterval) activeTaskInterval.getStart() ); - return indexerMetadataStorageCoordinator.deletePendingSegments(dataSource, deleteInterval); + return indexerMetadataStorageCoordinator.deletePendingSegmentsCreatedInInterval(dataSource, deleteInterval); } } diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/overlord/http/OverlordResource.java b/indexing-service/src/main/java/org/apache/druid/indexing/overlord/http/OverlordResource.java index 6226abd68bcb..e466e5ba60c8 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/overlord/http/OverlordResource.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/overlord/http/OverlordResource.java @@ -32,6 +32,7 @@ import org.apache.druid.audit.AuditEntry; import org.apache.druid.audit.AuditInfo; import org.apache.druid.audit.AuditManager; +import org.apache.druid.client.indexing.ClientTaskQuery; import org.apache.druid.common.config.ConfigManager.SetResult; import org.apache.druid.common.config.JacksonConfigManager; import org.apache.druid.indexer.RunnerTaskState; @@ -146,14 +147,16 @@ public OverlordResource( this.workerTaskRunnerQueryAdapter = workerTaskRunnerQueryAdapter; } + /** + * Warning, magic: {@link org.apache.druid.client.indexing.HttpIndexingServiceClient#runTask} may call this method + * remotely with {@link ClientTaskQuery} objects, but we deserialize {@link Task} objects. See the comment for {@link + * ClientTaskQuery} for details. + */ @POST @Path("/task") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - public Response taskPost( - final Task task, - @Context final HttpServletRequest req - ) + public Response taskPost(final Task task, @Context final HttpServletRequest req) { final String dataSource = task.getDataSource(); final ResourceAction resourceAction = new ResourceAction( diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/seekablestream/SeekableStreamIndexTaskRunner.java b/indexing-service/src/main/java/org/apache/druid/indexing/seekablestream/SeekableStreamIndexTaskRunner.java index 3fbbcb83bfaf..e37e1fb27fc6 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/seekablestream/SeekableStreamIndexTaskRunner.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/seekablestream/SeekableStreamIndexTaskRunner.java @@ -78,13 +78,14 @@ import org.apache.druid.java.util.common.parsers.ParseException; import org.apache.druid.java.util.emitter.EmittingLogger; import org.apache.druid.query.aggregation.AggregatorFactory; +import org.apache.druid.segment.SegmentUtils; import org.apache.druid.segment.indexing.RealtimeIOConfig; import org.apache.druid.segment.realtime.FireDepartment; import org.apache.druid.segment.realtime.FireDepartmentMetrics; import org.apache.druid.segment.realtime.appenderator.Appenderator; import org.apache.druid.segment.realtime.appenderator.AppenderatorDriverAddResult; import org.apache.druid.segment.realtime.appenderator.AppenderatorsManager; -import org.apache.druid.segment.realtime.appenderator.SegmentsAndMetadata; +import org.apache.druid.segment.realtime.appenderator.SegmentsAndCommitMetadata; import org.apache.druid.segment.realtime.appenderator.StreamAppenderatorDriver; import org.apache.druid.segment.realtime.firehose.ChatHandler; import org.apache.druid.segment.realtime.firehose.ChatHandlerProvider; @@ -215,8 +216,8 @@ public enum Status private final AppenderatorsManager appenderatorsManager; private final Set publishingSequences = Sets.newConcurrentHashSet(); - private final List> publishWaitList = new ArrayList<>(); - private final List> handOffWaitList = new ArrayList<>(); + private final List> publishWaitList = new ArrayList<>(); + private final List> handOffWaitList = new ArrayList<>(); private final LockGranularity lockGranularityToUse; @@ -856,7 +857,7 @@ public void onFailure(Throwable t) // handoffFuture. handoffFuture can throw an exception if 1) the corresponding publishFuture failed or 2) it // failed to persist sequences. It might also return null if handoff failed, but was recoverable. // See publishAndRegisterHandoff() for details. - List handedOffList = Collections.emptyList(); + List handedOffList = Collections.emptyList(); if (tuningConfig.getHandoffConditionTimeout() == 0) { handedOffList = Futures.allAsList(handOffWaitList).get(); } else { @@ -874,7 +875,7 @@ public void onFailure(Throwable t) } } - for (SegmentsAndMetadata handedOff : handedOffList) { + for (SegmentsAndCommitMetadata handedOff : handedOffList) { log.info( "Handoff complete for segments: %s", String.join(", ", Lists.transform(handedOff.getSegments(), DataSegment::toString)) @@ -956,12 +957,12 @@ public void onFailure(Throwable t) private void checkPublishAndHandoffFailure() throws ExecutionException, InterruptedException { // Check if any publishFuture failed. - final List> publishFinished = publishWaitList + final List> publishFinished = publishWaitList .stream() .filter(Future::isDone) .collect(Collectors.toList()); - for (ListenableFuture publishFuture : publishFinished) { + for (ListenableFuture publishFuture : publishFinished) { // If publishFuture failed, the below line will throw an exception and catched by (1), and then (2) or (3). publishFuture.get(); } @@ -969,12 +970,12 @@ private void checkPublishAndHandoffFailure() throws ExecutionException, Interrup publishWaitList.removeAll(publishFinished); // Check if any handoffFuture failed. - final List> handoffFinished = handOffWaitList + final List> handoffFinished = handOffWaitList .stream() .filter(Future::isDone) .collect(Collectors.toList()); - for (ListenableFuture handoffFuture : handoffFinished) { + for (ListenableFuture handoffFuture : handoffFinished) { // If handoffFuture failed, the below line will throw an exception and catched by (1), and then (2) or (3). handoffFuture.get(); } @@ -986,13 +987,13 @@ private void publishAndRegisterHandoff(SequenceMetadata publishFuture = Futures.transform( + final ListenableFuture publishFuture = Futures.transform( driver.publish( sequenceMetadata.createPublisher(this, toolbox, ioConfig.isUseTransaction()), sequenceMetadata.getCommitterSupplier(this, stream, lastPersistedOffsets).get(), Collections.singletonList(sequenceMetadata.getSequenceName()) ), - (Function) publishedSegmentsAndMetadata -> { + (Function) publishedSegmentsAndMetadata -> { if (publishedSegmentsAndMetadata == null) { throw new ISE( "Transaction failure publishing segments for sequence [%s]", @@ -1006,21 +1007,21 @@ private void publishAndRegisterHandoff(SequenceMetadata handoffFuture = SettableFuture.create(); + final SettableFuture handoffFuture = SettableFuture.create(); handOffWaitList.add(handoffFuture); Futures.addCallback( publishFuture, - new FutureCallback() + new FutureCallback() { @Override - public void onSuccess(SegmentsAndMetadata publishedSegmentsAndMetadata) + public void onSuccess(SegmentsAndCommitMetadata publishedSegmentsAndCommitMetadata) { log.info( - "Published segments [%s] for sequence [%s] with metadata [%s].", - String.join(", ", Lists.transform(publishedSegmentsAndMetadata.getSegments(), DataSegment::toString)), + "Published segments %s for sequence [%s] with metadata [%s].", + SegmentUtils.commaSeparatedIdentifiers(publishedSegmentsAndCommitMetadata.getSegments()), sequenceMetadata.getSequenceName(), - Preconditions.checkNotNull(publishedSegmentsAndMetadata.getCommitMetadata(), "commitMetadata") + Preconditions.checkNotNull(publishedSegmentsAndCommitMetadata.getCommitMetadata(), "commitMetadata") ); sequences.remove(sequenceMetadata); @@ -1036,23 +1037,20 @@ public void onSuccess(SegmentsAndMetadata publishedSegmentsAndMetadata) } Futures.transform( - driver.registerHandoff(publishedSegmentsAndMetadata), - new Function() + driver.registerHandoff(publishedSegmentsAndCommitMetadata), + new Function() { @Nullable @Override - public Void apply(@Nullable SegmentsAndMetadata handoffSegmentsAndMetadata) + public Void apply(@Nullable SegmentsAndCommitMetadata handoffSegmentsAndCommitMetadata) { - if (handoffSegmentsAndMetadata == null) { + if (handoffSegmentsAndCommitMetadata == null) { log.warn( "Failed to hand off segments: %s", - String.join( - ", ", - Lists.transform(publishedSegmentsAndMetadata.getSegments(), DataSegment::toString) - ) + SegmentUtils.commaSeparatedIdentifiers(publishedSegmentsAndCommitMetadata.getSegments()) ); } - handoffFuture.set(handoffSegmentsAndMetadata); + handoffFuture.set(handoffSegmentsAndCommitMetadata); return null; } } diff --git a/indexing-service/src/main/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisor.java b/indexing-service/src/main/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisor.java index d3a15cde8c4e..95e08029f9f0 100644 --- a/indexing-service/src/main/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisor.java +++ b/indexing-service/src/main/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisor.java @@ -1145,7 +1145,7 @@ public void resetInternal(DataSourceMetadata dataSourceMetadata) if (resetMetadata.getSeekableStreamSequenceNumbers().getStream().equals(ioConfig.getStream())) { // metadata can be null - final DataSourceMetadata metadata = indexerMetadataStorageCoordinator.getDataSourceMetadata(dataSource); + final DataSourceMetadata metadata = indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(dataSource); if (metadata != null && !checkSourceMetadataMatch(metadata)) { throw new IAE( "Datasource metadata instance does not match required, found instance of [%s]", @@ -1578,7 +1578,7 @@ private void verifyAndMergeCheckpoints(final TaskGroup taskGroup) throw new RuntimeException(e); } - final DataSourceMetadata rawDataSourceMetadata = indexerMetadataStorageCoordinator.getDataSourceMetadata(dataSource); + final DataSourceMetadata rawDataSourceMetadata = indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(dataSource); if (rawDataSourceMetadata != null && !checkSourceMetadataMatch(rawDataSourceMetadata)) { throw new IAE( @@ -2057,8 +2057,8 @@ private void cleanupClosedAndExpiredPartitions( // Mark partitions as expired in metadata @SuppressWarnings("unchecked") SeekableStreamDataSourceMetadata currentMetadata = - (SeekableStreamDataSourceMetadata) indexerMetadataStorageCoordinator.getDataSourceMetadata( - dataSource); + (SeekableStreamDataSourceMetadata) + indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(dataSource); SeekableStreamDataSourceMetadata cleanedMetadata = createDataSourceMetadataWithExpiredPartitions(currentMetadata, newlyExpiredPartitions); @@ -2805,10 +2805,10 @@ private void createNewTasks() ImmutableMap simpleStartingOffsets = startingOffsets .entrySet() .stream() - .filter(x -> x.getValue().get() != null) + .filter(entry -> entry.getValue().get() != null) .collect( Collectors.collectingAndThen( - Collectors.toMap(Entry::getKey, x -> x.getValue().get()), + Collectors.toMap(Entry::getKey, entry -> entry.getValue().get()), ImmutableMap::copyOf ) ); @@ -2818,10 +2818,10 @@ private void createNewTasks() simpleUnfilteredStartingOffsets = unfilteredStartingOffsets .entrySet() .stream() - .filter(x -> x.getValue().get() != null) + .filter(entry -> entry.getValue().get() != null) .collect( Collectors.collectingAndThen( - Collectors.toMap(Entry::getKey, x -> x.getValue().get()), + Collectors.toMap(Entry::getKey, entry -> entry.getValue().get()), ImmutableMap::copyOf ) ); @@ -2829,15 +2829,18 @@ private void createNewTasks() simpleUnfilteredStartingOffsets = simpleStartingOffsets; } - Set exclusiveStartSequenceNumberPartitions = !useExclusiveStartingSequence - ? Collections.emptySet() - : startingOffsets - .entrySet() - .stream() - .filter(x -> x.getValue().get() != null - && x.getValue().isExclusive()) - .map(Entry::getKey) - .collect(Collectors.toSet()); + Set exclusiveStartSequenceNumberPartitions; + if (!useExclusiveStartingSequence) { + exclusiveStartSequenceNumberPartitions = Collections.emptySet(); + } else { + exclusiveStartSequenceNumberPartitions = startingOffsets + .entrySet() + .stream() + .filter(x -> x.getValue().get() != null + && x.getValue().isExclusive()) + .map(Entry::getKey) + .collect(Collectors.toSet()); + } activelyReadingTaskGroups.put( groupId, @@ -2988,7 +2991,7 @@ private OrderedSequenceNumber getOffsetFromStorageForPartiti private Map getOffsetsFromMetadataStorage() { - final DataSourceMetadata dataSourceMetadata = indexerMetadataStorageCoordinator.getDataSourceMetadata(dataSource); + final DataSourceMetadata dataSourceMetadata = indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(dataSource); if (dataSourceMetadata instanceof SeekableStreamDataSourceMetadata && checkSourceMetadataMatch(dataSourceMetadata)) { @SuppressWarnings("unchecked") diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/actions/RetrieveSegmentsActionsTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/actions/RetrieveSegmentsActionsTest.java index 9f3d63823e78..86aba77cfd63 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/actions/RetrieveSegmentsActionsTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/actions/RetrieveSegmentsActionsTest.java @@ -74,9 +74,7 @@ public void setup() throws IOException expectedUsedSegments.forEach(s -> actionTestKit.getTaskLockbox().unlock(task, s.getInterval())); - expectedUnusedSegments.forEach( - s -> actionTestKit.getMetadataSegmentManager().markSegmentAsUnused(s.getId().toString()) - ); + expectedUnusedSegments.forEach(s -> actionTestKit.getSegmentsMetadataManager().markSegmentAsUnused(s.getId().toString())); } private DataSegment createSegment(Interval interval, String version) diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/actions/SegmentInsertActionTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/actions/SegmentInsertActionTest.java index a79b3ba327fc..c10df89ad986 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/actions/SegmentInsertActionTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/actions/SegmentInsertActionTest.java @@ -32,6 +32,7 @@ import org.apache.druid.java.util.common.Intervals; import org.apache.druid.timeline.DataSegment; import org.apache.druid.timeline.partition.LinearShardSpec; +import org.assertj.core.api.Assertions; import org.hamcrest.CoreMatchers; import org.joda.time.Interval; import org.junit.Assert; @@ -118,13 +119,10 @@ public void testSimple() throws Exception .build() ); - Assert.assertEquals( - ImmutableSet.of(SEGMENT1, SEGMENT2), - ImmutableSet.copyOf( - actionTestKit.getMetadataStorageCoordinator() - .getUsedSegmentsForInterval(DATA_SOURCE, INTERVAL, Segments.ONLY_VISIBLE) - ) - ); + Assertions.assertThat( + actionTestKit.getMetadataStorageCoordinator() + .retrieveUsedSegmentsForInterval(DATA_SOURCE, INTERVAL, Segments.ONLY_VISIBLE) + ).containsExactlyInAnyOrder(SEGMENT1, SEGMENT2); } @Test diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/actions/SegmentTransactionalInsertActionTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/actions/SegmentTransactionalInsertActionTest.java index f371deb597aa..b9eb14c01c0c 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/actions/SegmentTransactionalInsertActionTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/actions/SegmentTransactionalInsertActionTest.java @@ -33,6 +33,7 @@ import org.apache.druid.java.util.common.Intervals; import org.apache.druid.timeline.DataSegment; import org.apache.druid.timeline.partition.LinearShardSpec; +import org.assertj.core.api.Assertions; import org.hamcrest.CoreMatchers; import org.joda.time.Interval; import org.junit.Assert; @@ -122,17 +123,14 @@ public void testTransactional() throws Exception ); Assert.assertEquals(SegmentPublishResult.ok(ImmutableSet.of(SEGMENT2)), result2); - Assert.assertEquals( - ImmutableSet.of(SEGMENT1, SEGMENT2), - ImmutableSet.copyOf( - actionTestKit.getMetadataStorageCoordinator() - .getUsedSegmentsForInterval(DATA_SOURCE, INTERVAL, Segments.ONLY_VISIBLE) - ) - ); + Assertions.assertThat( + actionTestKit.getMetadataStorageCoordinator() + .retrieveUsedSegmentsForInterval(DATA_SOURCE, INTERVAL, Segments.ONLY_VISIBLE) + ).containsExactlyInAnyOrder(SEGMENT1, SEGMENT2); Assert.assertEquals( new ObjectMetadata(ImmutableList.of(2)), - actionTestKit.getMetadataStorageCoordinator().getDataSourceMetadata(DATA_SOURCE) + actionTestKit.getMetadataStorageCoordinator().retrieveDataSourceMetadata(DATA_SOURCE) ); } diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/actions/TaskActionTestKit.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/actions/TaskActionTestKit.java index e1477d603743..df7311206b0f 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/actions/TaskActionTestKit.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/actions/TaskActionTestKit.java @@ -29,11 +29,11 @@ import org.apache.druid.indexing.overlord.TaskStorage; import org.apache.druid.indexing.overlord.supervisor.SupervisorManager; import org.apache.druid.metadata.IndexerSQLMetadataStorageCoordinator; -import org.apache.druid.metadata.MetadataSegmentManager; -import org.apache.druid.metadata.MetadataSegmentManagerConfig; import org.apache.druid.metadata.MetadataStorageConnectorConfig; import org.apache.druid.metadata.MetadataStorageTablesConfig; -import org.apache.druid.metadata.SQLMetadataSegmentManager; +import org.apache.druid.metadata.SegmentsMetadataManager; +import org.apache.druid.metadata.SegmentsMetadataManagerConfig; +import org.apache.druid.metadata.SqlSegmentsMetadataManager; import org.apache.druid.metadata.TestDerbyConnector; import org.apache.druid.server.metrics.NoopServiceEmitter; import org.easymock.EasyMock; @@ -48,7 +48,7 @@ public class TaskActionTestKit extends ExternalResource private TaskLockbox taskLockbox; private TestDerbyConnector testDerbyConnector; private IndexerMetadataStorageCoordinator metadataStorageCoordinator; - private MetadataSegmentManager metadataSegmentManager; + private SegmentsMetadataManager segmentsMetadataManager; private TaskActionToolbox taskActionToolbox; public TaskLockbox getTaskLockbox() @@ -61,9 +61,9 @@ public IndexerMetadataStorageCoordinator getMetadataStorageCoordinator() return metadataStorageCoordinator; } - public MetadataSegmentManager getMetadataSegmentManager() + public SegmentsMetadataManager getSegmentsMetadataManager() { - return metadataSegmentManager; + return segmentsMetadataManager; } public TaskActionToolbox getTaskActionToolbox() @@ -86,9 +86,9 @@ public void before() testDerbyConnector ); taskLockbox = new TaskLockbox(taskStorage, metadataStorageCoordinator); - metadataSegmentManager = new SQLMetadataSegmentManager( + segmentsMetadataManager = new SqlSegmentsMetadataManager( objectMapper, - Suppliers.ofInstance(new MetadataSegmentManagerConfig()), + Suppliers.ofInstance(new SegmentsMetadataManagerConfig()), Suppliers.ofInstance(metadataStorageTablesConfig), testDerbyConnector ); @@ -116,7 +116,7 @@ public void after() taskLockbox = null; testDerbyConnector = null; metadataStorageCoordinator = null; - metadataSegmentManager = null; + segmentsMetadataManager = null; taskActionToolbox = null; } } diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/ClientCompactQuerySerdeTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/ClientCompactionTaskQuerySerdeTest.java similarity index 95% rename from indexing-service/src/test/java/org/apache/druid/indexing/common/task/ClientCompactQuerySerdeTest.java rename to indexing-service/src/test/java/org/apache/druid/indexing/common/task/ClientCompactionTaskQuerySerdeTest.java index a67128ef6d01..8be6b85864df 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/ClientCompactQuerySerdeTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/ClientCompactionTaskQuerySerdeTest.java @@ -24,10 +24,10 @@ import com.fasterxml.jackson.databind.jsontype.NamedType; import com.google.common.collect.ImmutableList; import org.apache.druid.client.coordinator.CoordinatorClient; -import org.apache.druid.client.indexing.ClientCompactQuery; -import org.apache.druid.client.indexing.ClientCompactQueryTuningConfig; import org.apache.druid.client.indexing.ClientCompactionIOConfig; import org.apache.druid.client.indexing.ClientCompactionIntervalSpec; +import org.apache.druid.client.indexing.ClientCompactionTaskQuery; +import org.apache.druid.client.indexing.ClientCompactionTaskQueryTuningConfig; import org.apache.druid.client.indexing.IndexingServiceClient; import org.apache.druid.client.indexing.NoopIndexingServiceClient; import org.apache.druid.data.input.SegmentsSplitHintSpec; @@ -55,7 +55,7 @@ import java.io.IOException; import java.util.HashMap; -public class ClientCompactQuerySerdeTest +public class ClientCompactionTaskQuerySerdeTest { private static final RowIngestionMetersFactory ROW_INGESTION_METERS_FACTORY = new TestUtils() .getRowIngestionMetersFactory(); @@ -66,7 +66,7 @@ public class ClientCompactQuerySerdeTest public void testSerde() throws IOException { final ObjectMapper mapper = setupInjectablesInObjectMapper(new DefaultObjectMapper()); - final ClientCompactQuery query = new ClientCompactQuery( + final ClientCompactionTaskQuery query = new ClientCompactionTaskQuery( "datasource", new ClientCompactionIOConfig( new ClientCompactionIntervalSpec( @@ -74,7 +74,7 @@ public void testSerde() throws IOException "testSha256OfSortedSegmentIds" ) ), - new ClientCompactQueryTuningConfig( + new ClientCompactionTaskQueryTuningConfig( 100, 40000, 2000L, diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/CompactionTaskParallelRunTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/CompactionTaskParallelRunTest.java index 98bb64bdb511..89098fb4600e 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/CompactionTaskParallelRunTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/CompactionTaskParallelRunTest.java @@ -103,17 +103,19 @@ public CompactionTaskParallelRunTest(LockGranularity lockGranularity) coordinatorClient = new CoordinatorClient(null, null) { @Override - public Collection getDatabaseSegmentDataSourceSegments(String dataSource, List intervals) + public Collection fetchUsedSegmentsInDataSourceForIntervals( + String dataSource, + List intervals + ) { - return getStorageCoordinator().getUsedSegmentsForIntervals(dataSource, intervals, Segments.ONLY_VISIBLE); + return getStorageCoordinator().retrieveUsedSegmentsForIntervals(dataSource, intervals, Segments.ONLY_VISIBLE); } @Override - public DataSegment getDatabaseSegmentDataSourceSegment(String dataSource, String segmentId) + public DataSegment fetchUsedSegment(String dataSource, String segmentId) { - ImmutableDruidDataSource druidDataSource = getMetadataSegmentManager().getImmutableDataSourceWithUsedSegments( - dataSource - ); + ImmutableDruidDataSource druidDataSource = + getSegmentsMetadataManager().getImmutableDataSourceWithUsedSegments(dataSource); if (druidDataSource == null) { throw new ISE("Unknown datasource[%s]", dataSource); } @@ -189,7 +191,7 @@ public void testDruidInputSourceCreateSplitsWithIndividualSplits() throws Except ); List segments = new ArrayList<>( - coordinatorClient.getDatabaseSegmentDataSourceSegments( + coordinatorClient.fetchUsedSegmentsInDataSourceForIntervals( DATA_SOURCE, ImmutableList.of(interval) ) diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/CompactionTaskRunTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/CompactionTaskRunTest.java index 779113fc3d76..2b0874f5150a 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/CompactionTaskRunTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/CompactionTaskRunTest.java @@ -182,9 +182,12 @@ public CompactionTaskRunTest(LockGranularity lockGranularity) coordinatorClient = new CoordinatorClient(null, null) { @Override - public Collection getDatabaseSegmentDataSourceSegments(String dataSource, List intervals) + public Collection fetchUsedSegmentsInDataSourceForIntervals( + String dataSource, + List intervals + ) { - return getStorageCoordinator().getUsedSegmentsForIntervals(dataSource, intervals, Segments.ONLY_VISIBLE); + return getStorageCoordinator().retrieveUsedSegmentsForIntervals(dataSource, intervals, Segments.ONLY_VISIBLE); } }; segmentLoaderFactory = new SegmentLoaderFactory(getIndexIO(), getObjectMapper()); @@ -521,7 +524,7 @@ public void testCompactThenAppend() throws Exception expectedSegments.addAll(appendResult.rhs); final Set usedSegments = new HashSet<>( - getStorageCoordinator().getUsedSegmentsForIntervals( + getStorageCoordinator().retrieveUsedSegmentsForIntervals( DATA_SOURCE, Collections.singletonList(Intervals.of("2014-01-01/2014-01-02")), Segments.ONLY_VISIBLE diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/CompactionTaskTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/CompactionTaskTest.java index caad2db871be..ce9580475dc7 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/CompactionTaskTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/CompactionTaskTest.java @@ -1245,7 +1245,10 @@ private static class TestCoordinatorClient extends CoordinatorClient } @Override - public Collection getDatabaseSegmentDataSourceSegments(String dataSource, List intervals) + public Collection fetchUsedSegmentsInDataSourceForIntervals( + String dataSource, + List intervals + ) { return ImmutableSet.copyOf(segmentMap.keySet()); } diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/IngestionTestBase.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/IngestionTestBase.java index b3ecce4fab0e..3eeeb8bc4aeb 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/IngestionTestBase.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/IngestionTestBase.java @@ -49,10 +49,10 @@ import org.apache.druid.java.util.common.StringUtils; import org.apache.druid.metadata.EntryExistsException; import org.apache.druid.metadata.IndexerSQLMetadataStorageCoordinator; -import org.apache.druid.metadata.MetadataSegmentManager; -import org.apache.druid.metadata.MetadataSegmentManagerConfig; import org.apache.druid.metadata.SQLMetadataConnector; -import org.apache.druid.metadata.SQLMetadataSegmentManager; +import org.apache.druid.metadata.SegmentsMetadataManager; +import org.apache.druid.metadata.SegmentsMetadataManagerConfig; +import org.apache.druid.metadata.SqlSegmentsMetadataManager; import org.apache.druid.metadata.TestDerbyConnector; import org.apache.druid.segment.IndexIO; import org.apache.druid.segment.IndexMergerV9; @@ -93,7 +93,7 @@ public abstract class IngestionTestBase extends InitializedNullHandlingTest private SegmentLoaderFactory segmentLoaderFactory; private TaskStorage taskStorage; private IndexerSQLMetadataStorageCoordinator storageCoordinator; - private MetadataSegmentManager segmentManager; + private SegmentsMetadataManager segmentsMetadataManager; private TaskLockbox lockbox; @Before @@ -110,9 +110,9 @@ public void setUp() throws IOException derbyConnectorRule.metadataTablesConfigSupplier().get(), derbyConnectorRule.getConnector() ); - segmentManager = new SQLMetadataSegmentManager( + segmentsMetadataManager = new SqlSegmentsMetadataManager( objectMapper, - MetadataSegmentManagerConfig::new, + SegmentsMetadataManagerConfig::new, derbyConnectorRule.metadataTablesConfigSupplier(), derbyConnectorRule.getConnector() ); @@ -167,9 +167,9 @@ public IndexerMetadataStorageCoordinator getMetadataStorageCoordinator() return storageCoordinator; } - public MetadataSegmentManager getMetadataSegmentManager() + public SegmentsMetadataManager getSegmentsMetadataManager() { - return segmentManager; + return segmentsMetadataManager; } public TaskLockbox getLockbox() diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/KillTaskTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/KillUnusedSegmentsTaskTest.java similarity index 78% rename from indexing-service/src/test/java/org/apache/druid/indexing/common/task/KillTaskTest.java rename to indexing-service/src/test/java/org/apache/druid/indexing/common/task/KillUnusedSegmentsTaskTest.java index 4db77719b198..688158dc27c3 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/KillTaskTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/KillUnusedSegmentsTaskTest.java @@ -27,6 +27,7 @@ import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.Intervals; import org.apache.druid.timeline.DataSegment; +import org.assertj.core.api.Assertions; import org.joda.time.Interval; import org.junit.Assert; import org.junit.Before; @@ -35,7 +36,7 @@ import java.util.List; import java.util.Set; -public class KillTaskTest extends IngestionTestBase +public class KillUnusedSegmentsTaskTest extends IngestionTestBase { private static final String DATA_SOURCE = "dataSource"; @@ -62,33 +63,31 @@ public void testKill() throws Exception Assert.assertEquals(segments, announced); Assert.assertTrue( - getMetadataSegmentManager().markSegmentAsUnused( + getSegmentsMetadataManager().markSegmentAsUnused( newSegment(Intervals.of("2019-02-01/2019-03-01"), version).getId().toString() ) ); Assert.assertTrue( - getMetadataSegmentManager().markSegmentAsUnused( + getSegmentsMetadataManager().markSegmentAsUnused( newSegment(Intervals.of("2019-03-01/2019-04-01"), version).getId().toString() ) ); - final KillTask task = new KillTask(null, DATA_SOURCE, Intervals.of("2019-03-01/2019-04-01"), null); + final KillUnusedSegmentsTask task = + new KillUnusedSegmentsTask(null, DATA_SOURCE, Intervals.of("2019-03-01/2019-04-01"), null); Assert.assertEquals(TaskState.SUCCESS, taskRunner.run(task).get().getStatusCode()); final List unusedSegments = - getMetadataStorageCoordinator().getUnusedSegmentsForInterval(DATA_SOURCE, Intervals.of("2019/2020")); + getMetadataStorageCoordinator().retrieveUnusedSegmentsForInterval(DATA_SOURCE, Intervals.of("2019/2020")); Assert.assertEquals(ImmutableList.of(newSegment(Intervals.of("2019-02-01/2019-03-01"), version)), unusedSegments); - Assert.assertEquals( - ImmutableSet.of( - newSegment(Intervals.of("2019-01-01/2019-02-01"), version), - newSegment(Intervals.of("2019-04-01/2019-05-01"), version) - ), - ImmutableSet.copyOf( - getMetadataStorageCoordinator() - .getUsedSegmentsForInterval(DATA_SOURCE, Intervals.of("2019/2020"), Segments.ONLY_VISIBLE) - ) + Assertions.assertThat( + getMetadataStorageCoordinator() + .retrieveUsedSegmentsForInterval(DATA_SOURCE, Intervals.of("2019/2020"), Segments.ONLY_VISIBLE) + ).containsExactlyInAnyOrder( + newSegment(Intervals.of("2019-01-01/2019-02-01"), version), + newSegment(Intervals.of("2019-04-01/2019-05-01"), version) ); } diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/TaskSerdeTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/TaskSerdeTest.java index b8ae69e2894f..d415488435f6 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/TaskSerdeTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/TaskSerdeTest.java @@ -24,7 +24,7 @@ import com.fasterxml.jackson.databind.jsontype.NamedType; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import org.apache.druid.client.indexing.ClientKillQuery; +import org.apache.druid.client.indexing.ClientKillUnusedSegmentsTaskQuery; import org.apache.druid.data.input.impl.DimensionsSpec; import org.apache.druid.data.input.impl.LocalInputSource; import org.apache.druid.data.input.impl.NoopInputFormat; @@ -344,7 +344,7 @@ public void testIndexTaskwithResourceSerde() throws Exception @Test public void testKillTaskSerde() throws Exception { - final KillTask task = new KillTask( + final KillUnusedSegmentsTask task = new KillUnusedSegmentsTask( null, "foo", Intervals.of("2010-01-01/P1D"), @@ -354,7 +354,7 @@ public void testKillTaskSerde() throws Exception final String json = jsonMapper.writeValueAsString(task); Thread.sleep(100); // Just want to run the clock a bit to make sure the task id doesn't change - final KillTask task2 = (KillTask) jsonMapper.readValue(json, Task.class); + final KillUnusedSegmentsTask task2 = (KillUnusedSegmentsTask) jsonMapper.readValue(json, Task.class); Assert.assertEquals("foo", task.getDataSource()); Assert.assertEquals(Intervals.of("2010-01-01/P1D"), task.getInterval()); @@ -364,9 +364,9 @@ public void testKillTaskSerde() throws Exception Assert.assertEquals(task.getDataSource(), task2.getDataSource()); Assert.assertEquals(task.getInterval(), task2.getInterval()); - final KillTask task3 = (KillTask) jsonMapper.readValue( + final KillUnusedSegmentsTask task3 = (KillUnusedSegmentsTask) jsonMapper.readValue( jsonMapper.writeValueAsString( - new ClientKillQuery( + new ClientKillUnusedSegmentsTaskQuery( "foo", Intervals.of("2010-01-01/P1D") ) diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/TasksTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/TasksTest.java index 2bbad51392db..248df1db44d3 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/TasksTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/TasksTest.java @@ -34,7 +34,7 @@ public class TasksTest { @Test - public void testComputeCompactIntervals() + public void testComputeCondensedIntervals() { final SortedSet inputIntervals = new TreeSet<>(Comparators.intervalsByStartThenEnd()); for (int m = 1; m < 13; m++) { @@ -59,23 +59,23 @@ public void testComputeCompactIntervals() inputIntervals.add(Intervals.of("2017-12-31/2018-01-01")); - final SortedSet compactIntervals = Tasks.computeCompactIntervals(inputIntervals); - final Iterator compactIntervalIterator = compactIntervals.iterator(); - Assert.assertTrue(compactIntervalIterator.hasNext()); + final SortedSet condensedIntervals = Tasks.computeCondensedIntervals(inputIntervals); + final Iterator condensedIntervalIterator = condensedIntervals.iterator(); + Assert.assertTrue(condensedIntervalIterator.hasNext()); - Interval compactInterval = compactIntervalIterator.next(); + Interval condensedInterval = condensedIntervalIterator.next(); final SortedSet checkedIntervals = new TreeSet<>(Comparators.intervalsByStartThenEnd()); for (Interval inputInterval : inputIntervals) { - if (!compactInterval.contains(inputInterval)) { - if (compactIntervalIterator.hasNext()) { - compactInterval = compactIntervalIterator.next(); - Assert.assertTrue(compactInterval.contains(inputInterval)); + if (!condensedInterval.contains(inputInterval)) { + if (condensedIntervalIterator.hasNext()) { + condensedInterval = condensedIntervalIterator.next(); + Assert.assertTrue(condensedInterval.contains(inputInterval)); } } checkedIntervals.add(inputInterval); } - Assert.assertFalse(compactIntervalIterator.hasNext()); + Assert.assertFalse(condensedIntervalIterator.hasNext()); Assert.assertEquals(inputIntervals, checkedIntervals); } diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/batch/parallel/AbstractParallelIndexSupervisorTaskTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/batch/parallel/AbstractParallelIndexSupervisorTaskTest.java index d0aeede08100..029d2bf20c6a 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/batch/parallel/AbstractParallelIndexSupervisorTaskTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/batch/parallel/AbstractParallelIndexSupervisorTaskTest.java @@ -260,7 +260,7 @@ public TaskStatusResponse getTaskStatus(String taskId) } @Override - public String killTask(String taskId) + public String cancelTask(String taskId) { final Future taskStatusFuture = tasks.remove(taskId); if (taskStatusFuture != null) { diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/batch/parallel/ParallelIndexSupervisorTaskKillTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/batch/parallel/ParallelIndexSupervisorTaskKillTest.java index 7564f8cecc4e..c0b515d31db1 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/batch/parallel/ParallelIndexSupervisorTaskKillTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/batch/parallel/ParallelIndexSupervisorTaskKillTest.java @@ -119,7 +119,7 @@ public void testStopGracefully() throws Exception // completeSubTaskSpecs should be empty because no task has reported its status to TaskMonitor Assert.assertTrue(runner.getCompleteSubTaskSpecs().isEmpty()); - Assert.assertEquals(4, runner.getTaskMonitor().getNumKilledTasks()); + Assert.assertEquals(4, runner.getTaskMonitor().getNumCanceledTasks()); } @Test(timeout = 5000L) @@ -159,7 +159,7 @@ public void testSubTaskFail() throws Exception Assert.assertEquals(TaskState.FAILED, status.getStatusCode()); } - Assert.assertEquals(3, runner.getTaskMonitor().getNumKilledTasks()); + Assert.assertEquals(3, runner.getTaskMonitor().getNumCanceledTasks()); } private ParallelIndexSupervisorTask newTask( diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/batch/parallel/SinglePhaseParallelIndexingTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/batch/parallel/SinglePhaseParallelIndexingTest.java index 0bc1b93de477..a1935630b63a 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/common/task/batch/parallel/SinglePhaseParallelIndexingTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/common/task/batch/parallel/SinglePhaseParallelIndexingTest.java @@ -20,7 +20,6 @@ package org.apache.druid.indexing.common.task.batch.parallel; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import org.apache.druid.client.indexing.IndexingServiceClient; import org.apache.druid.data.input.InputSplit; import org.apache.druid.data.input.impl.LocalInputSource; @@ -182,16 +181,16 @@ private void testRunAndOverwrite(@Nullable Interval inputInterval, Granularity s runTestTask(inputInterval, Granularities.DAY); final Interval interval = inputInterval == null ? Intervals.ETERNITY : inputInterval; - final Collection oldSegments = - getStorageCoordinator().getUsedSegmentsForInterval("dataSource", interval, Segments.ONLY_VISIBLE); + final Collection allSegments = + getStorageCoordinator().retrieveUsedSegmentsForInterval("dataSource", interval, Segments.ONLY_VISIBLE); // Reingest the same data. Each segment should get replaced by a segment with a newer version. runTestTask(inputInterval, secondSegmentGranularity); // Verify that the segment has been replaced. final Collection newSegments = - getStorageCoordinator().getUsedSegmentsForInterval("dataSource", interval, Segments.ONLY_VISIBLE); - Set allSegments = ImmutableSet.builder().addAll(oldSegments).addAll(newSegments).build(); + getStorageCoordinator().retrieveUsedSegmentsForInterval("dataSource", interval, Segments.ONLY_VISIBLE); + allSegments.addAll(newSegments); final VersionedIntervalTimeline timeline = VersionedIntervalTimeline.forSegments(allSegments); final Set visibles = timeline.findNonOvershadowedObjectsInInterval(interval, Partitions.ONLY_COMPLETE); Assert.assertEquals(new HashSet<>(newSegments), visibles); @@ -302,11 +301,11 @@ public void testAppendToExisting() throws Exception final Interval interval = Intervals.of("2017/2018"); runTestTask(interval, Granularities.DAY, true); final Collection oldSegments = - getStorageCoordinator().getUsedSegmentsForInterval("dataSource", interval, Segments.ONLY_VISIBLE); + getStorageCoordinator().retrieveUsedSegmentsForInterval("dataSource", interval, Segments.ONLY_VISIBLE); runTestTask(interval, Granularities.DAY, true); final Collection newSegments = - getStorageCoordinator().getUsedSegmentsForInterval("dataSource", interval, Segments.ONLY_VISIBLE); + getStorageCoordinator().retrieveUsedSegmentsForInterval("dataSource", interval, Segments.ONLY_VISIBLE); Assert.assertTrue(newSegments.containsAll(oldSegments)); final VersionedIntervalTimeline timeline = VersionedIntervalTimeline.forSegments(newSegments); final Set visibles = timeline.findNonOvershadowedObjectsInInterval(interval, Partitions.ONLY_COMPLETE); diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/firehose/IngestSegmentFirehoseFactoryTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/firehose/IngestSegmentFirehoseFactoryTest.java index d4e40781016e..1a786ec2ef78 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/firehose/IngestSegmentFirehoseFactoryTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/firehose/IngestSegmentFirehoseFactoryTest.java @@ -144,7 +144,7 @@ public class IngestSegmentFirehoseFactoryTest private final Set published = new HashSet<>(); @Override - public List getUsedSegmentsForIntervals( + public List retrieveUsedSegmentsForIntervals( String dataSource, List interval, Segments visibility @@ -154,7 +154,7 @@ public List getUsedSegmentsForIntervals( } @Override - public List getUnusedSegmentsForInterval(String dataSource, Interval interval) + public List retrieveUnusedSegmentsForInterval(String dataSource, Interval interval) { return ImmutableList.of(); } @@ -213,7 +213,10 @@ public static Collection constructorFeeder() throws IOException final CoordinatorClient cc = new CoordinatorClient(null, null) { @Override - public Collection getDatabaseSegmentDataSourceSegments(String dataSource, List intervals) + public Collection fetchUsedSegmentsInDataSourceForIntervals( + String dataSource, + List intervals + ) { return ImmutableSet.copyOf(SEGMENT_SET); } diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/firehose/IngestSegmentFirehoseFactoryTimelineTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/firehose/IngestSegmentFirehoseFactoryTimelineTest.java index f78124f386ce..7c2760cafbed 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/firehose/IngestSegmentFirehoseFactoryTimelineTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/firehose/IngestSegmentFirehoseFactoryTimelineTest.java @@ -321,7 +321,10 @@ public static Collection constructorFeeder() final CoordinatorClient cc = new CoordinatorClient(null, null) { @Override - public Collection getDatabaseSegmentDataSourceSegments(String dataSource, List intervals) + public Collection fetchUsedSegmentsInDataSourceForIntervals( + String dataSource, + List intervals + ) { // Expect the interval we asked for if (intervals.equals(ImmutableList.of(testCase.interval))) { @@ -332,7 +335,7 @@ public Collection getDatabaseSegmentDataSourceSegments(String dataS } @Override - public DataSegment getDatabaseSegmentDataSourceSegment(String dataSource, String segmentId) + public DataSegment fetchUsedSegment(String dataSource, String segmentId) { return testCase.segments .stream() diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/overlord/IndexerMetadataStorageAdapterTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/overlord/IndexerMetadataStorageAdapterTest.java index 8cb45ade0f09..4a9c066416c8 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/overlord/IndexerMetadataStorageAdapterTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/overlord/IndexerMetadataStorageAdapterTest.java @@ -81,7 +81,10 @@ public void testDeletePendingSegments() final Interval deleteInterval = Intervals.of("2017-01-01/2017-12-01"); EasyMock .expect( - indexerMetadataStorageCoordinator.deletePendingSegments(EasyMock.anyString(), EasyMock.eq(deleteInterval)) + indexerMetadataStorageCoordinator.deletePendingSegmentsCreatedInInterval( + EasyMock.anyString(), + EasyMock.eq(deleteInterval) + ) ) .andReturn(10); EasyMock.replay(taskStorageQueryAdapter, indexerMetadataStorageCoordinator); @@ -114,7 +117,10 @@ public void testDeletePendingSegmentsOfRunningTasks() final Interval deleteInterval = Intervals.of("2017-01-01/2017-12-01"); EasyMock .expect( - indexerMetadataStorageCoordinator.deletePendingSegments(EasyMock.anyString(), EasyMock.eq(deleteInterval)) + indexerMetadataStorageCoordinator.deletePendingSegmentsCreatedInInterval( + EasyMock.anyString(), + EasyMock.eq(deleteInterval) + ) ) .andReturn(10); EasyMock.replay(taskStorageQueryAdapter, indexerMetadataStorageCoordinator); diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/overlord/TaskLifecycleTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/overlord/TaskLifecycleTest.java index 3dce1974e7e2..e1f18584ab85 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/overlord/TaskLifecycleTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/overlord/TaskLifecycleTest.java @@ -74,7 +74,7 @@ import org.apache.druid.indexing.common.task.IndexTask.IndexIOConfig; import org.apache.druid.indexing.common.task.IndexTask.IndexIngestionSpec; import org.apache.druid.indexing.common.task.IndexTask.IndexTuningConfig; -import org.apache.druid.indexing.common.task.KillTask; +import org.apache.druid.indexing.common.task.KillUnusedSegmentsTask; import org.apache.druid.indexing.common.task.NoopTestTaskReportFileWriter; import org.apache.druid.indexing.common.task.RealtimeIndexTask; import org.apache.druid.indexing.common.task.Task; @@ -862,7 +862,7 @@ public void testIndexTaskFailure() throws Exception } @Test - public void testKillTask() throws Exception + public void testKillUnusedSegmentsTask() throws Exception { final File tmpSegmentDir = temporaryFolder.newFolder(); @@ -915,15 +915,16 @@ public DataSegment apply(String input) // manually create local segments files List segmentFiles = new ArrayList<>(); - for (DataSegment segment : mdc.getUnusedSegmentsForInterval("test_kill_task", Intervals.of("2011-04-01/P4D"))) { + for (DataSegment segment : mdc.retrieveUnusedSegmentsForInterval("test_kill_task", Intervals.of("2011-04-01/P4D"))) { File file = new File((String) segment.getLoadSpec().get("path")); file.mkdirs(); segmentFiles.add(file); } - final Task killTask = new KillTask(null, "test_kill_task", Intervals.of("2011-04-01/P4D"), null); + final Task killUnusedSegmentsTask = + new KillUnusedSegmentsTask(null, "test_kill_task", Intervals.of("2011-04-01/P4D"), null); - final TaskStatus status = runTask(killTask); + final TaskStatus status = runTask(killUnusedSegmentsTask); Assert.assertEquals(taskLocation, status.getLocation()); Assert.assertEquals("merged statusCode", TaskState.SUCCESS, status.getStatusCode()); Assert.assertEquals("num segments published", 0, mdc.getPublished().size()); diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/seekablestream/SeekableStreamIndexTaskTestBase.java b/indexing-service/src/test/java/org/apache/druid/indexing/seekablestream/SeekableStreamIndexTaskTestBase.java index ffb9ff44bdbf..d14769161025 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/seekablestream/SeekableStreamIndexTaskTestBase.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/seekablestream/SeekableStreamIndexTaskTestBase.java @@ -409,7 +409,7 @@ protected void unlockAppenderatorBasePersistDirForTask(SeekableStreamIndexTask t protected List publishedDescriptors() { return metadataStorageCoordinator - .getUsedSegmentsForInterval(OLD_DATA_SCHEMA.getDataSource(), Intervals.of("0000/3000"), Segments.ONLY_VISIBLE) + .retrieveAllUsedSegments(OLD_DATA_SCHEMA.getDataSource(), Segments.ONLY_VISIBLE) .stream() .map(DataSegment::toDescriptor) .collect(Collectors.toList()); diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisorStateTest.java b/indexing-service/src/test/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisorStateTest.java index 3dcd6d9f9a03..57aaec30f062 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisorStateTest.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/seekablestream/supervisor/SeekableStreamSupervisorStateTest.java @@ -146,7 +146,8 @@ public void setupTest() taskRunner.registerListener(EasyMock.anyObject(TaskRunnerListener.class), EasyMock.anyObject(Executor.class)); - EasyMock.expect(indexerMetadataStorageCoordinator.getDataSourceMetadata(DATASOURCE)).andReturn(null).anyTimes(); + EasyMock + .expect(indexerMetadataStorageCoordinator.retrieveDataSourceMetadata(DATASOURCE)).andReturn(null).anyTimes(); EasyMock.expect(recordSupplier.getAssignment()).andReturn(ImmutableSet.of(SHARD0_PARTITION)).anyTimes(); EasyMock.expect(recordSupplier.getLatestSequenceNumber(EasyMock.anyObject())).andReturn("10").anyTimes(); } diff --git a/indexing-service/src/test/java/org/apache/druid/indexing/test/TestIndexerMetadataStorageCoordinator.java b/indexing-service/src/test/java/org/apache/druid/indexing/test/TestIndexerMetadataStorageCoordinator.java index 0a370d5ace41..96562a42125a 100644 --- a/indexing-service/src/test/java/org/apache/druid/indexing/test/TestIndexerMetadataStorageCoordinator.java +++ b/indexing-service/src/test/java/org/apache/druid/indexing/test/TestIndexerMetadataStorageCoordinator.java @@ -52,7 +52,7 @@ public TestIndexerMetadataStorageCoordinator() } @Override - public DataSourceMetadata getDataSourceMetadata(String dataSource) + public DataSourceMetadata retrieveDataSourceMetadata(String dataSource) { throw new UnsupportedOperationException(); } @@ -76,19 +76,29 @@ public boolean insertDataSourceMetadata(String dataSource, DataSourceMetadata da } @Override - public List> getUsedSegmentAndCreatedDateForInterval(String dataSource, Interval interval) + public List retrieveAllUsedSegments(String dataSource, Segments visibility) { return ImmutableList.of(); } - + @Override - public List getUsedSegmentsForIntervals(String dataSource, List intervals, Segments visibility) + public List> retrieveUsedSegmentsAndCreatedDates(String dataSource) { return ImmutableList.of(); } @Override - public List getUnusedSegmentsForInterval(String dataSource, Interval interval) + public List retrieveUsedSegmentsForIntervals( + String dataSource, + List intervals, + Segments visibility + ) + { + return ImmutableList.of(); + } + + @Override + public List retrieveUnusedSegmentsForInterval(String dataSource, Interval interval) { synchronized (unusedSegments) { return ImmutableList.copyOf(unusedSegments); @@ -148,7 +158,13 @@ public SegmentIdWithShardSpec allocatePendingSegment( } @Override - public int deletePendingSegments(String dataSource, Interval deleteInterval) + public int deletePendingSegmentsCreatedInInterval(String dataSource, Interval deleteInterval) + { + throw new UnsupportedOperationException(); + } + + @Override + public int deletePendingSegments(String dataSource) { throw new UnsupportedOperationException(); } diff --git a/integration-tests/src/main/java/org/apache/druid/testing/clients/CoordinatorResourceTestClient.java b/integration-tests/src/main/java/org/apache/druid/testing/clients/CoordinatorResourceTestClient.java index 71ca9f83a4d0..7e0adff62556 100644 --- a/integration-tests/src/main/java/org/apache/druid/testing/clients/CoordinatorResourceTestClient.java +++ b/integration-tests/src/main/java/org/apache/druid/testing/clients/CoordinatorResourceTestClient.java @@ -72,7 +72,7 @@ private String getCoordinatorURL() ); } - private String getMetadataSegmentsURL(String dataSource) + private String getSegmentsMetadataURL(String dataSource) { return StringUtils.format("%smetadata/datasources/%s/segments", getCoordinatorURL(), StringUtils.urlEncode(dataSource)); } @@ -92,12 +92,12 @@ private String getLoadStatusURL() return StringUtils.format("%s%s", getCoordinatorURL(), "loadstatus"); } - // return a list of the segment dates for the specified datasource - public List getMetadataSegments(final String dataSource) + /** return a list of the segment dates for the specified data source */ + public List getSegments(final String dataSource) { List segments; try { - StatusResponseHolder response = makeRequest(HttpMethod.GET, getMetadataSegmentsURL(dataSource)); + StatusResponseHolder response = makeRequest(HttpMethod.GET, getSegmentsMetadataURL(dataSource)); segments = jsonMapper.readValue( response.getContent(), new TypeReference>() diff --git a/integration-tests/src/test/java/org/apache/druid/tests/indexer/ITCompactionTaskTest.java b/integration-tests/src/test/java/org/apache/druid/tests/indexer/ITCompactionTaskTest.java index b1ca281fde40..2c0dbc381d01 100644 --- a/integration-tests/src/test/java/org/apache/druid/tests/indexer/ITCompactionTaskTest.java +++ b/integration-tests/src/test/java/org/apache/druid/tests/indexer/ITCompactionTaskTest.java @@ -126,7 +126,7 @@ private void checkCompactionFinished(int numExpectedSegments) { ITRetryUtil.retryUntilTrue( () -> { - int metadataSegmentCount = coordinator.getMetadataSegments(fullDatasourceName).size(); + int metadataSegmentCount = coordinator.getSegments(fullDatasourceName).size(); LOG.info("Current metadata segment count: %d, expected: %d", metadataSegmentCount, numExpectedSegments); return metadataSegmentCount == numExpectedSegments; }, diff --git a/server/src/main/java/org/apache/druid/client/DataSourcesSnapshot.java b/server/src/main/java/org/apache/druid/client/DataSourcesSnapshot.java index a2cde8eedd6c..1cca2b9aed08 100644 --- a/server/src/main/java/org/apache/druid/client/DataSourcesSnapshot.java +++ b/server/src/main/java/org/apache/druid/client/DataSourcesSnapshot.java @@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; +import org.apache.druid.metadata.SqlSegmentsMetadataManager; import org.apache.druid.timeline.DataSegment; import org.apache.druid.timeline.SegmentId; import org.apache.druid.timeline.VersionedIntervalTimeline; @@ -35,8 +36,8 @@ import java.util.Map; /** - * An immutable snapshot information about used segments and overshadowed segments for - * {@link org.apache.druid.metadata.SQLMetadataSegmentManager}. + * An immutable snapshot of metadata information about used segments and overshadowed segments, coming from + * {@link SqlSegmentsMetadataManager}. */ public class DataSourcesSnapshot { diff --git a/server/src/main/java/org/apache/druid/client/coordinator/CoordinatorClient.java b/server/src/main/java/org/apache/druid/client/coordinator/CoordinatorClient.java index 6cf33bbe48a3..36dba89416b7 100644 --- a/server/src/main/java/org/apache/druid/client/coordinator/CoordinatorClient.java +++ b/server/src/main/java/org/apache/druid/client/coordinator/CoordinatorClient.java @@ -127,7 +127,7 @@ public List fetchServerView(String dataSource, Interva } } - public Collection getDatabaseSegmentDataSourceSegments(String dataSource, List intervals) + public Collection fetchUsedSegmentsInDataSourceForIntervals(String dataSource, List intervals) { try { StringFullResponseHolder response = druidLeaderClient.go( @@ -142,7 +142,7 @@ public Collection getDatabaseSegmentDataSourceSegments(String dataS if (!response.getStatus().equals(HttpResponseStatus.OK)) { throw new ISE( - "Error while fetching database segment data source segments status[%s] content[%s]", + "Error while fetching used segments in a data source for intervals: status[%s] content[%s]", response.getStatus(), response.getContent() ); @@ -158,7 +158,7 @@ public Collection getDatabaseSegmentDataSourceSegments(String dataS } } - public DataSegment getDatabaseSegmentDataSourceSegment(String dataSource, String segmentId) + public DataSegment fetchUsedSegment(String dataSource, String segmentId) { try { StringFullResponseHolder response = druidLeaderClient.go( diff --git a/server/src/main/java/org/apache/druid/client/indexing/ClientCompactionIOConfig.java b/server/src/main/java/org/apache/druid/client/indexing/ClientCompactionIOConfig.java index 2bc66d2f53eb..eec09545ec7f 100644 --- a/server/src/main/java/org/apache/druid/client/indexing/ClientCompactionIOConfig.java +++ b/server/src/main/java/org/apache/druid/client/indexing/ClientCompactionIOConfig.java @@ -25,7 +25,7 @@ import java.util.Objects; /** - * IOConfig for {@link ClientCompactQuery}. + * IOConfig for {@link ClientCompactionTaskQuery}. * * Should be synchronized with org.apache.druid.indexing.common.task.CompactionIOConfig. */ diff --git a/server/src/main/java/org/apache/druid/client/indexing/ClientCompactQuery.java b/server/src/main/java/org/apache/druid/client/indexing/ClientCompactionTaskQuery.java similarity index 88% rename from server/src/main/java/org/apache/druid/client/indexing/ClientCompactQuery.java rename to server/src/main/java/org/apache/druid/client/indexing/ClientCompactionTaskQuery.java index ffb283cfe2c1..fd509a3583b5 100644 --- a/server/src/main/java/org/apache/druid/client/indexing/ClientCompactQuery.java +++ b/server/src/main/java/org/apache/druid/client/indexing/ClientCompactionTaskQuery.java @@ -29,18 +29,18 @@ * Client representation of org.apache.druid.indexing.common.task.CompactionTask. JSON serialization fields of * this class must correspond to those of org.apache.druid.indexing.common.task.CompactionTask. */ -public class ClientCompactQuery implements ClientQuery +public class ClientCompactionTaskQuery implements ClientTaskQuery { private final String dataSource; private final ClientCompactionIOConfig ioConfig; - private final ClientCompactQueryTuningConfig tuningConfig; + private final ClientCompactionTaskQueryTuningConfig tuningConfig; private final Map context; @JsonCreator - public ClientCompactQuery( + public ClientCompactionTaskQuery( @JsonProperty("dataSource") String dataSource, @JsonProperty("ioConfig") ClientCompactionIOConfig ioConfig, - @JsonProperty("tuningConfig") ClientCompactQueryTuningConfig tuningConfig, + @JsonProperty("tuningConfig") ClientCompactionTaskQueryTuningConfig tuningConfig, @JsonProperty("context") Map context ) { @@ -71,7 +71,7 @@ public ClientCompactionIOConfig getIoConfig() } @JsonProperty - public ClientCompactQueryTuningConfig getTuningConfig() + public ClientCompactionTaskQueryTuningConfig getTuningConfig() { return tuningConfig; } @@ -91,7 +91,7 @@ public boolean equals(Object o) if (o == null || getClass() != o.getClass()) { return false; } - ClientCompactQuery that = (ClientCompactQuery) o; + ClientCompactionTaskQuery that = (ClientCompactionTaskQuery) o; return Objects.equals(dataSource, that.dataSource) && Objects.equals(ioConfig, that.ioConfig) && Objects.equals(tuningConfig, that.tuningConfig) && diff --git a/server/src/main/java/org/apache/druid/client/indexing/ClientCompactQueryTuningConfig.java b/server/src/main/java/org/apache/druid/client/indexing/ClientCompactionTaskQueryTuningConfig.java similarity index 92% rename from server/src/main/java/org/apache/druid/client/indexing/ClientCompactQueryTuningConfig.java rename to server/src/main/java/org/apache/druid/client/indexing/ClientCompactionTaskQueryTuningConfig.java index 026c6a746afc..bfee8cfacad3 100644 --- a/server/src/main/java/org/apache/druid/client/indexing/ClientCompactQueryTuningConfig.java +++ b/server/src/main/java/org/apache/druid/client/indexing/ClientCompactionTaskQueryTuningConfig.java @@ -23,20 +23,20 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.druid.data.input.SplitHintSpec; import org.apache.druid.segment.IndexSpec; -import org.apache.druid.server.coordinator.DataSourceCompactionConfig.UserCompactTuningConfig; +import org.apache.druid.server.coordinator.UserCompactionTaskQueryTuningConfig; import javax.annotation.Nullable; import java.util.Objects; -public class ClientCompactQueryTuningConfig +public class ClientCompactionTaskQueryTuningConfig { @Nullable private final Integer maxRowsPerSegment; @Nullable - private final Long maxBytesInMemory; - @Nullable private final Integer maxRowsInMemory; @Nullable + private final Long maxBytesInMemory; + @Nullable private final Long maxTotalRows; @Nullable private final SplitHintSpec splitHintSpec; @@ -49,13 +49,13 @@ public class ClientCompactQueryTuningConfig @Nullable private final Integer maxNumConcurrentSubTasks; - public static ClientCompactQueryTuningConfig from( - @Nullable UserCompactTuningConfig userCompactionTaskQueryTuningConfig, + public static ClientCompactionTaskQueryTuningConfig from( + @Nullable UserCompactionTaskQueryTuningConfig userCompactionTaskQueryTuningConfig, @Nullable Integer maxRowsPerSegment ) { if (userCompactionTaskQueryTuningConfig == null) { - return new ClientCompactQueryTuningConfig( + return new ClientCompactionTaskQueryTuningConfig( maxRowsPerSegment, null, null, @@ -67,7 +67,7 @@ public static ClientCompactQueryTuningConfig from( null ); } else { - return new ClientCompactQueryTuningConfig( + return new ClientCompactionTaskQueryTuningConfig( maxRowsPerSegment, userCompactionTaskQueryTuningConfig.getMaxRowsInMemory(), userCompactionTaskQueryTuningConfig.getMaxBytesInMemory(), @@ -82,7 +82,7 @@ public static ClientCompactQueryTuningConfig from( } @JsonCreator - public ClientCompactQueryTuningConfig( + public ClientCompactionTaskQueryTuningConfig( @JsonProperty("maxRowsPerSegment") @Nullable Integer maxRowsPerSegment, @JsonProperty("maxRowsInMemory") @Nullable Integer maxRowsInMemory, @JsonProperty("maxBytesInMemory") @Nullable Long maxBytesInMemory, @@ -95,8 +95,8 @@ public ClientCompactQueryTuningConfig( ) { this.maxRowsPerSegment = maxRowsPerSegment; - this.maxBytesInMemory = maxBytesInMemory; this.maxRowsInMemory = maxRowsInMemory; + this.maxBytesInMemory = maxBytesInMemory; this.maxTotalRows = maxTotalRows; this.splitHintSpec = splitHintSpec; this.indexSpec = indexSpec; @@ -188,7 +188,7 @@ public boolean equals(Object o) if (o == null || getClass() != o.getClass()) { return false; } - ClientCompactQueryTuningConfig that = (ClientCompactQueryTuningConfig) o; + ClientCompactionTaskQueryTuningConfig that = (ClientCompactionTaskQueryTuningConfig) o; return Objects.equals(maxRowsPerSegment, that.maxRowsPerSegment) && Objects.equals(maxBytesInMemory, that.maxBytesInMemory) && Objects.equals(maxRowsInMemory, that.maxRowsInMemory) && @@ -221,8 +221,8 @@ public String toString() { return "ClientCompactQueryTuningConfig{" + "maxRowsPerSegment=" + maxRowsPerSegment + - ", maxBytesInMemory=" + maxBytesInMemory + ", maxRowsInMemory=" + maxRowsInMemory + + ", maxBytesInMemory=" + maxBytesInMemory + ", maxTotalRows=" + maxTotalRows + ", splitHintSpec=" + splitHintSpec + ", indexSpec=" + indexSpec + diff --git a/server/src/main/java/org/apache/druid/client/indexing/ClientKillQuery.java b/server/src/main/java/org/apache/druid/client/indexing/ClientKillUnusedSegmentsTaskQuery.java similarity index 83% rename from server/src/main/java/org/apache/druid/client/indexing/ClientKillQuery.java rename to server/src/main/java/org/apache/druid/client/indexing/ClientKillUnusedSegmentsTaskQuery.java index 583dee506cda..f5851ba273be 100644 --- a/server/src/main/java/org/apache/druid/client/indexing/ClientKillQuery.java +++ b/server/src/main/java/org/apache/druid/client/indexing/ClientKillUnusedSegmentsTaskQuery.java @@ -24,17 +24,17 @@ import org.joda.time.Interval; /** - * Client representation of org.apache.druid.indexing.common.task.KillTask. JSON searialization - * fields of this class must correspond to those of - * org.apache.druid.indexing.common.task.KillTask, except for "id" and "context" fields. + * Client representation of org.apache.druid.indexing.common.task.KillUnusedSegmentsTask. JSON searialization + * fields of this class must correspond to those of org.apache.druid.indexing.common.task.KillUnusedSegmentsTask, except + * for "id" and "context" fields. */ -public class ClientKillQuery implements ClientQuery +public class ClientKillUnusedSegmentsTaskQuery implements ClientTaskQuery { private final String dataSource; private final Interval interval; @JsonCreator - public ClientKillQuery( + public ClientKillUnusedSegmentsTaskQuery( @JsonProperty("dataSource") String dataSource, @JsonProperty("interval") Interval interval ) diff --git a/server/src/main/java/org/apache/druid/client/indexing/ClientQuery.java b/server/src/main/java/org/apache/druid/client/indexing/ClientTaskQuery.java similarity index 87% rename from server/src/main/java/org/apache/druid/client/indexing/ClientQuery.java rename to server/src/main/java/org/apache/druid/client/indexing/ClientTaskQuery.java index 306d6e7c0cb2..e57e30903abb 100644 --- a/server/src/main/java/org/apache/druid/client/indexing/ClientQuery.java +++ b/server/src/main/java/org/apache/druid/client/indexing/ClientTaskQuery.java @@ -28,15 +28,15 @@ * at the moment of making a REST query: {@link HttpIndexingServiceClient#runTask} serializes ClientTaskQuery * objects and org.apache.druid.indexing.overlord.http.OverlordResource.taskPost() deserializes * org.apache.druid.indexing.common.task.Task objects from the same bytes. Therefore JSON serialization fields of - * ClientTaskQuery objects must match with those of the corresponding - * org.apache.druid.indexing.common.task.Task objects. + * ClientTaskQuery objects must match with those of the corresponding org.apache.druid.indexing.common.task.Task + * objects. */ @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") @JsonSubTypes(value = { - @Type(name = "kill", value = ClientKillQuery.class), - @Type(name = "compact", value = ClientCompactQuery.class) + @Type(name = "kill", value = ClientKillUnusedSegmentsTaskQuery.class), + @Type(name = "compact", value = ClientCompactionTaskQuery.class) }) -public interface ClientQuery +public interface ClientTaskQuery { String getType(); diff --git a/server/src/main/java/org/apache/druid/client/indexing/HttpIndexingServiceClient.java b/server/src/main/java/org/apache/druid/client/indexing/HttpIndexingServiceClient.java index 38e2501a4ad8..9e69b719f05e 100644 --- a/server/src/main/java/org/apache/druid/client/indexing/HttpIndexingServiceClient.java +++ b/server/src/main/java/org/apache/druid/client/indexing/HttpIndexingServiceClient.java @@ -65,16 +65,16 @@ public HttpIndexingServiceClient( } @Override - public void killSegments(String dataSource, Interval interval) + public void killUnusedSegments(String dataSource, Interval interval) { - runTask(new ClientKillQuery(dataSource, interval)); + runTask(new ClientKillUnusedSegmentsTaskQuery(dataSource, interval)); } @Override public String compactSegments( List segments, int compactionTaskPriority, - ClientCompactQueryTuningConfig tuningConfig, + ClientCompactionTaskQueryTuningConfig tuningConfig, @Nullable Map context ) { @@ -90,7 +90,7 @@ public String compactSegments( context.put("priority", compactionTaskPriority); return runTask( - new ClientCompactQuery( + new ClientCompactionTaskQuery( dataSource, new ClientCompactionIOConfig(ClientCompactionIntervalSpec.fromSegments(segments)), tuningConfig, @@ -103,6 +103,8 @@ public String compactSegments( public String runTask(Object taskObject) { try { + // Warning, magic: here we may serialize ClientTaskQuery objects, but OverlordResource.taskPost() deserializes + // Task objects from the same data. See the comment for ClientTaskQuery for details. final StringFullResponseHolder response = druidLeaderClient.go( druidLeaderClient.makeRequest(HttpMethod.POST, "/druid/indexer/v1/task") .setContent(MediaType.APPLICATION_JSON, jsonMapper.writeValueAsBytes(taskObject)) @@ -133,7 +135,7 @@ public String runTask(Object taskObject) } @Override - public String killTask(String taskId) + public String cancelTask(String taskId) { try { final StringFullResponseHolder response = druidLeaderClient.go( @@ -144,22 +146,22 @@ public String killTask(String taskId) ); if (!response.getStatus().equals(HttpResponseStatus.OK)) { - throw new ISE("Failed to kill task[%s]", taskId); + throw new ISE("Failed to cancel task[%s]", taskId); } final Map resultMap = jsonMapper.readValue( response.getContent(), JacksonUtils.TYPE_REFERENCE_MAP_STRING_OBJECT ); - final String killedTaskId = (String) resultMap.get("task"); - Preconditions.checkNotNull(killedTaskId, "Null task id returned for task[%s]", taskId); + final String cancelledTaskId = (String) resultMap.get("task"); + Preconditions.checkNotNull(cancelledTaskId, "Null task id returned for task[%s]", taskId); Preconditions.checkState( - taskId.equals(killedTaskId), - "Requested to kill task[%s], but another task[%s] was killed!", + taskId.equals(cancelledTaskId), + "Requested to cancel task[%s], but another task[%s] was cancelled!", taskId, - killedTaskId + cancelledTaskId ); - return killedTaskId; + return cancelledTaskId; } catch (Exception e) { throw new RuntimeException(e); diff --git a/server/src/main/java/org/apache/druid/client/indexing/IndexingServiceClient.java b/server/src/main/java/org/apache/druid/client/indexing/IndexingServiceClient.java index 4843d9ff7063..43c38884d39c 100644 --- a/server/src/main/java/org/apache/druid/client/indexing/IndexingServiceClient.java +++ b/server/src/main/java/org/apache/druid/client/indexing/IndexingServiceClient.java @@ -31,14 +31,14 @@ public interface IndexingServiceClient { - void killSegments(String dataSource, Interval interval); + void killUnusedSegments(String dataSource, Interval interval); int killPendingSegments(String dataSource, DateTime end); String compactSegments( List segments, int compactionTaskPriority, - @Nullable ClientCompactQueryTuningConfig tuningConfig, + @Nullable ClientCompactionTaskQueryTuningConfig tuningConfig, @Nullable Map context ); @@ -46,7 +46,7 @@ String compactSegments( String runTask(Object taskObject); - String killTask(String taskId); + String cancelTask(String taskId); /** * Gets all tasks that are waiting, pending, or running. diff --git a/server/src/main/java/org/apache/druid/client/indexing/TaskPayloadResponse.java b/server/src/main/java/org/apache/druid/client/indexing/TaskPayloadResponse.java index 1b938af32626..45249593aa2f 100644 --- a/server/src/main/java/org/apache/druid/client/indexing/TaskPayloadResponse.java +++ b/server/src/main/java/org/apache/druid/client/indexing/TaskPayloadResponse.java @@ -25,12 +25,12 @@ public class TaskPayloadResponse { private final String task; - private final ClientQuery payload; + private final ClientTaskQuery payload; @JsonCreator public TaskPayloadResponse( @JsonProperty("task") final String task, - @JsonProperty("payload") final ClientQuery payload + @JsonProperty("payload") final ClientTaskQuery payload ) { this.task = task; @@ -44,7 +44,7 @@ public String getTask() } @JsonProperty - public ClientQuery getPayload() + public ClientTaskQuery getPayload() { return payload; } diff --git a/server/src/main/java/org/apache/druid/guice/MetadataConfigModule.java b/server/src/main/java/org/apache/druid/guice/MetadataConfigModule.java index 99545650dc76..ccff6dd2870a 100644 --- a/server/src/main/java/org/apache/druid/guice/MetadataConfigModule.java +++ b/server/src/main/java/org/apache/druid/guice/MetadataConfigModule.java @@ -22,9 +22,9 @@ import com.google.inject.Binder; import com.google.inject.Module; import org.apache.druid.metadata.MetadataRuleManagerConfig; -import org.apache.druid.metadata.MetadataSegmentManagerConfig; import org.apache.druid.metadata.MetadataStorageConnectorConfig; import org.apache.druid.metadata.MetadataStorageTablesConfig; +import org.apache.druid.metadata.SegmentsMetadataManagerConfig; public class MetadataConfigModule implements Module { @@ -34,7 +34,7 @@ public void configure(Binder binder) JsonConfigProvider.bind(binder, "druid.metadata.storage.tables", MetadataStorageTablesConfig.class); JsonConfigProvider.bind(binder, "druid.metadata.storage.connector", MetadataStorageConnectorConfig.class); - JsonConfigProvider.bind(binder, "druid.manager.segments", MetadataSegmentManagerConfig.class); + JsonConfigProvider.bind(binder, "druid.manager.segments", SegmentsMetadataManagerConfig.class); JsonConfigProvider.bind(binder, "druid.manager.rules", MetadataRuleManagerConfig.class); } } diff --git a/server/src/main/java/org/apache/druid/guice/SQLMetadataStorageDruidModule.java b/server/src/main/java/org/apache/druid/guice/SQLMetadataStorageDruidModule.java index 955ab6bb4be4..6bfe1e25eedc 100644 --- a/server/src/main/java/org/apache/druid/guice/SQLMetadataStorageDruidModule.java +++ b/server/src/main/java/org/apache/druid/guice/SQLMetadataStorageDruidModule.java @@ -29,8 +29,6 @@ import org.apache.druid.metadata.IndexerSQLMetadataStorageCoordinator; import org.apache.druid.metadata.MetadataRuleManager; import org.apache.druid.metadata.MetadataRuleManagerProvider; -import org.apache.druid.metadata.MetadataSegmentManager; -import org.apache.druid.metadata.MetadataSegmentManagerProvider; import org.apache.druid.metadata.MetadataSegmentPublisher; import org.apache.druid.metadata.MetadataSegmentPublisherProvider; import org.apache.druid.metadata.MetadataStorageActionHandlerFactory; @@ -40,11 +38,13 @@ import org.apache.druid.metadata.SQLMetadataConnector; import org.apache.druid.metadata.SQLMetadataRuleManager; import org.apache.druid.metadata.SQLMetadataRuleManagerProvider; -import org.apache.druid.metadata.SQLMetadataSegmentManager; -import org.apache.druid.metadata.SQLMetadataSegmentManagerProvider; import org.apache.druid.metadata.SQLMetadataSegmentPublisher; import org.apache.druid.metadata.SQLMetadataSegmentPublisherProvider; import org.apache.druid.metadata.SQLMetadataSupervisorManager; +import org.apache.druid.metadata.SegmentsMetadataManager; +import org.apache.druid.metadata.SegmentsMetadataManagerProvider; +import org.apache.druid.metadata.SqlSegmentsMetadataManager; +import org.apache.druid.metadata.SqlSegmentsMetadataManagerProvider; import org.apache.druid.server.audit.AuditManagerProvider; import org.apache.druid.server.audit.SQLAuditManager; import org.apache.druid.server.audit.SQLAuditManagerConfig; @@ -73,8 +73,8 @@ public void createBindingChoices(Binder binder, String defaultValue) PolyBind.createChoiceWithDefault(binder, prop, Key.get(MetadataStorageProvider.class), defaultValue); PolyBind.createChoiceWithDefault(binder, prop, Key.get(SQLMetadataConnector.class), defaultValue); - PolyBind.createChoiceWithDefault(binder, prop, Key.get(MetadataSegmentManager.class), defaultValue); - PolyBind.createChoiceWithDefault(binder, prop, Key.get(MetadataSegmentManagerProvider.class), defaultValue); + PolyBind.createChoiceWithDefault(binder, prop, Key.get(SegmentsMetadataManager.class), defaultValue); + PolyBind.createChoiceWithDefault(binder, prop, Key.get(SegmentsMetadataManagerProvider.class), defaultValue); PolyBind.createChoiceWithDefault(binder, prop, Key.get(MetadataRuleManager.class), defaultValue); PolyBind.createChoiceWithDefault(binder, prop, Key.get(MetadataRuleManagerProvider.class), defaultValue); PolyBind.createChoiceWithDefault(binder, prop, Key.get(MetadataSegmentPublisher.class), defaultValue); @@ -90,14 +90,14 @@ public void createBindingChoices(Binder binder, String defaultValue) @Override public void configure(Binder binder) { - PolyBind.optionBinder(binder, Key.get(MetadataSegmentManager.class)) + PolyBind.optionBinder(binder, Key.get(SegmentsMetadataManager.class)) .addBinding(type) - .to(SQLMetadataSegmentManager.class) + .to(SqlSegmentsMetadataManager.class) .in(LazySingleton.class); - PolyBind.optionBinder(binder, Key.get(MetadataSegmentManagerProvider.class)) + PolyBind.optionBinder(binder, Key.get(SegmentsMetadataManagerProvider.class)) .addBinding(type) - .to(SQLMetadataSegmentManagerProvider.class) + .to(SqlSegmentsMetadataManagerProvider.class) .in(LazySingleton.class); PolyBind.optionBinder(binder, Key.get(MetadataRuleManager.class)) diff --git a/server/src/main/java/org/apache/druid/guice/annotations/CoordinatorIndexingServiceHelper.java b/server/src/main/java/org/apache/druid/guice/annotations/CoordinatorIndexingServiceDuty.java similarity index 95% rename from server/src/main/java/org/apache/druid/guice/annotations/CoordinatorIndexingServiceHelper.java rename to server/src/main/java/org/apache/druid/guice/annotations/CoordinatorIndexingServiceDuty.java index c9bfc0cabc21..75075ab53647 100644 --- a/server/src/main/java/org/apache/druid/guice/annotations/CoordinatorIndexingServiceHelper.java +++ b/server/src/main/java/org/apache/druid/guice/annotations/CoordinatorIndexingServiceDuty.java @@ -31,6 +31,6 @@ @BindingAnnotation @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) -public @interface CoordinatorIndexingServiceHelper +public @interface CoordinatorIndexingServiceDuty { } diff --git a/server/src/main/java/org/apache/druid/indexing/overlord/IndexerMetadataStorageCoordinator.java b/server/src/main/java/org/apache/druid/indexing/overlord/IndexerMetadataStorageCoordinator.java index 356223aacf33..0277a25c7625 100644 --- a/server/src/main/java/org/apache/druid/indexing/overlord/IndexerMetadataStorageCoordinator.java +++ b/server/src/main/java/org/apache/druid/indexing/overlord/IndexerMetadataStorageCoordinator.java @@ -37,14 +37,14 @@ public interface IndexerMetadataStorageCoordinator { /** - * Get all published segments which may include any data in the interval and are marked as used. + * Retrieve all published segments which may include any data in the interval and are marked as used from the + * metadata store. * * The order of segments within the returned collection is unspecified, but each segment is guaranteed to appear in * the collection only once. * - * @param dataSource The datasource to query - * @param interval The interval for which all applicable and used datasources are requested. Start is inclusive, - * end is exclusive + * @param dataSource The data source to query + * @param interval The interval for which all applicable and used segmented are requested. * @param visibility Whether only visible or visible as well as overshadowed segments should be returned. The * visibility is considered within the specified interval: that is, a segment which is visible * outside of the specified interval, but overshadowed within the specified interval will not be @@ -58,45 +58,80 @@ public interface IndexerMetadataStorageCoordinator * {@link java.util.HashSet} or {@link com.google.common.collect.ImmutableSet} which may in turn be unnecessary in * other use cases. So clients should perform such copy themselves if they need {@link Set} semantics. */ - default Collection getUsedSegmentsForInterval(String dataSource, Interval interval, Segments visibility) + default Collection retrieveUsedSegmentsForInterval( + String dataSource, + Interval interval, + Segments visibility + ) { - return getUsedSegmentsForIntervals(dataSource, Collections.singletonList(interval), visibility); + return retrieveUsedSegmentsForIntervals(dataSource, Collections.singletonList(interval), visibility); } /** - * Get all published segments which are marked as used and the created_date of these segments in a given datasource - * and interval. + * Retrieve all published used segments in the data source from the metadata store. + * + * @param dataSource The data source to query + * + * @return all segments belonging to the given data source + * @see #retrieveUsedSegmentsForInterval(String, Interval, Segments) similar to this method but also accepts data + * interval. + */ + Collection retrieveAllUsedSegments(String dataSource, Segments visibility); + + /** + * Retrieve all published segments which are marked as used and the created_date of these segments belonging to the + * given data source from the metadata store. + * + * Unlike other similar methods in this interface, this method doesn't accept a {@link Segments} "visibility" + * parameter. The returned collection may include overshadowed segments and their created_dates, as if {@link + * Segments#INCLUDING_OVERSHADOWED} was passed. It's the responsibility of the caller to filter out overshadowed ones + * if needed. * - * @param dataSource The datasource to query - * @param interval The interval for which all applicable and used datasources are requested. Start is inclusive, - * end is exclusive + * @param dataSource The data source to query * - * @return The DataSegments and the related created_date of segments which include data in the requested interval + * @return The DataSegments and the related created_date of segments */ - Collection> getUsedSegmentAndCreatedDateForInterval(String dataSource, Interval interval); + Collection> retrieveUsedSegmentsAndCreatedDates(String dataSource); /** - * Get all published segments which may include any data in the interval and are marked as used. + * Retrieve all published segments which may include any data in the given intervals and are marked as used from the + * metadata store. * * The order of segments within the returned collection is unspecified, but each segment is guaranteed to appear in * the collection only once. * - * @param dataSource The datasource to query - * @param intervals The intervals for which all applicable and used datasources are requested. + * @param dataSource The data source to query + * @param intervals The intervals for which all applicable and used segments are requested. * @param visibility Whether only visible or visible as well as overshadowed segments should be returned. The * visibility is considered within the specified intervals: that is, a segment which is visible * outside of the specified intervals, but overshadowed on the specified intervals will not be * returned if {@link Segments#ONLY_VISIBLE} is passed. See more precise description in the doc for * {@link Segments}. * @return The DataSegments which include data in the requested intervals. These segments may contain data outside the - * requested interval. + * requested intervals. * * @implNote This method doesn't return a {@link Set} because there may be an expectation that {@code Set.contains()} * is O(1) operation, while it's not the case for the returned collection unless it copies all segments into a new * {@link java.util.HashSet} or {@link com.google.common.collect.ImmutableSet} which may in turn be unnecessary in * other use cases. So clients should perform such copy themselves if they need {@link Set} semantics. */ - Collection getUsedSegmentsForIntervals(String dataSource, List intervals, Segments visibility); + Collection retrieveUsedSegmentsForIntervals( + String dataSource, + List intervals, + Segments visibility + ); + + /** + * Retrieve all published segments which include ONLY data within the given interval and are marked as unused from the + * metadata store. + * + * @param dataSource The data source the segments belong to + * @param interval Filter the data segments to ones that include data in this interval exclusively. + * + * @return DataSegments which include ONLY data within the requested interval and are marked as unused. Segments NOT + * returned here may include data in the interval + */ + List retrieveUnusedSegmentsForInterval(String dataSource, Interval interval); /** * Attempts to insert a set of segments to the metadata storage. Returns the set of segments actually added (segments @@ -119,12 +154,13 @@ default Collection getUsedSegmentsForInterval(String dataSource, In * * @param dataSource dataSource for which to allocate a segment * @param sequenceName name of the group of ingestion tasks producing a segment series - * @param previousSegmentId previous segment in the series; may be null or empty, meaning this is the first segment + * @param previousSegmentId previous segment in the series; may be null or empty, meaning this is the first + * segment * @param interval interval for which to allocate a segment * @param shardSpecFactory shardSpecFactory containing all necessary information to create a shardSpec for the * new segmentId - * @param maxVersion use this version if we have no better version to use. The returned segment identifier may - * have a version lower than this one, but will not have one higher. + * @param maxVersion use this version if we have no better version to use. The returned segment + * identifier may have a version lower than this one, but will not have one higher. * @param skipSegmentLineageCheck if true, perform lineage validation using previousSegmentId for this sequence. * Should be set to false if replica tasks would index events in same order * @@ -141,15 +177,28 @@ SegmentIdWithShardSpec allocatePendingSegment( ); /** - * Delete pending segments created in the given interval for the given dataSource from the pending segments table. - * The {@code created_date} field of the pending segments table is checked to find segments to be deleted. + * Delete pending segments created in the given interval belonging to the given data source from the pending segments + * table. The {@code created_date} field of the pending segments table is checked to find segments to be deleted. + * + * Note that the semantic of the interval (for `created_date`s) is different from the semantic of the interval + * parameters in some other methods in this class, such as {@link #retrieveUsedSegmentsForInterval} (where the + * interval is about the time column value in rows belonging to the segment). * * @param dataSource dataSource * @param deleteInterval interval to check the {@code created_date} of pendingSegments * * @return number of deleted pending segments */ - int deletePendingSegments(String dataSource, Interval deleteInterval); + int deletePendingSegmentsCreatedInInterval(String dataSource, Interval deleteInterval); + + /** + * Delete all pending segments belonging to the given data source from the pending segments table. + * + * @return number of deleted pending segments + * @see #deletePendingSegmentsCreatedInInterval(String, Interval) similar to this method but also accepts interval for + * segments' `created_date`s + */ + int deletePendingSegments(String dataSource); /** * Attempts to insert a set of segments to the metadata storage. Returns the set of segments actually added (segments @@ -180,36 +229,9 @@ SegmentPublishResult announceHistoricalSegments( ) throws IOException; /** - * Similar to {@link #announceHistoricalSegments(Set)}, but meant for streaming ingestion tasks for handling - * the case where the task ingested no records and created no segments, but still needs to update the metadata - * with the progress that the task made. - * - * The metadata should undergo the same validation checks as performed by announceHistoricalSegments. - * - * - * @param dataSource the datasource - * @param startMetadata dataSource metadata pre-insert must match this startMetadata according to - * {@link DataSourceMetadata#matches(DataSourceMetadata)}. - * @param endMetadata dataSource metadata post-insert will have this endMetadata merged in with - * {@link DataSourceMetadata#plus(DataSourceMetadata)}. - * - * @return segment publish result indicating transaction success or failure. - * This method must only return a failure code if it is sure that the transaction did not happen. If it is not sure, - * it must throw an exception instead. - * - * @throws IllegalArgumentException if either startMetadata and endMetadata are null - * @throws RuntimeException if the state of metadata storage after this call is unknown - */ - SegmentPublishResult commitMetadataOnly( - String dataSource, - DataSourceMetadata startMetadata, - DataSourceMetadata endMetadata - ); - - /** - * Read dataSource metadata. Returns null if there is no metadata. + * Retrieves data source's metadata from the metadata store. Returns null if there is no metadata. */ - DataSourceMetadata getDataSourceMetadata(String dataSource); + @Nullable DataSourceMetadata retrieveDataSourceMetadata(String dataSource); /** * Removes entry for 'dataSource' from the dataSource metadata table. @@ -240,19 +262,34 @@ SegmentPublishResult commitMetadataOnly( */ boolean insertDataSourceMetadata(String dataSource, DataSourceMetadata dataSourceMetadata); - void updateSegmentMetadata(Set segments); - - void deleteSegments(Set segments); - /** - * Get all published segments which include ONLY data within the given interval and are not marked as used. + * Similar to {@link #announceHistoricalSegments(Set)}, but meant for streaming ingestion tasks for handling + * the case where the task ingested no records and created no segments, but still needs to update the metadata + * with the progress that the task made. + * + * The metadata should undergo the same validation checks as performed by {@link #announceHistoricalSegments}. + * + * + * @param dataSource the datasource + * @param startMetadata dataSource metadata pre-insert must match this startMetadata according to + * {@link DataSourceMetadata#matches(DataSourceMetadata)}. + * @param endMetadata dataSource metadata post-insert will have this endMetadata merged in with + * {@link DataSourceMetadata#plus(DataSourceMetadata)}. * - * @param dataSource The datasource the segments belong to - * @param interval Filter the data segments to ones that include data in this interval exclusively. Start is - * inclusive, end is exclusive + * @return segment publish result indicating transaction success or failure. + * This method must only return a failure code if it is sure that the transaction did not happen. If it is not sure, + * it must throw an exception instead. * - * @return DataSegments which include ONLY data within the requested interval and are not marked as used. - * Data segments NOT returned here may include data in the interval + * @throws IllegalArgumentException if either startMetadata and endMetadata are null + * @throws RuntimeException if the state of metadata storage after this call is unknown */ - List getUnusedSegmentsForInterval(String dataSource, Interval interval); + SegmentPublishResult commitMetadataOnly( + String dataSource, + DataSourceMetadata startMetadata, + DataSourceMetadata endMetadata + ); + + void updateSegmentMetadata(Set segments); + + void deleteSegments(Set segments); } diff --git a/server/src/main/java/org/apache/druid/metadata/IndexerSQLMetadataStorageCoordinator.java b/server/src/main/java/org/apache/druid/metadata/IndexerSQLMetadataStorageCoordinator.java index ad6221330508..2f638c90b23a 100644 --- a/server/src/main/java/org/apache/druid/metadata/IndexerSQLMetadataStorageCoordinator.java +++ b/server/src/main/java/org/apache/druid/metadata/IndexerSQLMetadataStorageCoordinator.java @@ -52,7 +52,6 @@ import org.apache.druid.timeline.partition.ShardSpec; import org.apache.druid.timeline.partition.ShardSpecFactory; import org.joda.time.Interval; -import org.skife.jdbi.v2.FoldController; import org.skife.jdbi.v2.Folder3; import org.skife.jdbi.v2.Handle; import org.skife.jdbi.v2.Query; @@ -70,6 +69,7 @@ import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; @@ -116,10 +116,31 @@ public void start() } @Override - public Collection getUsedSegmentsForIntervals( + public Collection retrieveUsedSegmentsForIntervals( final String dataSource, final List intervals, - Segments visibility + final Segments visibility + ) + { + if (intervals == null || intervals.isEmpty()) { + throw new IAE("null/empty intervals"); + } + return doRetrieveUsedSegments(dataSource, intervals, visibility); + } + + @Override + public Collection retrieveAllUsedSegments(String dataSource, Segments visibility) + { + return doRetrieveUsedSegments(dataSource, Collections.emptyList(), visibility); + } + + /** + * @param intervals empty list means unrestricted interval. + */ + private Collection doRetrieveUsedSegments( + final String dataSource, + final List intervals, + final Segments visibility ) { return connector.retryWithHandle( @@ -129,12 +150,70 @@ public Collection getUsedSegmentsForIntervals( getTimelineForIntervalsWithHandle(handle, dataSource, intervals); return timeline.findNonOvershadowedObjectsInInterval(Intervals.ETERNITY, Partitions.ONLY_COMPLETE); } else { - return getAllUsedSegmentsForIntervalsWithHandle(handle, dataSource, intervals); + return retrieveAllUsedSegmentsForIntervalsWithHandle(handle, dataSource, intervals); } } ); } + @Override + public List> retrieveUsedSegmentsAndCreatedDates(String dataSource) + { + String rawQueryString = "SELECT created_date, payload FROM %1$s WHERE dataSource = :dataSource AND used = true"; + final String queryString = StringUtils.format(rawQueryString, dbTables.getSegmentsTable()); + return connector.retryWithHandle( + handle -> { + Query> query = handle + .createQuery(queryString) + .bind("dataSource", dataSource); + return query + .map((int index, ResultSet r, StatementContext ctx) -> + new Pair<>( + JacksonUtils.readValue(jsonMapper, r.getBytes("payload"), DataSegment.class), + r.getString("created_date") + ) + ) + .list(); + } + ); + } + + @Override + public List retrieveUnusedSegmentsForInterval(final String dataSource, final Interval interval) + { + List matchingSegments = connector.inReadOnlyTransaction( + (handle, status) -> { + // 2 range conditions are used on different columns, but not all SQL databases properly optimize it. + // Some databases can only use an index on one of the columns. An additional condition provides + // explicit knowledge that 'start' cannot be greater than 'end'. + return handle + .createQuery( + StringUtils.format( + "SELECT payload FROM %1$s WHERE dataSource = :dataSource and start >= :start " + + "and start <= :end and %2$send%2$s <= :end and used = false", + dbTables.getSegmentsTable(), + connector.getQuoteString() + ) + ) + .setFetchSize(connector.getStreamingFetchSize()) + .bind("dataSource", dataSource) + .bind("start", interval.getStart().toString()) + .bind("end", interval.getEnd().toString()) + .map(ByteArrayMapper.FIRST) + .fold( + new ArrayList<>(), + (Folder3, byte[]>) (accumulator, payload, foldController, statementContext) -> { + accumulator.add(JacksonUtils.readValue(jsonMapper, payload, DataSegment.class)); + return accumulator; + } + ); + } + ); + + log.info("Found %,d segments for %s for interval %s.", matchingSegments.size(), dataSource, interval); + return matchingSegments; + } + private List getPendingSegmentsForIntervalWithHandle( final Handle handle, final String dataSource, @@ -185,7 +264,7 @@ private VersionedIntervalTimeline getTimelineForIntervalsWi } } - private Collection getAllUsedSegmentsForIntervalsWithHandle( + private Collection retrieveAllUsedSegmentsForIntervalsWithHandle( final Handle handle, final String dataSource, final List intervals @@ -206,29 +285,25 @@ private Query> createUsedSegmentsSqlQueryForIntervals( List intervals ) { - if (intervals == null || intervals.isEmpty()) { - throw new IAE("null/empty intervals"); - } - final StringBuilder sb = new StringBuilder(); - sb.append("SELECT payload FROM %s WHERE used = true AND dataSource = ? AND ("); - for (int i = 0; i < intervals.size(); i++) { - sb.append( - StringUtils.format("(start < ? AND %1$send%1$s > ?)", connector.getQuoteString()) - ); - if (i == intervals.size() - 1) { - sb.append(")"); - } else { - sb.append(" OR "); + sb.append("SELECT payload FROM %s WHERE used = true AND dataSource = ?"); + if (!intervals.isEmpty()) { + sb.append(" AND ("); + for (int i = 0; i < intervals.size(); i++) { + sb.append( + StringUtils.format("(start < ? AND %1$send%1$s > ?)", connector.getQuoteString()) + ); + if (i == intervals.size() - 1) { + sb.append(")"); + } else { + sb.append(" OR "); + } } } - Query> sql = handle.createQuery( - StringUtils.format( - sb.toString(), - dbTables.getSegmentsTable() - ) - ).bind(0, dataSource); + Query> sql = handle + .createQuery(StringUtils.format(sb.toString(), dbTables.getSegmentsTable())) + .bind(0, dataSource); for (int i = 0; i < intervals.size(); i++) { Interval interval = intervals.get(i); @@ -239,14 +314,6 @@ private Query> createUsedSegmentsSqlQueryForIntervals( return sql; } - /** - * Attempts to insert a set of segments to the database. Returns the set of segments actually added (segments - * with identifiers already in the database will not be added). - * - * @param segments set of segments to add - * - * @return set of segments actually added - */ @Override public Set announceHistoricalSegments(final Set segments) throws IOException { @@ -696,8 +763,10 @@ private void insertToMetastore( { handle.createStatement( StringUtils.format( - "INSERT INTO %1$s (id, dataSource, created_date, start, %2$send%2$s, sequence_name, sequence_prev_id, sequence_name_prev_id_sha1, payload) " - + "VALUES (:id, :dataSource, :created_date, :start, :end, :sequence_name, :sequence_prev_id, :sequence_name_prev_id_sha1, :payload)", + "INSERT INTO %1$s (id, dataSource, created_date, start, %2$send%2$s, sequence_name, sequence_prev_id, " + + "sequence_name_prev_id_sha1, payload) " + + "VALUES (:id, :dataSource, :created_date, :start, :end, :sequence_name, :sequence_prev_id, " + + ":sequence_name_prev_id_sha1, :payload)", dbTables.getPendingSegmentsTable(), connector.getQuoteString() ) @@ -754,14 +823,15 @@ private SegmentIdWithShardSpec createNewSegment( if (!existingChunks.isEmpty()) { TimelineObjectHolder existingHolder = Iterables.getOnlyElement(existingChunks); - maxId = StreamSupport.stream(existingHolder.getObject().spliterator(), false) - // Here we check only the segments of the same shardSpec to find out the max partitionId. - // Note that OverwriteShardSpec has the higher range for partitionId than others. - // See PartitionIds. - .filter(chunk -> chunk.getObject().getShardSpec().getClass() == shardSpecFactory.getShardSpecClass()) - .max(Comparator.comparing(chunk -> chunk.getObject().getShardSpec().getPartitionNum())) - .map(chunk -> SegmentIdWithShardSpec.fromDataSegment(chunk.getObject())) - .orElse(null); + maxId = StreamSupport + .stream(existingHolder.getObject().spliterator(), false) + // Here we check only the segments of the same shardSpec to find out the max partitionId. + // Note that OverwriteShardSpec has the higher range for partitionId than others. + // See PartitionIds. + .filter(chunk -> chunk.getObject().getShardSpec().getClass() == shardSpecFactory.getShardSpecClass()) + .max(Comparator.comparing(chunk -> chunk.getObject().getShardSpec().getPartitionNum())) + .map(chunk -> SegmentIdWithShardSpec.fromDataSegment(chunk.getObject())) + .orElse(null); } final List pendings = getPendingSegmentsForIntervalWithHandle( @@ -798,7 +868,8 @@ private SegmentIdWithShardSpec createNewSegment( if (maxId == null) { final ShardSpec shardSpec = shardSpecFactory.create(jsonMapper, null); - return new SegmentIdWithShardSpec(dataSource, interval, versionOfExistingChunks == null ? maxVersion : versionOfExistingChunks, shardSpec); + String version = versionOfExistingChunks == null ? maxVersion : versionOfExistingChunks; + return new SegmentIdWithShardSpec(dataSource, interval, version, shardSpec); } else if (!maxId.getInterval().equals(interval) || maxId.getVersion().compareTo(maxVersion) > 0) { log.warn( "Cannot allocate new segment for dataSource[%s], interval[%s], maxVersion[%s]: conflicting segment[%s].", @@ -821,13 +892,13 @@ private SegmentIdWithShardSpec createNewSegment( } @Override - public int deletePendingSegments(String dataSource, Interval deleteInterval) + public int deletePendingSegmentsCreatedInInterval(String dataSource, Interval deleteInterval) { return connector.getDBI().inTransaction( (handle, status) -> handle .createStatement( StringUtils.format( - "delete from %s where datasource = :dataSource and created_date >= :start and created_date < :end", + "DELETE FROM %s WHERE datasource = :dataSource AND created_date >= :start AND created_date < :end", dbTables.getPendingSegmentsTable() ) ) @@ -838,6 +909,19 @@ public int deletePendingSegments(String dataSource, Interval deleteInterval) ); } + @Override + public int deletePendingSegments(String dataSource) + { + return connector.getDBI().inTransaction( + (handle, status) -> handle + .createStatement( + StringUtils.format("DELETE FROM %s WHERE datasource = :dataSource", dbTables.getPendingSegmentsTable()) + ) + .bind("dataSource", dataSource) + .execute() + ); + } + /** * Attempts to insert a single segment to the database. If the segment already exists, will do nothing; although, * this checking is imperfect and callers must be prepared to retry their entire transaction on exceptions. @@ -861,7 +945,8 @@ private boolean announceHistoricalSegment( // Avoiding try/catch since it may cause inadvertent transaction-splitting. final int numRowsInserted = handle.createStatement( StringUtils.format( - "INSERT INTO %1$s (id, dataSource, created_date, start, %2$send%2$s, partitioned, version, used, payload) " + "INSERT INTO %1$s (id, dataSource, created_date, start, %2$send%2$s, partitioned, version, used, " + + "payload) " + "VALUES (:id, :dataSource, :created_date, :start, :end, :partitioned, :version, :used, :payload)", dbTables.getSegmentsTable(), connector.getQuoteString() @@ -879,11 +964,27 @@ private boolean announceHistoricalSegment( .execute(); if (numRowsInserted == 1) { - log.info("Published segment [%s] to DB with used flag [%s], json[%s]", segment.getId(), used, jsonMapper.writeValueAsString(segment)); + log.info( + "Published segment [%s] to DB with used flag [%s], json[%s]", + segment.getId(), + used, + jsonMapper.writeValueAsString(segment) + ); } else if (numRowsInserted == 0) { - throw new ISE("Failed to publish segment[%s] to DB with used flag[%s], json[%s]", segment.getId(), used, jsonMapper.writeValueAsString(segment)); + throw new ISE( + "Failed to publish segment[%s] to DB with used flag[%s], json[%s]", + segment.getId(), + used, + jsonMapper.writeValueAsString(segment) + ); } else { - throw new ISE("WTH? numRowsInserted[%s] is larger than 1 after inserting segment[%s] with used flag[%s], json[%s]", numRowsInserted, segment.getId(), used, jsonMapper.writeValueAsString(segment)); + throw new ISE( + "numRowsInserted[%s] is larger than 1 after inserting segment[%s] with used flag[%s], json[%s]", + numRowsInserted, + segment.getId(), + used, + jsonMapper.writeValueAsString(segment) + ); } } catch (Exception e) { @@ -908,7 +1009,7 @@ private boolean segmentExists(final Handle handle, final DataSegment segment) * Read dataSource metadata. Returns null if there is no metadata. */ @Override - public DataSourceMetadata getDataSourceMetadata(final String dataSource) + public @Nullable DataSourceMetadata retrieveDataSourceMetadata(final String dataSource) { final byte[] bytes = connector.lookup( dbTables.getDataSourceTable(), @@ -927,7 +1028,7 @@ public DataSourceMetadata getDataSourceMetadata(final String dataSource) /** * Read dataSource metadata as bytes, from a specific handle. Returns null if there is no metadata. */ - private byte[] getDataSourceMetadataWithHandleAsBytes( + private @Nullable byte[] retrieveDataSourceMetadataWithHandleAsBytes( final Handle handle, final String dataSource ) @@ -971,7 +1072,7 @@ protected DataSourceMetadataUpdateResult updateDataSourceMetadataWithHandle( Preconditions.checkNotNull(startMetadata, "startMetadata"); Preconditions.checkNotNull(endMetadata, "endMetadata"); - final byte[] oldCommitMetadataBytesFromDb = getDataSourceMetadataWithHandleAsBytes(handle, dataSource); + final byte[] oldCommitMetadataBytesFromDb = retrieveDataSourceMetadataWithHandleAsBytes(handle, dataSource); final String oldCommitMetadataSha1FromDb; final DataSourceMetadata oldCommitMetadataFromDb; @@ -1180,81 +1281,6 @@ private void updatePayload(final Handle handle, final DataSegment segment) throw } } - @Override - public List getUnusedSegmentsForInterval(final String dataSource, final Interval interval) - { - List matchingSegments = connector.inReadOnlyTransaction( - new TransactionCallback>() - { - @Override - public List inTransaction(final Handle handle, final TransactionStatus status) - { - // 2 range conditions are used on different columns, but not all SQL databases properly optimize it. - // Some databases can only use an index on one of the columns. An additional condition provides - // explicit knowledge that 'start' cannot be greater than 'end'. - return handle - .createQuery( - StringUtils.format( - "SELECT payload FROM %1$s WHERE dataSource = :dataSource and start >= :start " - + "and start <= :end and %2$send%2$s <= :end and used = false", - dbTables.getSegmentsTable(), connector.getQuoteString() - ) - ) - .setFetchSize(connector.getStreamingFetchSize()) - .bind("dataSource", dataSource) - .bind("start", interval.getStart().toString()) - .bind("end", interval.getEnd().toString()) - .map(ByteArrayMapper.FIRST) - .fold( - new ArrayList<>(), - new Folder3, byte[]>() - { - @Override - public List fold( - List accumulator, - byte[] payload, - FoldController foldController, - StatementContext statementContext - ) - { - accumulator.add(JacksonUtils.readValue(jsonMapper, payload, DataSegment.class)); - return accumulator; - } - } - ); - } - } - ); - - log.info("Found %,d segments for %s for interval %s.", matchingSegments.size(), dataSource, interval); - return matchingSegments; - } - - @Override - public Collection> getUsedSegmentAndCreatedDateForInterval( - String dataSource, - Interval interval - ) - { - return connector.retryWithHandle( - handle -> handle.createQuery( - StringUtils.format( - "SELECT created_date, payload FROM %1$s WHERE dataSource = :dataSource " + - "AND start >= :start AND %2$send%2$s <= :end AND used = true", - dbTables.getSegmentsTable(), connector.getQuoteString() - ) - ) - .bind("dataSource", dataSource) - .bind("start", interval.getStart().toString()) - .bind("end", interval.getEnd().toString()) - .map((int index, ResultSet r, StatementContext ctx) -> new Pair<>( - JacksonUtils.readValue(jsonMapper, r.getBytes("payload"), DataSegment.class), - r.getString("created_date") - )) - .list() - ); - } - @Override public boolean insertDataSourceMetadata(String dataSource, DataSourceMetadata metadata) { diff --git a/server/src/main/java/org/apache/druid/metadata/SQLMetadataConnector.java b/server/src/main/java/org/apache/druid/metadata/SQLMetadataConnector.java index 71a1aedf2b7f..e3cfe299b2b1 100644 --- a/server/src/main/java/org/apache/druid/metadata/SQLMetadataConnector.java +++ b/server/src/main/java/org/apache/druid/metadata/SQLMetadataConnector.java @@ -42,6 +42,7 @@ import org.skife.jdbi.v2.util.ByteArrayMapper; import org.skife.jdbi.v2.util.IntegerMapper; +import javax.annotation.Nullable; import java.sql.Connection; import java.sql.SQLException; import java.sql.SQLRecoverableException; @@ -596,7 +597,7 @@ public void createSupervisorsTable() } @Override - public byte[] lookup( + public @Nullable byte[] lookup( final String tableName, final String keyColumn, final String valueColumn, @@ -615,7 +616,7 @@ public byte[] withHandle(Handle handle) ); } - public byte[] lookupWithHandle( + public @Nullable byte[] lookupWithHandle( final Handle handle, final String tableName, final String keyColumn, diff --git a/server/src/main/java/org/apache/druid/metadata/SQLMetadataRuleManager.java b/server/src/main/java/org/apache/druid/metadata/SQLMetadataRuleManager.java index fc7801341826..0f0cce52110a 100644 --- a/server/src/main/java/org/apache/druid/metadata/SQLMetadataRuleManager.java +++ b/server/src/main/java/org/apache/druid/metadata/SQLMetadataRuleManager.java @@ -148,7 +148,7 @@ public Void withHandle(Handle handle) throws Exception * the theoretical situation of two tasks scheduled in {@link #start()} calling {@link #poll()} concurrently, if * the sequence of {@link #start()} - {@link #stop()} - {@link #start()} actions occurs quickly. * - * {@link SQLMetadataSegmentManager} also have a similar issue. + * {@link SqlSegmentsMetadataManager} also have a similar issue. */ private long currentStartOrder = -1; private ScheduledExecutorService exec = null; diff --git a/server/src/main/java/org/apache/druid/metadata/SQLMetadataSupervisorManager.java b/server/src/main/java/org/apache/druid/metadata/SQLMetadataSupervisorManager.java index a5354b1990bf..52aee9218116 100644 --- a/server/src/main/java/org/apache/druid/metadata/SQLMetadataSupervisorManager.java +++ b/server/src/main/java/org/apache/druid/metadata/SQLMetadataSupervisorManager.java @@ -166,9 +166,7 @@ public Map> fold( { try { String specId = pair.lhs; - retVal.putIfAbsent(specId, new ArrayList<>()); - - retVal.get(specId).add(pair.rhs); + retVal.computeIfAbsent(specId, sId -> new ArrayList<>()).add(pair.rhs); return retVal; } catch (Exception e) { diff --git a/server/src/main/java/org/apache/druid/metadata/MetadataSegmentManager.java b/server/src/main/java/org/apache/druid/metadata/SegmentsMetadataManager.java similarity index 95% rename from server/src/main/java/org/apache/druid/metadata/MetadataSegmentManager.java rename to server/src/main/java/org/apache/druid/metadata/SegmentsMetadataManager.java index fb623acce329..4f97b158021e 100644 --- a/server/src/main/java/org/apache/druid/metadata/MetadataSegmentManager.java +++ b/server/src/main/java/org/apache/druid/metadata/SegmentsMetadataManager.java @@ -33,11 +33,11 @@ import java.util.Set; /** - * The difference between this class and org.apache.druid.sql.calcite.schema.MetadataSegmentView is that this - * class resides in Coordinator's memory, while org.apache.druid.sql.calcite.schema.MetadataSegmentView resides - * in Broker's memory. + * The difference between this class and org.apache.druid.sql.calcite.schema.MetadataSegmentView is that this class + * resides in Coordinator's memory, while org.apache.druid.sql.calcite.schema.MetadataSegmentView resides in Broker's + * memory. */ -public interface MetadataSegmentManager +public interface SegmentsMetadataManager { void startPollingDatabasePeriodically(); @@ -54,7 +54,7 @@ public interface MetadataSegmentManager int markAsUsedNonOvershadowedSegmentsInInterval(String dataSource, Interval interval); int markAsUsedNonOvershadowedSegments(String dataSource, Set segmentIds) - throws UnknownSegmentIdException; + throws UnknownSegmentIdsException; /** * Returns true if the state of the segment entry is changed in the database as the result of this call (that is, the diff --git a/server/src/main/java/org/apache/druid/metadata/MetadataSegmentManagerConfig.java b/server/src/main/java/org/apache/druid/metadata/SegmentsMetadataManagerConfig.java similarity index 96% rename from server/src/main/java/org/apache/druid/metadata/MetadataSegmentManagerConfig.java rename to server/src/main/java/org/apache/druid/metadata/SegmentsMetadataManagerConfig.java index d6c881198a89..5141582a9868 100644 --- a/server/src/main/java/org/apache/druid/metadata/MetadataSegmentManagerConfig.java +++ b/server/src/main/java/org/apache/druid/metadata/SegmentsMetadataManagerConfig.java @@ -24,7 +24,7 @@ /** */ -public class MetadataSegmentManagerConfig +public class SegmentsMetadataManagerConfig { @JsonProperty private Period pollDuration = new Period("PT1M"); diff --git a/server/src/main/java/org/apache/druid/metadata/MetadataSegmentManagerProvider.java b/server/src/main/java/org/apache/druid/metadata/SegmentsMetadataManagerProvider.java similarity index 87% rename from server/src/main/java/org/apache/druid/metadata/MetadataSegmentManagerProvider.java rename to server/src/main/java/org/apache/druid/metadata/SegmentsMetadataManagerProvider.java index c57f5bf66d9c..8aed63bf35e5 100644 --- a/server/src/main/java/org/apache/druid/metadata/MetadataSegmentManagerProvider.java +++ b/server/src/main/java/org/apache/druid/metadata/SegmentsMetadataManagerProvider.java @@ -23,8 +23,8 @@ /** */ -public interface MetadataSegmentManagerProvider extends Provider +public interface SegmentsMetadataManagerProvider extends Provider { @Override - MetadataSegmentManager get(); + SegmentsMetadataManager get(); } diff --git a/server/src/main/java/org/apache/druid/metadata/SQLMetadataSegmentManager.java b/server/src/main/java/org/apache/druid/metadata/SqlSegmentsMetadataManager.java similarity index 95% rename from server/src/main/java/org/apache/druid/metadata/SQLMetadataSegmentManager.java rename to server/src/main/java/org/apache/druid/metadata/SqlSegmentsMetadataManager.java index d121cc9b08dd..92a874863527 100644 --- a/server/src/main/java/org/apache/druid/metadata/SQLMetadataSegmentManager.java +++ b/server/src/main/java/org/apache/druid/metadata/SqlSegmentsMetadataManager.java @@ -84,9 +84,9 @@ * */ @ManageLifecycle -public class SQLMetadataSegmentManager implements MetadataSegmentManager +public class SqlSegmentsMetadataManager implements SegmentsMetadataManager { - private static final EmittingLogger log = new EmittingLogger(SQLMetadataSegmentManager.class); + private static final EmittingLogger log = new EmittingLogger(SqlSegmentsMetadataManager.class); /** * Marker interface for objects stored in {@link #latestDatabasePoll}. See the comment for that field for details. @@ -107,7 +107,7 @@ private static class PeriodicDatabasePoll implements DatabasePoll } /** - * Represents on-demand {@link #poll} initiated at periods of time when SqlSegmentsMetadata doesn't poll the database + * Represents on-demand {@link #poll} initiated at periods of time when SqlSegmentsMetadataManager doesn't poll the database * periodically. */ private static class OnDemandDatabasePoll implements DatabasePoll @@ -127,7 +127,7 @@ long nanosElapsedFromInitiation() * called at the same time if two different threads are calling them. This might be possible if Coordinator gets and * drops leadership repeatedly in quick succession. * - * This lock is also used to synchronize {@link #awaitOrPerformDatabasePoll} for times when SqlSegmentsMetadata + * This lock is also used to synchronize {@link #awaitOrPerformDatabasePoll} for times when SqlSegmentsMetadataManager * is not polling the database periodically (in other words, when the Coordinator is not the leader). */ private final ReentrantReadWriteLock startStopPollLock = new ReentrantReadWriteLock(); @@ -155,7 +155,7 @@ long nanosElapsedFromInitiation() * easy to forget to do. * * This field may be updated from {@link #exec}, or from whatever thread calling {@link #doOnDemandPoll} via {@link - * #awaitOrPerformDatabasePoll()} via one of the public methods of SqlSegmentsMetadata. + * #awaitOrPerformDatabasePoll()} via one of the public methods of SqlSegmentsMetadataManager. */ private volatile @MonotonicNonNull DataSourcesSnapshot dataSourcesSnapshot = null; @@ -164,7 +164,7 @@ long nanosElapsedFromInitiation() * periodically (see {@link PeriodicDatabasePoll}, {@link #startPollingDatabasePeriodically}, {@link * #stopPollingDatabasePeriodically}) or "on demand" (see {@link OnDemandDatabasePoll}), when one of the methods that * accesses {@link #dataSourcesSnapshot}'s state (such as {@link #getImmutableDataSourceWithUsedSegments}) is - * called when the Coordinator is not the leader and therefore SqlSegmentsMetadata isn't polling the database + * called when the Coordinator is not the leader and therefore SqlSegmentsMetadataManager isn't polling the database * periodically. * * Note that if there is a happens-before relationship between a call to {@link #startPollingDatabasePeriodically()} @@ -182,7 +182,7 @@ long nanosElapsedFromInitiation() * #dataSourcesSnapshot}-accessing methods should be generally "wait free" for database polls. * * The notion and the complexity of "on demand" database polls was introduced to simplify the interface of {@link - * MetadataSegmentManager} and guarantee that it always returns consistent and relatively up-to-date data from methods + * SegmentsMetadataManager} and guarantee that it always returns consistent and relatively up-to-date data from methods * like {@link #getImmutableDataSourceWithUsedSegments}, while avoiding excessive repetitive polls. The last part * is achieved via "hooking on" other polls by awaiting on {@link PeriodicDatabasePoll#firstPollCompletionFuture} or * {@link OnDemandDatabasePoll#pollCompletionFuture}, see {@link #awaitOrPerformDatabasePoll} method @@ -207,7 +207,7 @@ long nanosElapsedFromInitiation() private long startPollingCount = 0; /** - * Equal to the current {@link #startPollingCount} value if the SqlSegmentsMetadata is currently started; -1 if + * Equal to the current {@link #startPollingCount} value if the SqlSegmentsMetadataManager is currently started; -1 if * currently stopped. * * This field is used to implement a simple stamp mechanism instead of just a boolean "started" flag to prevent @@ -225,9 +225,9 @@ long nanosElapsedFromInitiation() private @Nullable ScheduledExecutorService exec = null; @Inject - public SQLMetadataSegmentManager( + public SqlSegmentsMetadataManager( ObjectMapper jsonMapper, - Supplier config, + Supplier config, Supplier dbTables, SQLMetadataConnector connector ) @@ -240,7 +240,7 @@ public SQLMetadataSegmentManager( /** * Don't confuse this method with {@link #startPollingDatabasePeriodically}. This is a lifecycle starting method to - * be executed just once for an instance of SqlSegmentsMetadata. + * be executed just once for an instance of SqlSegmentsMetadataManager. */ @LifecycleStart public void start() @@ -260,7 +260,7 @@ public void start() /** * Don't confuse this method with {@link #stopPollingDatabasePeriodically}. This is a lifecycle stopping method to - * be executed just once for an instance of SqlSegmentsMetadata. + * be executed just once for an instance of SqlSegmentsMetadataManager. */ @LifecycleStop public void stop() @@ -289,15 +289,15 @@ public void startPollingDatabasePeriodically() return; } - PeriodicDatabasePoll periodicPollUpdate = new PeriodicDatabasePoll(); - latestDatabasePoll = periodicPollUpdate; + PeriodicDatabasePoll periodicDatabasePoll = new PeriodicDatabasePoll(); + latestDatabasePoll = periodicDatabasePoll; startPollingCount++; currentStartPollingOrder = startPollingCount; final long localStartOrder = currentStartPollingOrder; periodicPollTaskFuture = exec.scheduleWithFixedDelay( - createPollTaskForStartOrder(localStartOrder, periodicPollUpdate), + createPollTaskForStartOrder(localStartOrder, periodicDatabasePoll), 0, periodicPollDelay.getMillis(), TimeUnit.MILLISECONDS @@ -308,31 +308,31 @@ public void startPollingDatabasePeriodically() } } - private Runnable createPollTaskForStartOrder(long startOrder, PeriodicDatabasePoll periodicPollUpdate) + private Runnable createPollTaskForStartOrder(long startOrder, PeriodicDatabasePoll periodicDatabasePoll) { return () -> { // poll() is synchronized together with startPollingDatabasePeriodically(), stopPollingDatabasePeriodically() and // isPollingDatabasePeriodically() to ensure that when stopPollingDatabasePeriodically() exits, poll() won't // actually run anymore after that (it could only enter the synchronized section and exit immediately because the // localStartedOrder doesn't match the new currentStartPollingOrder). It's needed to avoid flakiness in - // SqlSegmentsMetadataTest. See https://github.com/apache/druid/issues/6028 + // SqlSegmentsMetadataManagerTest. See https://github.com/apache/druid/issues/6028 ReentrantReadWriteLock.ReadLock lock = startStopPollLock.readLock(); lock.lock(); try { if (startOrder == currentStartPollingOrder) { poll(); - periodicPollUpdate.firstPollCompletionFuture.complete(null); + periodicDatabasePoll.firstPollCompletionFuture.complete(null); } else { log.debug("startOrder = currentStartPollingOrder = %d, skipping poll()", startOrder); } } catch (Throwable t) { - log.makeAlert(t, "Uncaught exception in %s's polling thread", SQLMetadataSegmentManager.class).emit(); + log.makeAlert(t, "Uncaught exception in %s's polling thread", SqlSegmentsMetadataManager.class).emit(); // Swallow the exception, so that scheduled polling goes on. Leave firstPollFutureSinceLastStart uncompleted // for now, so that it may be completed during the next poll. if (!(t instanceof Exception)) { // Don't try to swallow a Throwable which is not an Exception (that is, a Error). - periodicPollUpdate.firstPollCompletionFuture.completeExceptionally(t); + periodicDatabasePoll.firstPollCompletionFuture.completeExceptionally(t); throw t; } } @@ -371,7 +371,7 @@ public void stopPollingDatabasePeriodically() periodicPollTaskFuture.cancel(false); latestDatabasePoll = null; - // NOT nulling dataSourcesSnapshot, allowing to query the latest polled data even when this SegmentsMetadata + // NOT nulling dataSourcesSnapshot, allowing to query the latest polled data even when this SegmentsMetadataManager // object is stopped. currentStartPollingOrder = -1; @@ -393,9 +393,9 @@ private void awaitOrPerformDatabasePoll() if (awaitLatestDatabasePoll()) { return; } - OnDemandDatabasePoll newOnDemandUpdate = new OnDemandDatabasePoll(); - this.latestDatabasePoll = newOnDemandUpdate; - doOnDemandPoll(newOnDemandUpdate); + OnDemandDatabasePoll onDemandDatabasePoll = new OnDemandDatabasePoll(); + this.latestDatabasePoll = onDemandDatabasePoll; + doOnDemandPoll(onDemandDatabasePoll); } finally { lock.unlock(); @@ -417,15 +417,15 @@ private boolean awaitLatestDatabasePoll() if (latestDatabasePoll instanceof OnDemandDatabasePoll) { long periodicPollDelayNanos = TimeUnit.MILLISECONDS.toNanos(periodicPollDelay.getMillis()); OnDemandDatabasePoll latestOnDemandPoll = (OnDemandDatabasePoll) latestDatabasePoll; - boolean latestUpdateIsFresh = latestOnDemandPoll.nanosElapsedFromInitiation() < periodicPollDelayNanos; - if (latestUpdateIsFresh) { + boolean latestDatabasePollIsFresh = latestOnDemandPoll.nanosElapsedFromInitiation() < periodicPollDelayNanos; + if (latestDatabasePollIsFresh) { Futures.getUnchecked(latestOnDemandPoll.pollCompletionFuture); return true; } - // Latest on-demand update is not fresh. Fall through to return false from this method. + // Latest on-demand poll is not fresh. Fall through to return false from this method. } else { assert latestDatabasePoll == null; - // No periodic updates and no on-demand database poll have been done yet, nothing to await for. + // No periodic database polls and no on-demand poll have been done yet, nothing to await for. } return false; } @@ -457,7 +457,7 @@ public boolean markSegmentAsUsed(final String segmentId) // segment into the respective data source, because we don't have it fetched from the database. It's probably not // worth complicating the implementation and making two database queries just to add the segment because it will // be anyway fetched during the next poll(). Segment putting that is done in the bulk markAsUsed methods is a nice - // to have thing, but doesn't formally affects the external guarantees of SegmentsMetadata class. + // to have thing, but doesn't formally affects the external guarantees of SegmentsMetadataManager class. return numUpdatedDatabaseEntries > 0; } catch (RuntimeException e) { @@ -556,7 +556,7 @@ private int markNonOvershadowedSegmentsAsUsed( @Override public int markAsUsedNonOvershadowedSegments(final String dataSource, final Set segmentIds) - throws UnknownSegmentIdException + throws UnknownSegmentIdsException { try { Pair, VersionedIntervalTimeline> unusedSegmentsAndTimeline = connector @@ -581,8 +581,8 @@ public int markAsUsedNonOvershadowedSegments(final String dataSource, final Set< } catch (Exception e) { Throwable rootCause = Throwables.getRootCause(e); - if (rootCause instanceof UnknownSegmentIdException) { - throw (UnknownSegmentIdException) rootCause; + if (rootCause instanceof UnknownSegmentIdsException) { + throw (UnknownSegmentIdsException) rootCause; } else { throw e; } @@ -593,7 +593,7 @@ private List retrieveUnusedSegments( final String dataSource, final Set segmentIds, final Handle handle - ) throws UnknownSegmentIdException + ) throws UnknownSegmentIdsException { List unknownSegmentIds = new ArrayList<>(); List segments = segmentIds @@ -642,7 +642,7 @@ private List retrieveUnusedSegments( .filter(Objects::nonNull) // Filter nulls corresponding to used segments. .collect(Collectors.toList()); if (!unknownSegmentIds.isEmpty()) { - throw new UnknownSegmentIdException(unknownSegmentIds); + throw new UnknownSegmentIdsException(unknownSegmentIds); } return segments; } @@ -950,7 +950,7 @@ public DataSegment map(int index, ResultSet r, StatementContext ctx) throws SQLE ); // dataSourcesSnapshot is updated only here and the DataSourcesSnapshot object is immutable. If data sources or - // segments are marked as used or unused directly (via markAs...() methods in MetadataSegmentManager), the + // segments are marked as used or unused directly (via markAs...() methods in SegmentsMetadataManager), the // dataSourcesSnapshot can become invalid until the next database poll. // DataSourcesSnapshot computes the overshadowed segments, which makes it an expensive operation if the // snapshot was invalidated on each segment mark as unused or used, especially if a user issues a lot of single diff --git a/server/src/main/java/org/apache/druid/metadata/SQLMetadataSegmentManagerProvider.java b/server/src/main/java/org/apache/druid/metadata/SqlSegmentsMetadataManagerProvider.java similarity index 85% rename from server/src/main/java/org/apache/druid/metadata/SQLMetadataSegmentManagerProvider.java rename to server/src/main/java/org/apache/druid/metadata/SqlSegmentsMetadataManagerProvider.java index 0644e7feddf0..d795a3b7aca6 100644 --- a/server/src/main/java/org/apache/druid/metadata/SQLMetadataSegmentManagerProvider.java +++ b/server/src/main/java/org/apache/druid/metadata/SqlSegmentsMetadataManagerProvider.java @@ -26,18 +26,18 @@ import org.apache.druid.java.util.common.lifecycle.Lifecycle; -public class SQLMetadataSegmentManagerProvider implements MetadataSegmentManagerProvider +public class SqlSegmentsMetadataManagerProvider implements SegmentsMetadataManagerProvider { private final ObjectMapper jsonMapper; - private final Supplier config; + private final Supplier config; private final Supplier storageConfig; private final SQLMetadataConnector connector; private final Lifecycle lifecycle; @Inject - public SQLMetadataSegmentManagerProvider( + public SqlSegmentsMetadataManagerProvider( ObjectMapper jsonMapper, - Supplier config, + Supplier config, Supplier storageConfig, SQLMetadataConnector connector, Lifecycle lifecycle @@ -51,7 +51,7 @@ public SQLMetadataSegmentManagerProvider( } @Override - public MetadataSegmentManager get() + public SegmentsMetadataManager get() { lifecycle.addHandler( new Lifecycle.Handler() @@ -70,7 +70,7 @@ public void stop() } ); - return new SQLMetadataSegmentManager( + return new SqlSegmentsMetadataManager( jsonMapper, config, storageConfig, diff --git a/server/src/main/java/org/apache/druid/metadata/UnknownSegmentIdException.java b/server/src/main/java/org/apache/druid/metadata/UnknownSegmentIdsException.java similarity index 84% rename from server/src/main/java/org/apache/druid/metadata/UnknownSegmentIdException.java rename to server/src/main/java/org/apache/druid/metadata/UnknownSegmentIdsException.java index 6362077a2010..e3d1cc32c586 100644 --- a/server/src/main/java/org/apache/druid/metadata/UnknownSegmentIdException.java +++ b/server/src/main/java/org/apache/druid/metadata/UnknownSegmentIdsException.java @@ -22,13 +22,13 @@ import java.util.Collection; /** - * Exception thrown by {@link MetadataSegmentManager} when a segment id is unknown. + * Exception thrown by {@link SegmentsMetadataManager} when a segment id is unknown. */ -public class UnknownSegmentIdException extends Exception +public class UnknownSegmentIdsException extends Exception { private final Collection unknownSegmentIds; - UnknownSegmentIdException(Collection segmentIds) + UnknownSegmentIdsException(Collection segmentIds) { super("Cannot find segment ids " + segmentIds); this.unknownSegmentIds = segmentIds; diff --git a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/Appenderator.java b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/Appenderator.java index 7f5c595d81a3..56c3a5de47d8 100644 --- a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/Appenderator.java +++ b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/Appenderator.java @@ -193,7 +193,7 @@ AppenderatorAddResult add( * @return future that resolves when all segments have been pushed. The segment list will be the list of segments * that have been pushed and the commit metadata from the Committer. */ - ListenableFuture push( + ListenableFuture push( Collection identifiers, @Nullable Committer committer, boolean useUniquePath diff --git a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/AppenderatorDriverMetadata.java b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/AppenderatorDriverMetadata.java index f1bc8d207eab..4b509d5e4f31 100644 --- a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/AppenderatorDriverMetadata.java +++ b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/AppenderatorDriverMetadata.java @@ -51,8 +51,8 @@ public AppenderatorDriverMetadata( { Preconditions.checkState( segments != null || (activeSegments != null && publishPendingSegments != null), - "Metadata should either have segments with state information or both active segments and publish pending segments information. " - + "segments [%s], activeSegments [%s], publishPendingSegments [%s]", + "Metadata should either have segments with state information or both active segments and publish pending " + + "segments information. segments [%s], activeSegments [%s], publishPendingSegments [%s]", segments, activeSegments, publishPendingSegments diff --git a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/AppenderatorImpl.java b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/AppenderatorImpl.java index 2bf8ddcd5a6e..7fe1affcfe53 100644 --- a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/AppenderatorImpl.java +++ b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/AppenderatorImpl.java @@ -618,7 +618,7 @@ public Object call() throws IOException } @Override - public ListenableFuture push( + public ListenableFuture push( final Collection identifiers, @Nullable final Committer committer, final boolean useUniquePath @@ -640,7 +640,7 @@ public ListenableFuture push( // We should always persist all segments regardless of the input because metadata should be committed for all // segments. persistAll(committer), - (Function) commitMetadata -> { + (Function) commitMetadata -> { final List dataSegments = new ArrayList<>(); log.debug( @@ -666,7 +666,7 @@ public ListenableFuture push( } } - return new SegmentsAndMetadata(dataSegments, commitMetadata); + return new SegmentsAndCommitMetadata(dataSegments, commitMetadata); }, pushExecutor ); diff --git a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/AppenderatorPlumber.java b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/AppenderatorPlumber.java index 2c07d4d55c6a..28c3ac74df36 100644 --- a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/AppenderatorPlumber.java +++ b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/AppenderatorPlumber.java @@ -459,10 +459,10 @@ public Void apply(Throwable throwable) // WARNING: Committers.nil() here means that on-disk data can get out of sync with committing. Futures.addCallback( appenderator.push(segmentsToPush, Committers.nil(), false), - new FutureCallback() + new FutureCallback() { @Override - public void onSuccess(SegmentsAndMetadata result) + public void onSuccess(SegmentsAndCommitMetadata result) { // Immediately publish after pushing for (DataSegment pushedSegment : result.getSegments()) { diff --git a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/BaseAppenderatorDriver.java b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/BaseAppenderatorDriver.java index eeb3269ead63..c0c81843cba0 100644 --- a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/BaseAppenderatorDriver.java +++ b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/BaseAppenderatorDriver.java @@ -464,7 +464,7 @@ Stream getAppendingSegments(Collection sequenceNames) * * @return a future for pushing segments */ - ListenableFuture pushInBackground( + ListenableFuture pushInBackground( @Nullable final WrappedCommitter wrappedCommitter, final Collection segmentIdentifiers, final boolean useUniquePath @@ -474,7 +474,7 @@ ListenableFuture pushInBackground( return Futures.transform( appenderator.push(segmentIdentifiers, wrappedCommitter, useUniquePath), - (Function) segmentsAndMetadata -> { + (Function) segmentsAndMetadata -> { // Sanity check final Set pushedSegments = segmentsAndMetadata .getSegments() @@ -485,7 +485,7 @@ ListenableFuture pushInBackground( if (!pushedSegments.equals(Sets.newHashSet(segmentIdentifiers))) { log.warn( "Removing segments from deep storage because sanity check failed: %s", - SegmentUtils.commaSeparateIdentifiers(segmentsAndMetadata.getSegments()) + SegmentUtils.commaSeparatedIdentifiers(segmentsAndMetadata.getSegments()) ); segmentsAndMetadata.getSegments().forEach(dataSegmentKiller::killQuietly); @@ -507,16 +507,16 @@ ListenableFuture pushInBackground( * Drop segments in background. The segments should be pushed (in batch ingestion) or published (in streaming * ingestion) before being dropped. * - * @param segmentsAndMetadata result of pushing or publishing + * @param segmentsAndCommitMetadata result of pushing or publishing * * @return a future for dropping segments */ - ListenableFuture dropInBackground(SegmentsAndMetadata segmentsAndMetadata) + ListenableFuture dropInBackground(SegmentsAndCommitMetadata segmentsAndCommitMetadata) { - log.debug("Dropping segments: %s", SegmentUtils.commaSeparateIdentifiers(segmentsAndMetadata.getSegments())); + log.debug("Dropping segments: %s", SegmentUtils.commaSeparatedIdentifiers(segmentsAndCommitMetadata.getSegments())); final ListenableFuture dropFuture = Futures.allAsList( - segmentsAndMetadata + segmentsAndCommitMetadata .getSegments() .stream() .map(segment -> appenderator.drop(SegmentIdWithShardSpec.fromDataSegment(segment))) @@ -525,10 +525,10 @@ ListenableFuture dropInBackground(SegmentsAndMetadata segme return Futures.transform( dropFuture, - (Function) x -> { - final Object metadata = segmentsAndMetadata.getCommitMetadata(); - return new SegmentsAndMetadata( - segmentsAndMetadata.getSegments(), + (Function) x -> { + final Object metadata = segmentsAndCommitMetadata.getCommitMetadata(); + return new SegmentsAndCommitMetadata( + segmentsAndCommitMetadata.getSegments(), metadata == null ? null : ((AppenderatorDriverMetadata) metadata).getCallerMetadata() ); } @@ -539,22 +539,22 @@ ListenableFuture dropInBackground(SegmentsAndMetadata segme * Publish segments in background. The segments should be dropped (in batch ingestion) or pushed (in streaming * ingestion) before being published. * - * @param segmentsAndMetadata result of dropping or pushing - * @param publisher transactional segment publisher + * @param segmentsAndCommitMetadata result of dropping or pushing + * @param publisher transactional segment publisher * * @return a future for publishing segments */ - ListenableFuture publishInBackground( + ListenableFuture publishInBackground( @Nullable Set segmentsToBeOverwritten, - SegmentsAndMetadata segmentsAndMetadata, + SegmentsAndCommitMetadata segmentsAndCommitMetadata, TransactionalSegmentPublisher publisher ) { - if (segmentsAndMetadata.getSegments().isEmpty()) { + if (segmentsAndCommitMetadata.getSegments().isEmpty()) { if (!publisher.supportsEmptyPublish()) { log.info("Nothing to publish, skipping publish step."); - final SettableFuture retVal = SettableFuture.create(); - retVal.set(segmentsAndMetadata); + final SettableFuture retVal = SettableFuture.create(); + retVal.set(segmentsAndCommitMetadata); return retVal; } else { // Sanity check: if we have no segments to publish, but the appenderator did ingest > 0 valid rows, @@ -569,7 +569,7 @@ ListenableFuture publishInBackground( } } - final Object metadata = segmentsAndMetadata.getCommitMetadata(); + final Object metadata = segmentsAndCommitMetadata.getCommitMetadata(); final Object callerMetadata = metadata == null ? null : ((AppenderatorDriverMetadata) metadata).getCallerMetadata(); @@ -577,7 +577,7 @@ ListenableFuture publishInBackground( return executor.submit( () -> { try { - final ImmutableSet ourSegments = ImmutableSet.copyOf(segmentsAndMetadata.getSegments()); + final ImmutableSet ourSegments = ImmutableSet.copyOf(segmentsAndCommitMetadata.getSegments()); final SegmentPublishResult publishResult = publisher.publishSegments( segmentsToBeOverwritten, ourSegments, @@ -588,7 +588,7 @@ ListenableFuture publishInBackground( log.info( "Published segments with commit metadata [%s]: %s", callerMetadata, - SegmentUtils.commaSeparateIdentifiers(segmentsAndMetadata.getSegments()) + SegmentUtils.commaSeparatedIdentifiers(segmentsAndCommitMetadata.getSegments()) ); } else { // Publishing didn't affirmatively succeed. However, segments with our identifiers may still be active @@ -600,7 +600,7 @@ ListenableFuture publishInBackground( // from the overlord. In this case we do not want to delete the segments we pushed, since they are // now live! - final Set segmentsIdentifiers = segmentsAndMetadata + final Set segmentsIdentifiers = segmentsAndCommitMetadata .getSegments() .stream() .map(SegmentIdWithShardSpec::fromDataSegment) @@ -611,7 +611,7 @@ ListenableFuture publishInBackground( if (activeSegments.equals(ourSegments)) { log.info( "Could not publish segments, but checked and found them already published; continuing: %s", - SegmentUtils.commaSeparateIdentifiers(ourSegments) + SegmentUtils.commaSeparatedIdentifiers(ourSegments) ); // Clean up pushed segments if they are physically disjoint from the published ones (this means @@ -622,32 +622,36 @@ ListenableFuture publishInBackground( ).isEmpty(); if (physicallyDisjoint) { - segmentsAndMetadata.getSegments().forEach(dataSegmentKiller::killQuietly); + segmentsAndCommitMetadata.getSegments().forEach(dataSegmentKiller::killQuietly); } } else { // Our segments aren't active. Publish failed for some reason. Clean them up and then throw an error. - segmentsAndMetadata.getSegments().forEach(dataSegmentKiller::killQuietly); + segmentsAndCommitMetadata.getSegments().forEach(dataSegmentKiller::killQuietly); if (publishResult.getErrorMsg() != null) { throw new ISE( "Failed to publish segments because of [%s]: %s", publishResult.getErrorMsg(), - SegmentUtils.commaSeparateIdentifiers(ourSegments) + SegmentUtils.commaSeparatedIdentifiers(ourSegments) ); } else { - throw new ISE("Failed to publish segments: %s", SegmentUtils.commaSeparateIdentifiers(ourSegments)); + throw new ISE("Failed to publish segments: %s", SegmentUtils.commaSeparatedIdentifiers(ourSegments)); } } } } catch (Exception e) { // Must not remove segments here, we aren't sure if our transaction succeeded or not. - log.noStackTrace().warn(e, "Failed publish, not removing segments: %s", segmentsAndMetadata.getSegments()); + log.noStackTrace().warn( + e, + "Failed publish, not removing segments: %s", + SegmentUtils.commaSeparatedIdentifiers(segmentsAndCommitMetadata.getSegments()) + ); Throwables.propagateIfPossible(e); throw new RuntimeException(e); } - return segmentsAndMetadata; + return segmentsAndCommitMetadata; } ); } diff --git a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/BatchAppenderatorDriver.java b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/BatchAppenderatorDriver.java index e9e946bbb74b..4f6fd54a18e8 100644 --- a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/BatchAppenderatorDriver.java +++ b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/BatchAppenderatorDriver.java @@ -118,9 +118,9 @@ public AppenderatorDriverAddResult add( * * @param pushAndClearTimeoutMs timeout for pushing and dropping segments * - * @return {@link SegmentsAndMetadata} for pushed and dropped segments + * @return {@link SegmentsAndCommitMetadata} for pushed and dropped segments */ - public SegmentsAndMetadata pushAllAndClear(long pushAndClearTimeoutMs) + public SegmentsAndCommitMetadata pushAllAndClear(long pushAndClearTimeoutMs) throws InterruptedException, ExecutionException, TimeoutException { final Collection sequences; @@ -131,7 +131,7 @@ public SegmentsAndMetadata pushAllAndClear(long pushAndClearTimeoutMs) return pushAndClear(sequences, pushAndClearTimeoutMs); } - private SegmentsAndMetadata pushAndClear( + private SegmentsAndCommitMetadata pushAndClear( Collection sequenceNames, long pushAndClearTimeoutMs ) throws InterruptedException, ExecutionException, TimeoutException @@ -140,17 +140,17 @@ private SegmentsAndMetadata pushAndClear( .map(SegmentWithState::getSegmentIdentifier) .collect(Collectors.toSet()); - final ListenableFuture future = ListenableFutures.transformAsync( + + final ListenableFuture future = ListenableFutures.transformAsync( pushInBackground(null, requestedSegmentIdsForSequences, false), this::dropInBackground ); - final SegmentsAndMetadata segmentsAndMetadata = pushAndClearTimeoutMs == 0L ? - future.get() : - future.get(pushAndClearTimeoutMs, TimeUnit.MILLISECONDS); + final SegmentsAndCommitMetadata segmentsAndCommitMetadata = + pushAndClearTimeoutMs == 0L ? future.get() : future.get(pushAndClearTimeoutMs, TimeUnit.MILLISECONDS); // Sanity check - final Map pushedSegmentIdToSegmentMap = segmentsAndMetadata + final Map pushedSegmentIdToSegmentMap = segmentsAndCommitMetadata .getSegments() .stream() .collect(Collectors.toMap(SegmentIdWithShardSpec::fromDataSegment, Function.identity())); @@ -186,7 +186,7 @@ private SegmentsAndMetadata pushAndClear( } } - return segmentsAndMetadata; + return segmentsAndCommitMetadata; } /** @@ -197,7 +197,7 @@ private SegmentsAndMetadata pushAndClear( * * @return a {@link ListenableFuture} for the publish task */ - public ListenableFuture publishAll( + public ListenableFuture publishAll( @Nullable final Set segmentsToBeOverwritten, final TransactionalSegmentPublisher publisher ) @@ -209,7 +209,7 @@ public ListenableFuture publishAll( return publishInBackground( segmentsToBeOverwritten, - new SegmentsAndMetadata( + new SegmentsAndCommitMetadata( snapshot .values() .stream() diff --git a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/SegmentsAndMetadata.java b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/SegmentsAndCommitMetadata.java similarity index 85% rename from server/src/main/java/org/apache/druid/segment/realtime/appenderator/SegmentsAndMetadata.java rename to server/src/main/java/org/apache/druid/segment/realtime/appenderator/SegmentsAndCommitMetadata.java index 034044111fbe..1518e3c1ee6e 100644 --- a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/SegmentsAndMetadata.java +++ b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/SegmentsAndCommitMetadata.java @@ -27,14 +27,14 @@ import java.util.List; import java.util.Objects; -public class SegmentsAndMetadata +public class SegmentsAndCommitMetadata { - private static final SegmentsAndMetadata NIL = new SegmentsAndMetadata(Collections.emptyList(), null); + private static final SegmentsAndCommitMetadata NIL = new SegmentsAndCommitMetadata(Collections.emptyList(), null); private final Object commitMetadata; private final ImmutableList segments; - public SegmentsAndMetadata( + public SegmentsAndCommitMetadata( List segments, @Nullable Object commitMetadata ) @@ -63,7 +63,7 @@ public boolean equals(Object o) if (o == null || getClass() != o.getClass()) { return false; } - SegmentsAndMetadata that = (SegmentsAndMetadata) o; + SegmentsAndCommitMetadata that = (SegmentsAndCommitMetadata) o; return Objects.equals(commitMetadata, that.commitMetadata) && Objects.equals(segments, that.segments); } @@ -77,13 +77,13 @@ public int hashCode() @Override public String toString() { - return "SegmentsAndMetadata{" + + return getClass().getSimpleName() + "{" + "commitMetadata=" + commitMetadata + ", segments=" + segments + '}'; } - public static SegmentsAndMetadata nil() + public static SegmentsAndCommitMetadata nil() { return NIL; } diff --git a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderatorDriver.java b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderatorDriver.java index d7b0b6ad6ad3..bee2c7dc9932 100644 --- a/server/src/main/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderatorDriver.java +++ b/server/src/main/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderatorDriver.java @@ -41,6 +41,7 @@ import org.apache.druid.segment.realtime.appenderator.SegmentWithState.SegmentState; import org.apache.druid.segment.realtime.plumber.SegmentHandoffNotifier; import org.apache.druid.segment.realtime.plumber.SegmentHandoffNotifierFactory; +import org.apache.druid.timeline.DataSegment; import javax.annotation.Nullable; import java.io.IOException; @@ -264,7 +265,7 @@ public ListenableFuture persistAsync(final Committer committer) * @return a {@link ListenableFuture} for the submitted task which removes published {@code sequenceNames} from * {@code activeSegments} and {@code publishPendingSegments} */ - public ListenableFuture publish( + public ListenableFuture publish( final TransactionalSegmentPublisher publisher, final Committer committer, final Collection sequenceNames @@ -274,7 +275,7 @@ public ListenableFuture publish( .map(SegmentWithState::getSegmentIdentifier) .collect(Collectors.toList()); - final ListenableFuture publishFuture = ListenableFutures.transformAsync( + final ListenableFuture publishFuture = ListenableFutures.transformAsync( // useUniquePath=true prevents inconsistencies in segment data when task failures or replicas leads to a second // version of a segment with the same identifier containing different data; see DataSegmentPusher.push() docs pushInBackground(wrapCommitter(committer), theSegments, true), @@ -286,7 +287,7 @@ public ListenableFuture publish( ); return Futures.transform( publishFuture, - (Function) sam -> { + (Function) sam -> { synchronized (segments) { sequenceNames.forEach(segments::remove); } @@ -296,32 +297,32 @@ public ListenableFuture publish( } /** - * Register the segments in the given {@link SegmentsAndMetadata} to be handed off and execute a background task which + * Register the segments in the given {@link SegmentsAndCommitMetadata} to be handed off and execute a background task which * waits until the hand off completes. * - * @param segmentsAndMetadata the result segments and metadata of + * @param segmentsAndCommitMetadata the result segments and metadata of * {@link #publish(TransactionalSegmentPublisher, Committer, Collection)} * * @return null if the input segmentsAndMetadata is null. Otherwise, a {@link ListenableFuture} for the submitted task - * which returns {@link SegmentsAndMetadata} containing the segments successfully handed off and the metadata + * which returns {@link SegmentsAndCommitMetadata} containing the segments successfully handed off and the metadata * of the caller of {@link AppenderatorDriverMetadata} */ - public ListenableFuture registerHandoff(SegmentsAndMetadata segmentsAndMetadata) + public ListenableFuture registerHandoff(SegmentsAndCommitMetadata segmentsAndCommitMetadata) { - if (segmentsAndMetadata == null) { + if (segmentsAndCommitMetadata == null) { return Futures.immediateFuture(null); } else { - final List waitingSegmentIdList = segmentsAndMetadata.getSegments().stream() - .map( + final List waitingSegmentIdList = segmentsAndCommitMetadata.getSegments().stream() + .map( SegmentIdWithShardSpec::fromDataSegment) - .collect(Collectors.toList()); - final Object metadata = Preconditions.checkNotNull(segmentsAndMetadata.getCommitMetadata(), "commitMetadata"); + .collect(Collectors.toList()); + final Object metadata = Preconditions.checkNotNull(segmentsAndCommitMetadata.getCommitMetadata(), "commitMetadata"); if (waitingSegmentIdList.isEmpty()) { return Futures.immediateFuture( - new SegmentsAndMetadata( - segmentsAndMetadata.getSegments(), + new SegmentsAndCommitMetadata( + segmentsAndCommitMetadata.getSegments(), ((AppenderatorDriverMetadata) metadata).getCallerMetadata() ) ); @@ -329,7 +330,7 @@ public ListenableFuture registerHandoff(SegmentsAndMetadata log.debug("Register handoff of segments: [%s]", waitingSegmentIdList); - final SettableFuture resultFuture = SettableFuture.create(); + final SettableFuture resultFuture = SettableFuture.create(); final AtomicInteger numRemainingHandoffSegments = new AtomicInteger(waitingSegmentIdList.size()); for (final SegmentIdWithShardSpec segmentIdentifier : waitingSegmentIdList) { @@ -353,10 +354,11 @@ public ListenableFuture registerHandoff(SegmentsAndMetadata public void onSuccess(Object result) { if (numRemainingHandoffSegments.decrementAndGet() == 0) { - log.debug("Successfully handed off [%d] segments.", segmentsAndMetadata.getSegments().size()); + List segments = segmentsAndCommitMetadata.getSegments(); + log.debug("Successfully handed off [%d] segments.", segments.size()); resultFuture.set( - new SegmentsAndMetadata( - segmentsAndMetadata.getSegments(), + new SegmentsAndCommitMetadata( + segments, ((AppenderatorDriverMetadata) metadata).getCallerMetadata() ) ); @@ -380,7 +382,7 @@ public void onFailure(Throwable e) } } - public ListenableFuture publishAndRegisterHandoff( + public ListenableFuture publishAndRegisterHandoff( final TransactionalSegmentPublisher publisher, final Committer committer, final Collection sequenceNames diff --git a/server/src/main/java/org/apache/druid/segment/realtime/firehose/SqlFirehoseFactory.java b/server/src/main/java/org/apache/druid/segment/realtime/firehose/SqlFirehoseFactory.java index b1af14fcc637..9d50499ab19f 100644 --- a/server/src/main/java/org/apache/druid/segment/realtime/firehose/SqlFirehoseFactory.java +++ b/server/src/main/java/org/apache/druid/segment/realtime/firehose/SqlFirehoseFactory.java @@ -35,7 +35,6 @@ import org.skife.jdbi.v2.exceptions.StatementException; import javax.annotation.Nullable; - import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; diff --git a/server/src/main/java/org/apache/druid/server/coordination/SegmentLoadDropHandler.java b/server/src/main/java/org/apache/druid/server/coordination/SegmentLoadDropHandler.java index 308c0d477d47..c359a9ab1743 100644 --- a/server/src/main/java/org/apache/druid/server/coordination/SegmentLoadDropHandler.java +++ b/server/src/main/java/org/apache/druid/server/coordination/SegmentLoadDropHandler.java @@ -45,7 +45,6 @@ import org.apache.druid.timeline.DataSegment; import javax.annotation.Nullable; - import java.io.File; import java.io.IOException; import java.util.ArrayList; diff --git a/server/src/main/java/org/apache/druid/server/coordination/ZkCoordinator.java b/server/src/main/java/org/apache/druid/server/coordination/ZkCoordinator.java index 734de202ce3c..e1d6620875f8 100644 --- a/server/src/main/java/org/apache/druid/server/coordination/ZkCoordinator.java +++ b/server/src/main/java/org/apache/druid/server/coordination/ZkCoordinator.java @@ -34,7 +34,6 @@ import org.apache.druid.server.initialization.ZkPathsConfig; import javax.annotation.Nullable; - import java.io.IOException; import java.util.concurrent.ExecutorService; diff --git a/server/src/main/java/org/apache/druid/server/coordinator/BalancerStrategy.java b/server/src/main/java/org/apache/druid/server/coordinator/BalancerStrategy.java index 552227eaf3c2..d9fea81e3a95 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/BalancerStrategy.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/BalancerStrategy.java @@ -19,6 +19,7 @@ package org.apache.druid.server.coordinator; +import org.apache.druid.server.coordinator.duty.BalanceSegments; import org.apache.druid.timeline.DataSegment; import javax.annotation.Nullable; @@ -30,7 +31,7 @@ * This interface describes the coordinator balancing strategy, which is responsible for making decisions on where * to place {@link DataSegment}s on historical servers (described by {@link ServerHolder}). The balancing strategy * is used by {@link org.apache.druid.server.coordinator.rules.LoadRule} to assign and drop segments, and by - * {@link org.apache.druid.server.coordinator.helper.DruidCoordinatorBalancer} to migrate segments between historicals. + * {@link BalanceSegments} to migrate segments between historicals. */ public interface BalancerStrategy { @@ -77,7 +78,7 @@ default Iterator pickServersToDrop(DataSegment toDropSegment, Navi /** * Add balancing strategy stats during the 'balanceTier' operation of - * {@link org.apache.druid.server.coordinator.helper.DruidCoordinatorBalancer} to be included + * {@link BalanceSegments} to be included * @param tier historical tier being balanced * @param stats stats object to add balancing strategy stats to * @param serverHolderList servers in tier being balanced diff --git a/server/src/main/java/org/apache/druid/server/coordinator/CoordinatorDynamicConfig.java b/server/src/main/java/org/apache/druid/server/coordinator/CoordinatorDynamicConfig.java index a3101a5c3f06..7f24a53840ae 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/CoordinatorDynamicConfig.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/CoordinatorDynamicConfig.java @@ -25,6 +25,7 @@ import com.google.common.collect.ImmutableSet; import org.apache.druid.common.config.JacksonConfigManager; import org.apache.druid.java.util.common.IAE; +import org.apache.druid.server.coordinator.duty.KillUnusedSegments; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -57,15 +58,11 @@ public class CoordinatorDynamicConfig private final int balancerComputeThreads; private final boolean emitBalancingStats; - /** - * If true, {@link org.apache.druid.server.coordinator.helper.DruidCoordinatorSegmentKiller} sends kill tasks for - * unused segments in all data sources. - */ + /** If true {@link KillUnusedSegments} sends kill tasks for unused segments in all data sources. */ private final boolean killUnusedSegmentsInAllDataSources; /** - * List of specific data sources for which kill tasks are sent in {@link - * org.apache.druid.server.coordinator.helper.DruidCoordinatorSegmentKiller}. + * List of specific data sources for which kill tasks are sent in {@link KillUnusedSegments}. */ private final Set specificDataSourcesToKillUnusedSegmentsIn; private final Set decommissioningNodes; @@ -73,10 +70,10 @@ public class CoordinatorDynamicConfig /** * Stale pending segments belonging to the data sources in this list are not killed by {@link - * DruidCoordinatorCleanupPendingSegments}. In other words, segments in these data sources are "protected". + * KillStalePendingSegments}. In other words, segments in these data sources are "protected". * * Pending segments are considered "stale" when their created_time is older than {@link - * DruidCoordinatorCleanupPendingSegments#KEEP_PENDING_SEGMENTS_OFFSET} from now. + * KillStalePendingSegments#KEEP_PENDING_SEGMENTS_OFFSET} from now. */ private final Set dataSourcesToNotKillStalePendingSegmentsIn; diff --git a/server/src/main/java/org/apache/druid/server/coordinator/DataSourceCompactionConfig.java b/server/src/main/java/org/apache/druid/server/coordinator/DataSourceCompactionConfig.java index c59de7f11028..7519a064a4a7 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/DataSourceCompactionConfig.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/DataSourceCompactionConfig.java @@ -20,12 +20,8 @@ package org.apache.druid.server.coordinator; import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.base.Preconditions; -import org.apache.druid.client.indexing.ClientCompactQueryTuningConfig; -import org.apache.druid.data.input.SplitHintSpec; -import org.apache.druid.segment.IndexSpec; import org.joda.time.Period; import javax.annotation.Nullable; @@ -34,22 +30,22 @@ public class DataSourceCompactionConfig { - public static final long DEFAULT_TARGET_COMPACTION_SIZE_BYTES = 400 * 1024 * 1024; // 400MB - - // should be synchronized with Tasks.DEFAULT_MERGE_TASK_PRIORITY - private static final int DEFAULT_COMPACTION_TASK_PRIORITY = 25; + /** Must be synced with Tasks.DEFAULT_MERGE_TASK_PRIORITY */ + public static final int DEFAULT_COMPACTION_TASK_PRIORITY = 25; private static final long DEFAULT_INPUT_SEGMENT_SIZE_BYTES = 400 * 1024 * 1024; private static final Period DEFAULT_SKIP_OFFSET_FROM_LATEST = new Period("P1D"); private final String dataSource; private final int taskPriority; private final long inputSegmentSizeBytes; - // The number of input segments is limited because the byte size of a serialized task spec is limited by - // RemoteTaskRunnerConfig.maxZnodeBytes. + /** + * The number of input segments is limited because the byte size of a serialized task spec is limited by + * org.apache.druid.indexing.overlord.config.RemoteTaskRunnerConfig.maxZnodeBytes. + */ @Nullable private final Integer maxRowsPerSegment; private final Period skipOffsetFromLatest; - private final UserCompactTuningConfig tuningConfig; + private final UserCompactionTaskQueryTuningConfig tuningConfig; private final Map taskContext; @JsonCreator @@ -59,7 +55,7 @@ public DataSourceCompactionConfig( @JsonProperty("inputSegmentSizeBytes") @Nullable Long inputSegmentSizeBytes, @JsonProperty("maxRowsPerSegment") @Nullable Integer maxRowsPerSegment, @JsonProperty("skipOffsetFromLatest") @Nullable Period skipOffsetFromLatest, - @JsonProperty("tuningConfig") @Nullable UserCompactTuningConfig tuningConfig, + @JsonProperty("tuningConfig") @Nullable UserCompactionTaskQueryTuningConfig tuningConfig, @JsonProperty("taskContext") @Nullable Map taskContext ) { @@ -109,7 +105,7 @@ public Period getSkipOffsetFromLatest() @JsonProperty @Nullable - public UserCompactTuningConfig getTuningConfig() + public UserCompactionTaskQueryTuningConfig getTuningConfig() { return tuningConfig; } @@ -151,40 +147,4 @@ public int hashCode() taskContext ); } - - public static class UserCompactTuningConfig extends ClientCompactQueryTuningConfig - { - @JsonCreator - public UserCompactTuningConfig( - @JsonProperty("maxRowsInMemory") @Nullable Integer maxRowsInMemory, - @JsonProperty("maxBytesInMemory") @Nullable Long maxBytesInMemory, - @JsonProperty("maxTotalRows") @Nullable Long maxTotalRows, - @JsonProperty("splitHintSpec") @Nullable SplitHintSpec splitHintSpec, - @JsonProperty("indexSpec") @Nullable IndexSpec indexSpec, - @JsonProperty("maxPendingPersists") @Nullable Integer maxPendingPersists, - @JsonProperty("pushTimeout") @Nullable Long pushTimeout, - @JsonProperty("maxNumConcurrentSubTasks") @Nullable Integer maxNumConcurrentSubTasks - ) - { - super( - null, - maxRowsInMemory, - maxBytesInMemory, - maxTotalRows, - splitHintSpec, - indexSpec, - maxPendingPersists, - pushTimeout, - maxNumConcurrentSubTasks - ); - } - - @Override - @Nullable - @JsonIgnore - public Integer getMaxRowsPerSegment() - { - throw new UnsupportedOperationException(); - } - } } diff --git a/server/src/main/java/org/apache/druid/server/coordinator/DruidCluster.java b/server/src/main/java/org/apache/druid/server/coordinator/DruidCluster.java index 6f52bf8d971c..318f663609b0 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/DruidCluster.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/DruidCluster.java @@ -70,10 +70,7 @@ private DruidCluster( this.realtimes = realtimes == null ? new HashSet<>() : new HashSet<>(realtimes); this.historicals = CollectionUtils.mapValues( historicals, - holders -> CollectionUtils.newTreeSet( - Comparator.reverseOrder(), - holders - ) + holders -> CollectionUtils.newTreeSet(Comparator.reverseOrder(), holders) ); } diff --git a/server/src/main/java/org/apache/druid/server/coordinator/DruidCoordinator.java b/server/src/main/java/org/apache/druid/server/coordinator/DruidCoordinator.java index ae29950bd518..539ba869ffb9 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/DruidCoordinator.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/DruidCoordinator.java @@ -44,7 +44,7 @@ import org.apache.druid.curator.discovery.ServiceAnnouncer; import org.apache.druid.discovery.DruidLeaderSelector; import org.apache.druid.guice.ManageLifecycle; -import org.apache.druid.guice.annotations.CoordinatorIndexingServiceHelper; +import org.apache.druid.guice.annotations.CoordinatorIndexingServiceDuty; import org.apache.druid.guice.annotations.Self; import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.IAE; @@ -59,16 +59,16 @@ import org.apache.druid.java.util.emitter.EmittingLogger; import org.apache.druid.java.util.emitter.service.ServiceEmitter; import org.apache.druid.metadata.MetadataRuleManager; -import org.apache.druid.metadata.MetadataSegmentManager; +import org.apache.druid.metadata.SegmentsMetadataManager; import org.apache.druid.server.DruidNode; -import org.apache.druid.server.coordinator.helper.DruidCoordinatorBalancer; -import org.apache.druid.server.coordinator.helper.DruidCoordinatorCleanupOvershadowed; -import org.apache.druid.server.coordinator.helper.DruidCoordinatorCleanupUnneeded; -import org.apache.druid.server.coordinator.helper.DruidCoordinatorHelper; -import org.apache.druid.server.coordinator.helper.DruidCoordinatorLogger; -import org.apache.druid.server.coordinator.helper.DruidCoordinatorRuleRunner; -import org.apache.druid.server.coordinator.helper.DruidCoordinatorSegmentCompactor; -import org.apache.druid.server.coordinator.helper.DruidCoordinatorSegmentInfoLoader; +import org.apache.druid.server.coordinator.duty.BalanceSegments; +import org.apache.druid.server.coordinator.duty.CompactSegments; +import org.apache.druid.server.coordinator.duty.CoordinatorDuty; +import org.apache.druid.server.coordinator.duty.EmitClusterStatsAndMetrics; +import org.apache.druid.server.coordinator.duty.LogUsedSegments; +import org.apache.druid.server.coordinator.duty.MarkAsUnusedOvershadowedSegments; +import org.apache.druid.server.coordinator.duty.RunRules; +import org.apache.druid.server.coordinator.duty.UnloadUnusedSegments; import org.apache.druid.server.coordinator.rules.LoadRule; import org.apache.druid.server.coordinator.rules.Rule; import org.apache.druid.server.initialization.ZkPathsConfig; @@ -78,6 +78,7 @@ import org.joda.time.DateTime; import org.joda.time.Duration; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -105,13 +106,13 @@ public class DruidCoordinator * * It is also used in {@link DruidCoordinatorRuntimeParams} for {@link * DruidCoordinatorRuntimeParams#getUsedSegments()} - a collection of segments to be considered during some - * coordinator run for different {@link DruidCoordinatorHelper}s. The order matters only for {@link - * DruidCoordinatorRuleRunner}, which tries to apply the rules while iterating the segments in the order imposed by + * coordinator run for different {@link CoordinatorDuty}s. The order matters only for {@link + * RunRules}, which tries to apply the rules while iterating the segments in the order imposed by * this comparator. In {@link LoadRule} the throttling limit may be hit (via {@link ReplicationThrottler}; see * {@link CoordinatorDynamicConfig#getReplicationThrottleLimit()}). So before we potentially hit this limit, we want * to schedule loading the more recent segments (among all of those that need to be loaded). * - * In both {@link LoadQueuePeon}s and {@link DruidCoordinatorRuleRunner}, we want to load more recent segments first + * In both {@link LoadQueuePeon}s and {@link RunRules}, we want to load more recent segments first * because presumably they are queried more often and contain are more important data for users, so if the Druid * cluster has availability problems and struggling to make all segments available immediately, at least we try to * make more "important" (more recent) segments available as soon as possible. @@ -128,7 +129,7 @@ public class DruidCoordinator private final DruidCoordinatorConfig config; private final ZkPathsConfig zkPaths; private final JacksonConfigManager configManager; - private final MetadataSegmentManager segmentsMetadata; + private final SegmentsMetadataManager segmentsMetadataManager; private final ServerInventoryView serverInventoryView; private final MetadataRuleManager metadataRuleManager; private final CuratorFramework curator; @@ -139,12 +140,12 @@ public class DruidCoordinator private final Map loadManagementPeons; private final ServiceAnnouncer serviceAnnouncer; private final DruidNode self; - private final Set indexingServiceHelpers; + private final Set indexingServiceDuties; private final BalancerStrategyFactory factory; private final LookupCoordinatorManager lookupCoordinatorManager; private final DruidLeaderSelector coordLeaderSelector; - private final DruidCoordinatorSegmentCompactor segmentCompactor; + private final CompactSegments compactSegments; private volatile boolean started = false; private volatile SegmentReplicantLookup segmentReplicantLookup = null; @@ -154,7 +155,7 @@ public DruidCoordinator( DruidCoordinatorConfig config, ZkPathsConfig zkPaths, JacksonConfigManager configManager, - MetadataSegmentManager segmentsMetadata, + SegmentsMetadataManager segmentsMetadataManager, ServerInventoryView serverInventoryView, MetadataRuleManager metadataRuleManager, CuratorFramework curator, @@ -164,18 +165,18 @@ public DruidCoordinator( LoadQueueTaskMaster taskMaster, ServiceAnnouncer serviceAnnouncer, @Self DruidNode self, - @CoordinatorIndexingServiceHelper Set indexingServiceHelpers, + @CoordinatorIndexingServiceDuty Set indexingServiceDuties, BalancerStrategyFactory factory, LookupCoordinatorManager lookupCoordinatorManager, @Coordinator DruidLeaderSelector coordLeaderSelector, - DruidCoordinatorSegmentCompactor segmentCompactor + CompactSegments compactSegments ) { this( config, zkPaths, configManager, - segmentsMetadata, + segmentsMetadataManager, serverInventoryView, metadataRuleManager, curator, @@ -186,11 +187,11 @@ public DruidCoordinator( serviceAnnouncer, self, new ConcurrentHashMap<>(), - indexingServiceHelpers, + indexingServiceDuties, factory, lookupCoordinatorManager, coordLeaderSelector, - segmentCompactor + compactSegments ); } @@ -198,7 +199,7 @@ public DruidCoordinator( DruidCoordinatorConfig config, ZkPathsConfig zkPaths, JacksonConfigManager configManager, - MetadataSegmentManager segmentsMetadata, + SegmentsMetadataManager segmentsMetadataManager, ServerInventoryView serverInventoryView, MetadataRuleManager metadataRuleManager, CuratorFramework curator, @@ -209,18 +210,18 @@ public DruidCoordinator( ServiceAnnouncer serviceAnnouncer, DruidNode self, ConcurrentMap loadQueuePeonMap, - Set indexingServiceHelpers, + Set indexingServiceDuties, BalancerStrategyFactory factory, LookupCoordinatorManager lookupCoordinatorManager, DruidLeaderSelector coordLeaderSelector, - DruidCoordinatorSegmentCompactor segmentCompactor + CompactSegments compactSegments ) { this.config = config; this.zkPaths = zkPaths; this.configManager = configManager; - this.segmentsMetadata = segmentsMetadata; + this.segmentsMetadataManager = segmentsMetadataManager; this.serverInventoryView = serverInventoryView; this.metadataRuleManager = metadataRuleManager; this.curator = curator; @@ -229,7 +230,7 @@ public DruidCoordinator( this.taskMaster = taskMaster; this.serviceAnnouncer = serviceAnnouncer; this.self = self; - this.indexingServiceHelpers = indexingServiceHelpers; + this.indexingServiceDuties = indexingServiceDuties; this.exec = scheduledExecutorFactory.create(1, "Coordinator-Exec--%d"); @@ -238,7 +239,7 @@ public DruidCoordinator( this.lookupCoordinatorManager = lookupCoordinatorManager; this.coordLeaderSelector = coordLeaderSelector; - this.segmentCompactor = segmentCompactor; + this.compactSegments = compactSegments; } public boolean isLeader() @@ -262,7 +263,7 @@ public Map> computeUnderReplicationCountsPerDataS return underReplicationCountsPerDataSourcePerTier; } - final Iterable dataSegments = segmentsMetadata.iterateAllUsedSegments(); + final Iterable dataSegments = segmentsMetadataManager.iterateAllUsedSegments(); final DateTime now = DateTimes.nowUtc(); @@ -298,7 +299,7 @@ public Object2IntMap computeNumsUnavailableUsedSegmentsPerDataSource() final Object2IntOpenHashMap numsUnavailableUsedSegmentsPerDataSource = new Object2IntOpenHashMap<>(); - final Iterable dataSegments = segmentsMetadata.iterateAllUsedSegments(); + final Iterable dataSegments = segmentsMetadataManager.iterateAllUsedSegments(); for (DataSegment segment : dataSegments) { if (segmentReplicantLookup.getLoadedReplicants(segment.getId()) == 0) { @@ -315,7 +316,7 @@ public Map getLoadStatus() { final Map loadStatus = new HashMap<>(); final Collection dataSources = - segmentsMetadata.getImmutableDataSourcesWithAllUsedSegments(); + segmentsMetadataManager.getImmutableDataSourcesWithAllUsedSegments(); for (ImmutableDruidDataSource dataSource : dataSources) { final Set segments = Sets.newHashSet(dataSource.getSegments()); @@ -342,9 +343,10 @@ public Map getLoadStatus() return loadStatus; } - public long remainingSegmentSizeBytesForCompaction(String dataSource) + @Nullable + public Long getTotalSizeOfSegmentsAwaitingCompaction(String dataSource) { - return segmentCompactor.getRemainingSegmentSizeBytes(dataSource); + return compactSegments.getTotalSizeOfSegmentsAwaitingCompaction(dataSource); } public CoordinatorDynamicConfig getDynamicConfigs() @@ -360,7 +362,7 @@ public CoordinatorCompactionConfig getCompactionConfig() public void markSegmentAsUnused(DataSegment segment) { log.debug("Marking segment[%s] as unused", segment.getId()); - segmentsMetadata.markSegmentAsUnused(segment.getId().toString()); + segmentsMetadataManager.markSegmentAsUnused(segment.getId().toString()); } public String getCurrentLeader() @@ -394,8 +396,8 @@ public void moveSegment( throw new IAE("Unable to find dataSource for segment [%s] in metadata", segmentId); } - // get segment information from MetadataSegmentManager instead of getting it from fromServer's. - // This is useful when MetadataSegmentManager and fromServer DataSegment's are different for same + // get segment information from SegmentsMetadataManager instead of getting it from fromServer's. + // This is useful when SegmentsMetadataManager and fromServer DataSegment's are different for same // identifier (say loadSpec differs because of deep storage migration). final DataSegment segmentToLoad = dataSource.getSegment(segment.getId()); if (segmentToLoad == null) { @@ -523,39 +525,36 @@ private void becomeLeader() config.getCoordinatorStartDelay() ); - segmentsMetadata.startPollingDatabasePeriodically(); + segmentsMetadataManager.startPollingDatabasePeriodically(); metadataRuleManager.start(); lookupCoordinatorManager.start(); serviceAnnouncer.announce(self); final int startingLeaderCounter = coordLeaderSelector.localTerm(); - final List> coordinatorRunnables = new ArrayList<>(); - coordinatorRunnables.add( + final List> dutiesRunnables = new ArrayList<>(); + dutiesRunnables.add( Pair.of( - new CoordinatorHistoricalManagerRunnable(startingLeaderCounter), + new DutiesRunnable(makeHistoricalManagementDuties(), startingLeaderCounter), config.getCoordinatorPeriod() ) ); if (indexingServiceClient != null) { - coordinatorRunnables.add( + dutiesRunnables.add( Pair.of( - new CoordinatorIndexingServiceRunnable( - makeIndexingServiceHelpers(), - startingLeaderCounter - ), + new DutiesRunnable(makeIndexingServiceDuties(), startingLeaderCounter), config.getCoordinatorIndexingPeriod() ) ); } - for (final Pair coordinatorRunnable : coordinatorRunnables) { + for (final Pair dutiesRunnable : dutiesRunnables) { ScheduledExecutors.scheduleWithFixedDelay( exec, config.getCoordinatorStartDelay(), - coordinatorRunnable.rhs, + dutiesRunnable.rhs, new Callable() { - private final CoordinatorRunnable theRunnable = coordinatorRunnable.lhs; + private final DutiesRunnable theRunnable = dutiesRunnable.lhs; @Override public ScheduledExecutors.Signal call() @@ -591,33 +590,46 @@ private void stopBeingLeader() serviceAnnouncer.unannounce(self); lookupCoordinatorManager.stop(); metadataRuleManager.stop(); - segmentsMetadata.stopPollingDatabasePeriodically(); + segmentsMetadataManager.stopPollingDatabasePeriodically(); } } - private List makeIndexingServiceHelpers() + private List makeHistoricalManagementDuties() { - List helpers = new ArrayList<>(); - helpers.add(new DruidCoordinatorSegmentInfoLoader(DruidCoordinator.this)); - helpers.add(segmentCompactor); - helpers.addAll(indexingServiceHelpers); + return ImmutableList.of( + new LogUsedSegments(), + new UpdateCoordinatorStateAndPrepareCluster(), + new RunRules(DruidCoordinator.this), + new UnloadUnusedSegments(), + new MarkAsUnusedOvershadowedSegments(DruidCoordinator.this), + new BalanceSegments(DruidCoordinator.this), + new EmitClusterStatsAndMetrics(DruidCoordinator.this) + ); + } + + private List makeIndexingServiceDuties() + { + List duties = new ArrayList<>(); + duties.add(new LogUsedSegments()); + duties.add(compactSegments); + duties.addAll(indexingServiceDuties); log.debug( - "Done making indexing service helpers %s", - helpers.stream().map(helper -> helper.getClass().getName()).collect(Collectors.toList()) + "Done making indexing service duties %s", + duties.stream().map(duty -> duty.getClass().getName()).collect(Collectors.toList()) ); - return ImmutableList.copyOf(helpers); + return ImmutableList.copyOf(duties); } - public abstract class CoordinatorRunnable implements Runnable + public class DutiesRunnable implements Runnable { private final long startTimeNanos = System.nanoTime(); - private final List helpers; + private final List duties; private final int startingLeaderCounter; - protected CoordinatorRunnable(List helpers, final int startingLeaderCounter) + protected DutiesRunnable(List duties, final int startingLeaderCounter) { - this.helpers = helpers; + this.duties = duties; this.startingLeaderCounter = startingLeaderCounter; } @@ -635,7 +647,7 @@ public void run() } List allStarted = Arrays.asList( - segmentsMetadata.isPollingDatabasePeriodically(), + segmentsMetadataManager.isPollingDatabasePeriodically(), serverInventoryView.isStarted() ); for (Boolean aBoolean : allStarted) { @@ -653,11 +665,12 @@ public void run() BalancerStrategy balancerStrategy = factory.createBalancerStrategy(balancerExec); // Do coordinator stuff. - DataSourcesSnapshot dataSourcesSnapshot = segmentsMetadata.getSnapshotOfDataSourcesWithAllUsedSegments(); + DataSourcesSnapshot dataSourcesSnapshot = segmentsMetadataManager.getSnapshotOfDataSourcesWithAllUsedSegments(); DruidCoordinatorRuntimeParams params = DruidCoordinatorRuntimeParams .newBuilder() + .withDatabaseRuleManager(metadataRuleManager) .withStartTimeNanos(startTimeNanos) .withSnapshotOfDataSourcesWithAllUsedSegments(dataSourcesSnapshot) .withDynamicConfigs(getDynamicConfigs()) @@ -665,14 +678,13 @@ public void run() .withEmitter(emitter) .withBalancerStrategy(balancerStrategy) .build(); - - for (DruidCoordinatorHelper helper : helpers) { - // Don't read state and run state in the same helper otherwise racy conditions may exist + for (CoordinatorDuty duty : duties) { + // Don't read state and run state in the same duty otherwise racy conditions may exist if (coordLeaderSelector.isLeader() && startingLeaderCounter == coordLeaderSelector.localTerm()) { - params = helper.run(params); + params = duty.run(params); if (params == null) { - // This helper wanted to cancel the run. No log message, since the helper should have logged a reason. + // This duty wanted to cancel the run. No log message, since the duty should have logged a reason. return; } } @@ -689,91 +701,97 @@ public void run() } } - private class CoordinatorHistoricalManagerRunnable extends CoordinatorRunnable + /** + * Updates the enclosing {@link DruidCoordinator}'s state and prepares an immutable view of the cluster state (which + * consists of {@link DruidCluster} and {@link SegmentReplicantLookup}) and feeds it into {@link + * DruidCoordinatorRuntimeParams} for use in subsequent {@link CoordinatorDuty}s (see the order in {@link + * #makeHistoricalManagementDuties()}). + */ + private class UpdateCoordinatorStateAndPrepareCluster implements CoordinatorDuty { - public CoordinatorHistoricalManagerRunnable(final int startingLeaderCounter) + @Nullable + @Override + public DruidCoordinatorRuntimeParams run(DruidCoordinatorRuntimeParams params) { - super( - ImmutableList.of( - new DruidCoordinatorSegmentInfoLoader(DruidCoordinator.this), - params -> { - List servers = serverInventoryView - .getInventory() - .stream() - .filter(DruidServer::segmentReplicatable) - .map(DruidServer::toImmutableDruidServer) - .collect(Collectors.toList()); - - if (log.isDebugEnabled()) { - // Display info about all historical servers - log.debug("Servers"); - for (ImmutableDruidServer druidServer : servers) { - log.debug(" %s", druidServer); - log.debug(" -- DataSources"); - for (ImmutableDruidDataSource druidDataSource : druidServer.getDataSources()) { - log.debug(" %s", druidDataSource); - } - } - } + List currentServers = prepareCurrentServers(); - // Find all historical servers, group them by subType and sort by ascending usage - Set decommissioningServers = params.getCoordinatorDynamicConfig().getDecommissioningNodes(); - final DruidCluster cluster = new DruidCluster(); - for (ImmutableDruidServer server : servers) { - if (!loadManagementPeons.containsKey(server.getName())) { - LoadQueuePeon loadQueuePeon = taskMaster.giveMePeon(server); - loadQueuePeon.start(); - log.debug("Created LoadQueuePeon for server[%s].", server.getName()); - - loadManagementPeons.put(server.getName(), loadQueuePeon); - } - - cluster.add( - new ServerHolder( - server, - loadManagementPeons.get(server.getName()), - decommissioningServers.contains(server.getHost()) - ) - ); - } + startPeonsForNewServers(currentServers); - segmentReplicantLookup = SegmentReplicantLookup.make(cluster); + final DruidCluster cluster = prepareCluster(params, currentServers); + segmentReplicantLookup = SegmentReplicantLookup.make(cluster); - // Stop peons for servers that aren't there anymore. - final Set disappeared = Sets.newHashSet(loadManagementPeons.keySet()); - for (ImmutableDruidServer server : servers) { - disappeared.remove(server.getName()); - } - for (String name : disappeared) { - log.debug("Removing listener for server[%s] which is no longer there.", name); - LoadQueuePeon peon = loadManagementPeons.remove(name); - peon.stop(); - } + stopPeonsForDisappearedServers(currentServers); - return params.buildFromExisting() - .withDruidCluster(cluster) - .withDatabaseRuleManager(metadataRuleManager) - .withLoadManagementPeons(loadManagementPeons) - .withSegmentReplicantLookup(segmentReplicantLookup) - .withBalancerReferenceTimestamp(DateTimes.nowUtc()) - .build(); - }, - new DruidCoordinatorRuleRunner(DruidCoordinator.this), - new DruidCoordinatorCleanupUnneeded(), - new DruidCoordinatorCleanupOvershadowed(DruidCoordinator.this), - new DruidCoordinatorBalancer(DruidCoordinator.this), - new DruidCoordinatorLogger(DruidCoordinator.this) - ), - startingLeaderCounter - ); + return params.buildFromExisting() + .withDruidCluster(cluster) + .withLoadManagementPeons(loadManagementPeons) + .withSegmentReplicantLookup(segmentReplicantLookup) + .withBalancerReferenceTimestamp(DateTimes.nowUtc()) + .build(); } - } - private class CoordinatorIndexingServiceRunnable extends CoordinatorRunnable - { - public CoordinatorIndexingServiceRunnable(List helpers, final int startingLeaderCounter) + List prepareCurrentServers() + { + List currentServers = serverInventoryView + .getInventory() + .stream() + .filter(DruidServer::segmentReplicatable) + .map(DruidServer::toImmutableDruidServer) + .collect(Collectors.toList()); + + if (log.isDebugEnabled()) { + // Display info about all segment-replicatable (historical and bridge) servers + log.debug("Servers"); + for (ImmutableDruidServer druidServer : currentServers) { + log.debug(" %s", druidServer); + log.debug(" -- DataSources"); + for (ImmutableDruidDataSource druidDataSource : druidServer.getDataSources()) { + log.debug(" %s", druidDataSource); + } + } + } + return currentServers; + } + + void startPeonsForNewServers(List currentServers) { - super(helpers, startingLeaderCounter); + for (ImmutableDruidServer server : currentServers) { + loadManagementPeons.computeIfAbsent(server.getName(), serverName -> { + LoadQueuePeon loadQueuePeon = taskMaster.giveMePeon(server); + loadQueuePeon.start(); + log.debug("Created LoadQueuePeon for server[%s].", server.getName()); + return loadQueuePeon; + }); + } + } + + DruidCluster prepareCluster(DruidCoordinatorRuntimeParams params, List currentServers) + { + Set decommissioningServers = params.getCoordinatorDynamicConfig().getDecommissioningNodes(); + final DruidCluster cluster = new DruidCluster(); + for (ImmutableDruidServer server : currentServers) { + cluster.add( + new ServerHolder( + server, + loadManagementPeons.get(server.getName()), + decommissioningServers.contains(server.getHost()) + ) + ); + } + return cluster; + } + + void stopPeonsForDisappearedServers(List servers) + { + final Set disappeared = Sets.newHashSet(loadManagementPeons.keySet()); + for (ImmutableDruidServer server : servers) { + disappeared.remove(server.getName()); + } + for (String name : disappeared) { + log.debug("Removing listener for server[%s] which is no longer there.", name); + LoadQueuePeon peon = loadManagementPeons.remove(name); + peon.stop(); + } } } } diff --git a/server/src/main/java/org/apache/druid/server/coordinator/DruidCoordinatorRuntimeParams.java b/server/src/main/java/org/apache/druid/server/coordinator/DruidCoordinatorRuntimeParams.java index d96a7a9ad974..7bae11e61db0 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/DruidCoordinatorRuntimeParams.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/DruidCoordinatorRuntimeParams.java @@ -43,6 +43,8 @@ public class DruidCoordinatorRuntimeParams { /** + * Creates a Set to be assigned into {@link Builder#usedSegments} from the given {@link Iterable} of segments. + * * Creates a TreeSet sorted in {@link DruidCoordinator#SEGMENT_COMPARATOR_RECENT_FIRST} order and populates it with * the segments from the given iterable. The given iterable is iterated exactly once. No special action is taken if * duplicate segments are encountered in the iterable. @@ -189,6 +191,7 @@ public boolean coordinatorIsLeadingEnoughTimeToMarkAsUnusedOvershadowedSegements public DataSourcesSnapshot getDataSourcesSnapshot() { + Preconditions.checkState(dataSourcesSnapshot != null, "usedSegments or dataSourcesSnapshot must be set"); return dataSourcesSnapshot; } diff --git a/server/src/main/java/org/apache/druid/server/coordinator/DruidCoordinatorCleanupPendingSegments.java b/server/src/main/java/org/apache/druid/server/coordinator/KillStalePendingSegments.java similarity index 90% rename from server/src/main/java/org/apache/druid/server/coordinator/DruidCoordinatorCleanupPendingSegments.java rename to server/src/main/java/org/apache/druid/server/coordinator/KillStalePendingSegments.java index 07cb037f6f0c..f9da22e9a71d 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/DruidCoordinatorCleanupPendingSegments.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/KillStalePendingSegments.java @@ -26,22 +26,22 @@ import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.guava.Comparators; import org.apache.druid.java.util.common.logger.Logger; -import org.apache.druid.server.coordinator.helper.DruidCoordinatorHelper; +import org.apache.druid.server.coordinator.duty.CoordinatorDuty; import org.joda.time.DateTime; import org.joda.time.Period; import java.util.ArrayList; import java.util.List; -public class DruidCoordinatorCleanupPendingSegments implements DruidCoordinatorHelper +public class KillStalePendingSegments implements CoordinatorDuty { - private static final Logger log = new Logger(DruidCoordinatorCleanupPendingSegments.class); + private static final Logger log = new Logger(KillStalePendingSegments.class); private static final Period KEEP_PENDING_SEGMENTS_OFFSET = new Period("P1D"); private final IndexingServiceClient indexingServiceClient; @Inject - public DruidCoordinatorCleanupPendingSegments(IndexingServiceClient indexingServiceClient) + public KillStalePendingSegments(IndexingServiceClient indexingServiceClient) { this.indexingServiceClient = indexingServiceClient; } diff --git a/server/src/main/java/org/apache/druid/server/coordinator/UserCompactionTaskQueryTuningConfig.java b/server/src/main/java/org/apache/druid/server/coordinator/UserCompactionTaskQueryTuningConfig.java new file mode 100644 index 000000000000..7671fa5bf19c --- /dev/null +++ b/server/src/main/java/org/apache/druid/server/coordinator/UserCompactionTaskQueryTuningConfig.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.server.coordinator; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.druid.client.indexing.ClientCompactionTaskQueryTuningConfig; +import org.apache.druid.data.input.SplitHintSpec; +import org.apache.druid.segment.IndexSpec; + +import javax.annotation.Nullable; + +public class UserCompactionTaskQueryTuningConfig extends ClientCompactionTaskQueryTuningConfig +{ + @JsonCreator + public UserCompactionTaskQueryTuningConfig( + @JsonProperty("maxRowsInMemory") @Nullable Integer maxRowsInMemory, + @JsonProperty("maxBytesInMemory") @Nullable Long maxBytesInMemory, + @JsonProperty("maxTotalRows") @Nullable Long maxTotalRows, + @JsonProperty("splitHintSpec") @Nullable SplitHintSpec splitHintSpec, + @JsonProperty("indexSpec") @Nullable IndexSpec indexSpec, + @JsonProperty("maxPendingPersists") @Nullable Integer maxPendingPersists, + @JsonProperty("pushTimeout") @Nullable Long pushTimeout, + @JsonProperty("maxNumConcurrentSubTasks") @Nullable Integer maxNumConcurrentSubTasks + ) + { + super( + null, + maxRowsInMemory, + maxBytesInMemory, + maxTotalRows, + splitHintSpec, + indexSpec, + maxPendingPersists, + pushTimeout, + maxNumConcurrentSubTasks + ); + } + + @Override + @Nullable + @JsonIgnore + public Integer getMaxRowsPerSegment() + { + throw new UnsupportedOperationException(); + } +} diff --git a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorBalancer.java b/server/src/main/java/org/apache/druid/server/coordinator/duty/BalanceSegments.java similarity index 96% rename from server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorBalancer.java rename to server/src/main/java/org/apache/druid/server/coordinator/duty/BalanceSegments.java index dc164c890eef..70c38131c4a8 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorBalancer.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/duty/BalanceSegments.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import com.google.common.collect.Lists; import org.apache.druid.client.ImmutableDruidServer; @@ -46,19 +46,16 @@ /** */ -public class DruidCoordinatorBalancer implements DruidCoordinatorHelper +public class BalanceSegments implements CoordinatorDuty { - - protected static final EmittingLogger log = new EmittingLogger(DruidCoordinatorBalancer.class); + protected static final EmittingLogger log = new EmittingLogger(BalanceSegments.class); protected final DruidCoordinator coordinator; protected final Map> currentlyMovingSegments = new HashMap<>(); - public DruidCoordinatorBalancer( - DruidCoordinator coordinator - ) + public BalanceSegments(DruidCoordinator coordinator) { this.coordinator = coordinator; } @@ -195,11 +192,11 @@ private Pair balanceServers( log.info("All servers to move segments from are empty, ending run."); break; } - // DruidCoordinatorRuntimeParams.getUsedSegments originate from SegmentsMetadata, i. e. that's a set of segments + // DruidCoordinatorRuntimeParams.getUsedSegments originate from SegmentsMetadataManager, i. e. that's a set of segments // that *should* be loaded. segmentToMoveHolder.getSegment originates from ServerInventoryView, i. e. that may be // any segment that happens to be loaded on some server, even if it is not used. (Coordinator closes such - // discrepancies eventually via DruidCoordinatorUnloadUnusedSegments). Therefore the picked segmentToMoveHolder's - // segment may not need to be balanced. + // discrepancies eventually via UnloadUnusedSegments). Therefore the picked segmentToMoveHolder's segment may not + // need to be balanced. boolean needToBalancePickedSegment = params.getUsedSegments().contains(segmentToMoveHolder.getSegment()); if (needToBalancePickedSegment) { final DataSegment segmentToMove = segmentToMoveHolder.getSegment(); diff --git a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorSegmentCompactor.java b/server/src/main/java/org/apache/druid/server/coordinator/duty/CompactSegments.java similarity index 70% rename from server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorSegmentCompactor.java rename to server/src/main/java/org/apache/druid/server/coordinator/duty/CompactSegments.java index ae9a9ac88fb3..231ca21b5fae 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorSegmentCompactor.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/duty/CompactSegments.java @@ -17,19 +17,19 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.Iterables; import com.google.inject.Inject; -import it.unimi.dsi.fastutil.objects.Object2LongMap; -import org.apache.druid.client.indexing.ClientCompactQuery; -import org.apache.druid.client.indexing.ClientCompactQueryTuningConfig; +import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; +import org.apache.druid.client.indexing.ClientCompactionTaskQuery; +import org.apache.druid.client.indexing.ClientCompactionTaskQueryTuningConfig; import org.apache.druid.client.indexing.IndexingServiceClient; import org.apache.druid.client.indexing.TaskPayloadResponse; import org.apache.druid.indexer.TaskStatusPlus; import org.apache.druid.java.util.common.ISE; import org.apache.druid.java.util.common.logger.Logger; +import org.apache.druid.segment.SegmentUtils; import org.apache.druid.server.coordinator.CoordinatorCompactionConfig; import org.apache.druid.server.coordinator.CoordinatorStats; import org.apache.druid.server.coordinator.DataSourceCompactionConfig; @@ -46,24 +46,25 @@ import java.util.function.Function; import java.util.stream.Collectors; -public class DruidCoordinatorSegmentCompactor implements DruidCoordinatorHelper +public class CompactSegments implements CoordinatorDuty { - static final String COMPACT_TASK_COUNT = "compactTaskCount"; - static final String SEGMENT_SIZE_WAIT_COMPACT = "segmentSizeWaitCompact"; + static final String COMPACTION_TASK_COUNT = "compactTaskCount"; + static final String TOTAL_SIZE_OF_SEGMENTS_AWAITING_COMPACTION = "segmentSizeWaitCompact"; - // Should be synced with CompactionTask.TYPE - private static final String COMPACT_TASK_TYPE = "compact"; - // Should be synced with Tasks.STORE_COMPACTION_STATE_KEY - private static final String STORE_COMPACTION_STATE_KEY = "storeCompactionState"; - private static final Logger LOG = new Logger(DruidCoordinatorSegmentCompactor.class); + /** Must be synced with org.apache.druid.indexing.common.task.CompactionTask.TYPE. */ + public static final String COMPACTION_TASK_TYPE = "compact"; + /** Must be synced with org.apache.druid.indexing.common.task.Tasks.STORE_COMPACTION_STATE_KEY */ + public static final String STORE_COMPACTION_STATE_KEY = "storeCompactionState"; + + private static final Logger LOG = new Logger(CompactSegments.class); private final CompactionSegmentSearchPolicy policy; private final IndexingServiceClient indexingServiceClient; - private Object2LongMap remainingSegmentSizeBytes; + private Object2LongOpenHashMap totalSizesOfSegmentsAwaitingCompactionPerDataSource; @Inject - public DruidCoordinatorSegmentCompactor( + public CompactSegments( ObjectMapper objectMapper, IndexingServiceClient indexingServiceClient ) @@ -75,7 +76,7 @@ public DruidCoordinatorSegmentCompactor( @Override public DruidCoordinatorRuntimeParams run(DruidCoordinatorRuntimeParams params) { - LOG.info("Run coordinator segment compactor"); + LOG.info("Compact segments"); final CoordinatorCompactionConfig dynamicConfig = params.getCoordinatorCompactionConfig(); final CoordinatorStats stats = new CoordinatorStats(); @@ -89,27 +90,28 @@ public DruidCoordinatorRuntimeParams run(DruidCoordinatorRuntimeParams params) Map compactionConfigs = compactionConfigList .stream() .collect(Collectors.toMap(DataSourceCompactionConfig::getDataSource, Function.identity())); - final List compactTasks = filterNonCompactTasks(indexingServiceClient.getActiveTasks()); - // dataSource -> list of intervals of compact tasks - final Map> compactTaskIntervals = new HashMap<>(compactionConfigList.size()); + final List compactionTasks = filterNonCompactionTasks(indexingServiceClient.getActiveTasks()); + // dataSource -> list of intervals of compaction tasks + final Map> compactionTaskIntervals = new HashMap<>(compactionConfigList.size()); int numEstimatedNonCompleteCompactionTasks = 0; - for (TaskStatusPlus status : compactTasks) { + for (TaskStatusPlus status : compactionTasks) { final TaskPayloadResponse response = indexingServiceClient.getTaskPayload(status.getId()); if (response == null) { throw new ISE("WTH? got a null paylord from overlord for task[%s]", status.getId()); } - if (COMPACT_TASK_TYPE.equals(response.getPayload().getType())) { - final ClientCompactQuery compactQuery = (ClientCompactQuery) response.getPayload(); - final Interval interval = compactQuery.getIoConfig().getInputSpec().getInterval(); - compactTaskIntervals.computeIfAbsent(status.getDataSource(), k -> new ArrayList<>()).add(interval); - final int numSubTasks = findNumMaxConcurrentSubTasks(compactQuery.getTuningConfig()); + if (COMPACTION_TASK_TYPE.equals(response.getPayload().getType())) { + final ClientCompactionTaskQuery compactionTaskQuery = (ClientCompactionTaskQuery) response.getPayload(); + final Interval interval = compactionTaskQuery.getIoConfig().getInputSpec().getInterval(); + compactionTaskIntervals.computeIfAbsent(status.getDataSource(), k -> new ArrayList<>()).add(interval); + final int numSubTasks = findNumMaxConcurrentSubTasks(compactionTaskQuery.getTuningConfig()); numEstimatedNonCompleteCompactionTasks += numSubTasks + 1; // count the compaction task itself } else { - throw new ISE("WTH? task[%s] is not a compactTask?", status.getId()); + throw new ISE("WTH? task[%s] is not a compactionTask?", status.getId()); } } - final CompactionSegmentIterator iterator = policy.reset(compactionConfigs, dataSources, compactTaskIntervals); + final CompactionSegmentIterator iterator = + policy.reset(compactionConfigs, dataSources, compactionTaskIntervals); final int compactionTaskCapacity = (int) Math.min( indexingServiceClient.getTotalWorkerCapacity() * dynamicConfig.getCompactionTaskSlotRatio(), @@ -124,7 +126,7 @@ public DruidCoordinatorRuntimeParams run(DruidCoordinatorRuntimeParams params) } else { // compactionTaskCapacity might be 0 if totalWorkerCapacity is low. // This guarantees that at least one slot is available if - // compaction is enabled and numRunningCompactTasks is 0. + // compaction is enabled and numEstimatedNonCompleteCompactionTasks is 0. numAvailableCompactionTaskSlots = Math.max(1, compactionTaskCapacity); } @@ -158,7 +160,7 @@ public DruidCoordinatorRuntimeParams run(DruidCoordinatorRuntimeParams params) * to estimate the number of sub tasks conservatively. This should be ok since it won't affect to the performance of * other ingestion types. */ - private int findNumMaxConcurrentSubTasks(@Nullable ClientCompactQueryTuningConfig tuningConfig) + private int findNumMaxConcurrentSubTasks(@Nullable ClientCompactionTaskQueryTuningConfig tuningConfig) { if (tuningConfig != null && tuningConfig.getMaxNumConcurrentSubTasks() != null) { // The actual number of subtasks might be smaller than the configured max. @@ -169,7 +171,7 @@ private int findNumMaxConcurrentSubTasks(@Nullable ClientCompactQueryTuningConfi } } - private static List filterNonCompactTasks(List taskStatuses) + private static List filterNonCompactionTasks(List taskStatuses) { return taskStatuses .stream() @@ -179,7 +181,7 @@ private static List filterNonCompactTasks(List t // the tasks of the unknown taskType as the compactionTask. This is because it's important to not run // compactionTasks more than the configured limit at any time which might impact to the ingestion // performance. - return taskType == null || COMPACT_TASK_TYPE.equals(taskType); + return taskType == null || COMPACTION_TASK_TYPE.equals(taskType); }) .collect(Collectors.toList()); } @@ -202,13 +204,13 @@ private CoordinatorStats doRun( final String taskId = indexingServiceClient.compactSegments( segmentsToCompact, config.getTaskPriority(), - ClientCompactQueryTuningConfig.from(config.getTuningConfig(), config.getMaxRowsPerSegment()), + ClientCompactionTaskQueryTuningConfig.from(config.getTuningConfig(), config.getMaxRowsPerSegment()), newAutoCompactionContext(config.getTaskContext()) ); LOG.info( - "Submitted a compactTask[%s] for segments %s", + "Submitted a compactionTask[%s] for segments %s", taskId, - Iterables.transform(segmentsToCompact, DataSegment::getId) + SegmentUtils.commaSeparatedIdentifiers(segmentsToCompact) ); // Count the compaction task itself + its sub tasks numSubmittedTasks += findNumMaxConcurrentSubTasks(config.getTuningConfig()) + 1; @@ -232,20 +234,26 @@ private Map newAutoCompactionContext(@Nullable Map { final String dataSource = entry.getKey(); - final long numSegmentsWaitCompact = entry.getLongValue(); - stats.addToDataSourceStat(SEGMENT_SIZE_WAIT_COMPACT, dataSource, numSegmentsWaitCompact); + final long totalSizeOfSegmentsAwaitingCompaction = entry.getLongValue(); + stats.addToDataSourceStat( + TOTAL_SIZE_OF_SEGMENTS_AWAITING_COMPACTION, + dataSource, + totalSizeOfSegmentsAwaitingCompaction + ); } ); return stats; } - public long getRemainingSegmentSizeBytes(String dataSource) + @SuppressWarnings("deprecation") // Intentionally using boxing get() to return null if dataSource is unknown + @Nullable + public Long getTotalSizeOfSegmentsAwaitingCompaction(String dataSource) { - return remainingSegmentSizeBytes.getLong(dataSource); + return totalSizesOfSegmentsAwaitingCompactionPerDataSource.get(dataSource); } } diff --git a/server/src/main/java/org/apache/druid/server/coordinator/helper/CompactionSegmentIterator.java b/server/src/main/java/org/apache/druid/server/coordinator/duty/CompactionSegmentIterator.java similarity index 89% rename from server/src/main/java/org/apache/druid/server/coordinator/helper/CompactionSegmentIterator.java rename to server/src/main/java/org/apache/druid/server/coordinator/duty/CompactionSegmentIterator.java index 448b78c2dea9..0e692f2f8585 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/helper/CompactionSegmentIterator.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/duty/CompactionSegmentIterator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; import org.apache.druid.timeline.DataSegment; @@ -31,10 +31,10 @@ */ public interface CompactionSegmentIterator extends Iterator> { - long UNKNOWN_REMAINING_SEGMENT_SIZE = -1L; + long UNKNOWN_TOTAL_REMAINING_SEGMENTS_SIZE = -1L; /** * Return a map of (dataSource, total size of remaining segments) for all dataSources. * This method should consider all segments except the segments returned by {@link #next()}. */ - Object2LongOpenHashMap remainingSegmentSizeBytes(); + Object2LongOpenHashMap totalRemainingSegmentsSizeBytes(); } diff --git a/server/src/main/java/org/apache/druid/server/coordinator/helper/CompactionSegmentSearchPolicy.java b/server/src/main/java/org/apache/druid/server/coordinator/duty/CompactionSegmentSearchPolicy.java similarity index 91% rename from server/src/main/java/org/apache/druid/server/coordinator/helper/CompactionSegmentSearchPolicy.java rename to server/src/main/java/org/apache/druid/server/coordinator/duty/CompactionSegmentSearchPolicy.java index fddec4b299fd..a0d0617b401d 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/helper/CompactionSegmentSearchPolicy.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/duty/CompactionSegmentSearchPolicy.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import org.apache.druid.server.coordinator.DataSourceCompactionConfig; import org.apache.druid.timeline.DataSegment; @@ -28,7 +28,7 @@ import java.util.Map; /** - * Segment searching policy used by {@link DruidCoordinatorSegmentCompactor}. + * Segment searching policy used by {@link CompactSegments}. */ public interface CompactionSegmentSearchPolicy { diff --git a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorHelper.java b/server/src/main/java/org/apache/druid/server/coordinator/duty/CoordinatorDuty.java similarity index 72% rename from server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorHelper.java rename to server/src/main/java/org/apache/druid/server/coordinator/duty/CoordinatorDuty.java index 78ee92bde323..349a8105d79c 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorHelper.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/duty/CoordinatorDuty.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import org.apache.druid.server.coordinator.DruidCoordinatorRuntimeParams; @@ -26,17 +26,15 @@ /** * */ -public interface DruidCoordinatorHelper +public interface CoordinatorDuty { /** * Implementations of this method run various activities performed by the coordinator. - * Input params can be used and modified. They are typically in a list and returned - * DruidCoordinatorRuntimeParams is passed to the next helper. + * Input params can be used and modified. The returned DruidCoordinatorRuntimeParams is passed to the next duty. * - * @param params - * - * @return same as input or a modified value to be used by next helper. Null return - * values will prevent future DruidCoordinatorHelpers from running until the next + * @return same as input or a modified value to be used by next duty. Null return + * values will prevent subsequent CoordinatorDuty objects (see the order in the lists passed into the constructor of + * {@link org.apache.druid.server.coordinator.DruidCoordinator.DutiesRunnable}) from running until the next * cycle. */ @Nullable diff --git a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorLogger.java b/server/src/main/java/org/apache/druid/server/coordinator/duty/EmitClusterStatsAndMetrics.java similarity index 89% rename from server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorLogger.java rename to server/src/main/java/org/apache/druid/server/coordinator/duty/EmitClusterStatsAndMetrics.java index a556ed3e57c1..09164e2c8f26 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorLogger.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/duty/EmitClusterStatsAndMetrics.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2LongMap; @@ -34,22 +34,22 @@ import org.apache.druid.server.coordinator.ServerHolder; import org.apache.druid.server.coordinator.rules.LoadRule; import org.apache.druid.timeline.DataSegment; - -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; +import org.apache.druid.timeline.VersionedIntervalTimeline; /** + * Emits stats of the cluster and metrics of the coordination (including segment balancing) process. */ -public class DruidCoordinatorLogger implements DruidCoordinatorHelper +public class EmitClusterStatsAndMetrics implements CoordinatorDuty { - private static final Logger log = new Logger(DruidCoordinatorLogger.class); - private final DruidCoordinator coordinator; + private static final Logger log = new Logger(EmitClusterStatsAndMetrics.class); + public static final String TOTAL_CAPACITY = "totalCapacity"; public static final String TOTAL_HISTORICAL_COUNT = "totalHistoricalCount"; public static final String MAX_REPLICATION_FACTOR = "maxReplicationFactor"; - public DruidCoordinatorLogger(DruidCoordinator coordinator) + private final DruidCoordinator coordinator; + + public EmitClusterStatsAndMetrics(DruidCoordinator coordinator) { this.coordinator = coordinator; } @@ -291,7 +291,7 @@ public DruidCoordinatorRuntimeParams run(DruidCoordinatorRuntimeParams params) emitter.emit( new ServiceMetricEvent.Builder().build( "compact/task/count", - stats.getGlobalStat(DruidCoordinatorSegmentCompactor.COMPACT_TASK_COUNT) + stats.getGlobalStat(CompactSegments.COMPACTION_TASK_COUNT) ) ); @@ -307,25 +307,25 @@ public DruidCoordinatorRuntimeParams run(DruidCoordinatorRuntimeParams params) ); // Emit segment metrics - final Stream allSegments = params - .getUsedSegmentsTimelinesPerDataSource() - .values() - .stream() - .flatMap(timeline -> timeline.iterateAllObjects().stream()); - - allSegments - .collect(Collectors.groupingBy(DataSegment::getDataSource)) - .forEach((final String name, final List segments) -> { - final long size = segments.stream().mapToLong(DataSegment::getSize).sum(); + params.getUsedSegmentsTimelinesPerDataSource().forEach( + (String dataSource, VersionedIntervalTimeline dataSourceWithUsedSegments) -> { + long totalSizeOfUsedSegments = dataSourceWithUsedSegments + .iterateAllObjects() + .stream() + .mapToLong(DataSegment::getSize) + .sum(); emitter.emit( - new ServiceMetricEvent.Builder().setDimension(DruidMetrics.DATASOURCE, name).build("segment/size", size) + new ServiceMetricEvent.Builder() + .setDimension(DruidMetrics.DATASOURCE, dataSource) + .build("segment/size", totalSizeOfUsedSegments) ); emitter.emit( new ServiceMetricEvent.Builder() - .setDimension(DruidMetrics.DATASOURCE, name) - .build("segment/count", segments.size()) + .setDimension(DruidMetrics.DATASOURCE, dataSource) + .build("segment/count", dataSourceWithUsedSegments.getNumObjects()) ); - }); + } + ); return params; } diff --git a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorSegmentKiller.java b/server/src/main/java/org/apache/druid/server/coordinator/duty/KillUnusedSegments.java similarity index 85% rename from server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorSegmentKiller.java rename to server/src/main/java/org/apache/druid/server/coordinator/duty/KillUnusedSegments.java index 302a91d3f08b..29c3f22e6a25 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorSegmentKiller.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/duty/KillUnusedSegments.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; @@ -26,7 +26,7 @@ import org.apache.druid.java.util.common.DateTimes; import org.apache.druid.java.util.common.JodaUtils; import org.apache.druid.java.util.common.logger.Logger; -import org.apache.druid.metadata.MetadataSegmentManager; +import org.apache.druid.metadata.SegmentsMetadataManager; import org.apache.druid.server.coordinator.DruidCoordinatorConfig; import org.apache.druid.server.coordinator.DruidCoordinatorRuntimeParams; import org.joda.time.Interval; @@ -39,24 +39,23 @@ * Completely removes information about unused segments whose end time is older than {@link #retainDuration} from now * from the metadata store. This action is called "to kill a segment". * - * See org.apache.druid.indexing.common.task.KillTask + * See org.apache.druid.indexing.common.task.KillUnusedSegmentsTask. */ -public class DruidCoordinatorSegmentKiller implements DruidCoordinatorHelper +public class KillUnusedSegments implements CoordinatorDuty { - private static final Logger log = new Logger(DruidCoordinatorSegmentKiller.class); + private static final Logger log = new Logger(KillUnusedSegments.class); private final long period; private final long retainDuration; private final int maxSegmentsToKill; private long lastKillTime = 0; - - private final MetadataSegmentManager segmentsMetadata; + private final SegmentsMetadataManager segmentsMetadataManager; private final IndexingServiceClient indexingServiceClient; @Inject - public DruidCoordinatorSegmentKiller( - MetadataSegmentManager segmentsMetadata, + public KillUnusedSegments( + SegmentsMetadataManager segmentsMetadataManager, IndexingServiceClient indexingServiceClient, DruidCoordinatorConfig config ) @@ -80,7 +79,7 @@ public DruidCoordinatorSegmentKiller( this.maxSegmentsToKill ); - this.segmentsMetadata = segmentsMetadata; + this.segmentsMetadataManager = segmentsMetadataManager; this.indexingServiceClient = indexingServiceClient; } @@ -100,7 +99,7 @@ public DruidCoordinatorRuntimeParams run(DruidCoordinatorRuntimeParams params) Collection dataSourcesToKill = specificDataSourcesToKill; if (killAllDataSources) { - dataSourcesToKill = segmentsMetadata.retrieveAllDataSourceNames(); + dataSourcesToKill = segmentsMetadataManager.retrieveAllDataSourceNames(); } if (dataSourcesToKill != null && @@ -112,7 +111,7 @@ public DruidCoordinatorRuntimeParams run(DruidCoordinatorRuntimeParams params) final Interval intervalToKill = findIntervalForKill(dataSource, maxSegmentsToKill); if (intervalToKill != null) { try { - indexingServiceClient.killSegments(dataSource, intervalToKill); + indexingServiceClient.killUnusedSegments(dataSource, intervalToKill); } catch (Exception ex) { log.error(ex, "Failed to submit kill task for dataSource [%s]", dataSource); @@ -132,7 +131,7 @@ public DruidCoordinatorRuntimeParams run(DruidCoordinatorRuntimeParams params) Interval findIntervalForKill(String dataSource, int limit) { List unusedSegmentIntervals = - segmentsMetadata.getUnusedSegmentIntervals(dataSource, DateTimes.nowUtc().minus(retainDuration), limit); + segmentsMetadataManager.getUnusedSegmentIntervals(dataSource, DateTimes.nowUtc().minus(retainDuration), limit); if (unusedSegmentIntervals != null && unusedSegmentIntervals.size() > 0) { return JodaUtils.umbrellaInterval(unusedSegmentIntervals); diff --git a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorSegmentInfoLoader.java b/server/src/main/java/org/apache/druid/server/coordinator/duty/LogUsedSegments.java similarity index 80% rename from server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorSegmentInfoLoader.java rename to server/src/main/java/org/apache/druid/server/coordinator/duty/LogUsedSegments.java index e1447887ec92..03c814d944d6 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorSegmentInfoLoader.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/duty/LogUsedSegments.java @@ -17,23 +17,19 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import org.apache.druid.client.DataSourcesSnapshot; import org.apache.druid.java.util.emitter.EmittingLogger; -import org.apache.druid.server.coordinator.DruidCoordinator; import org.apache.druid.server.coordinator.DruidCoordinatorRuntimeParams; import org.apache.druid.timeline.DataSegment; -public class DruidCoordinatorSegmentInfoLoader implements DruidCoordinatorHelper +public class LogUsedSegments implements CoordinatorDuty { - private static final EmittingLogger log = new EmittingLogger(DruidCoordinatorSegmentInfoLoader.class); + private static final EmittingLogger log = new EmittingLogger(LogUsedSegments.class); - private final DruidCoordinator coordinator; - - public DruidCoordinatorSegmentInfoLoader(DruidCoordinator coordinator) + public LogUsedSegments() { - this.coordinator = coordinator; } @Override diff --git a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorCleanupOvershadowed.java b/server/src/main/java/org/apache/druid/server/coordinator/duty/MarkAsUnusedOvershadowedSegments.java similarity index 94% rename from server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorCleanupOvershadowed.java rename to server/src/main/java/org/apache/druid/server/coordinator/duty/MarkAsUnusedOvershadowedSegments.java index 9845991c7b79..febf9a4deafd 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorCleanupOvershadowed.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/duty/MarkAsUnusedOvershadowedSegments.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import org.apache.druid.client.ImmutableDruidDataSource; import org.apache.druid.client.ImmutableDruidServer; @@ -34,11 +34,11 @@ import java.util.Map; import java.util.SortedSet; -public class DruidCoordinatorCleanupOvershadowed implements DruidCoordinatorHelper +public class MarkAsUnusedOvershadowedSegments implements CoordinatorDuty { private final DruidCoordinator coordinator; - public DruidCoordinatorCleanupOvershadowed(DruidCoordinator coordinator) + public MarkAsUnusedOvershadowedSegments(DruidCoordinator coordinator) { this.coordinator = coordinator; } diff --git a/server/src/main/java/org/apache/druid/server/coordinator/helper/NewestSegmentFirstIterator.java b/server/src/main/java/org/apache/druid/server/coordinator/duty/NewestSegmentFirstIterator.java similarity index 99% rename from server/src/main/java/org/apache/druid/server/coordinator/helper/NewestSegmentFirstIterator.java rename to server/src/main/java/org/apache/druid/server/coordinator/duty/NewestSegmentFirstIterator.java index 1790abd467d9..0ca50bc368f6 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/helper/NewestSegmentFirstIterator.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/duty/NewestSegmentFirstIterator.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.annotations.VisibleForTesting; @@ -108,10 +108,10 @@ public class NewestSegmentFirstIterator implements CompactionSegmentIterator } @Override - public Object2LongOpenHashMap remainingSegmentSizeBytes() + public Object2LongOpenHashMap totalRemainingSegmentsSizeBytes() { final Object2LongOpenHashMap resultMap = new Object2LongOpenHashMap<>(); - resultMap.defaultReturnValue(UNKNOWN_REMAINING_SEGMENT_SIZE); + resultMap.defaultReturnValue(UNKNOWN_TOTAL_REMAINING_SEGMENTS_SIZE); for (QueueEntry entry : queue) { final VersionedIntervalTimeline timeline = dataSources.get(entry.getDataSource()); final Interval interval = new Interval(timeline.first().getInterval().getStart(), entry.interval.getEnd()); diff --git a/server/src/main/java/org/apache/druid/server/coordinator/helper/NewestSegmentFirstPolicy.java b/server/src/main/java/org/apache/druid/server/coordinator/duty/NewestSegmentFirstPolicy.java similarity index 97% rename from server/src/main/java/org/apache/druid/server/coordinator/helper/NewestSegmentFirstPolicy.java rename to server/src/main/java/org/apache/druid/server/coordinator/duty/NewestSegmentFirstPolicy.java index f5f74a20d191..d01170157ed8 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/helper/NewestSegmentFirstPolicy.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/duty/NewestSegmentFirstPolicy.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.druid.server.coordinator.DataSourceCompactionConfig; diff --git a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorRuleRunner.java b/server/src/main/java/org/apache/druid/server/coordinator/duty/RunRules.java similarity index 88% rename from server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorRuleRunner.java rename to server/src/main/java/org/apache/druid/server/coordinator/duty/RunRules.java index c7b3b7a7bd9e..5288bb35858f 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorRuleRunner.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/duty/RunRules.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import com.google.common.collect.Lists; import org.apache.druid.java.util.common.DateTimes; @@ -38,16 +38,16 @@ /** */ -public class DruidCoordinatorRuleRunner implements DruidCoordinatorHelper +public class RunRules implements CoordinatorDuty { - private static final EmittingLogger log = new EmittingLogger(DruidCoordinatorRuleRunner.class); + private static final EmittingLogger log = new EmittingLogger(RunRules.class); private static final int MAX_MISSING_RULES = 10; private final ReplicationThrottler replicatorThrottler; private final DruidCoordinator coordinator; - public DruidCoordinatorRuleRunner(DruidCoordinator coordinator) + public RunRules(DruidCoordinator coordinator) { this( new ReplicationThrottler( @@ -58,7 +58,7 @@ public DruidCoordinatorRuleRunner(DruidCoordinator coordinator) ); } - public DruidCoordinatorRuleRunner(ReplicationThrottler replicatorThrottler, DruidCoordinator coordinator) + public RunRules(ReplicationThrottler replicatorThrottler, DruidCoordinator coordinator) { this.replicatorThrottler = replicatorThrottler; this.coordinator = coordinator; @@ -82,8 +82,8 @@ public DruidCoordinatorRuntimeParams run(DruidCoordinatorRuntimeParams params) // Get used segments which are overshadowed by other used segments. Those would not need to be loaded and // eventually will be unloaded from Historical servers. Segments overshadowed by *served* used segments are marked - // as unused in DruidCoordinatorMarkAsUnusedOvershadowedSegments, and then eventually Coordinator sends commands to - // Historical nodes to unload such segments in DruidCoordinatorUnloadUnusedSegments. + // as unused in MarkAsUnusedOvershadowedSegments, and then eventually Coordinator sends commands to Historical nodes + // to unload such segments in UnloadUnusedSegments. Set overshadowed = params.getDataSourcesSnapshot().getOvershadowedSegments(); for (String tier : cluster.getTierNames()) { diff --git a/server/src/main/java/org/apache/druid/server/coordinator/helper/SegmentCompactorUtil.java b/server/src/main/java/org/apache/druid/server/coordinator/duty/SegmentCompactionUtil.java similarity index 87% rename from server/src/main/java/org/apache/druid/server/coordinator/helper/SegmentCompactorUtil.java rename to server/src/main/java/org/apache/druid/server/coordinator/duty/SegmentCompactionUtil.java index 3473b35abb3a..e9e573206226 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/helper/SegmentCompactorUtil.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/duty/SegmentCompactionUtil.java @@ -17,15 +17,15 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import com.google.common.base.Preconditions; import org.joda.time.Interval; /** - * Util class used by {@link DruidCoordinatorSegmentCompactor} and {@link CompactionSegmentSearchPolicy}. + * Util class used by {@link CompactSegments} and {@link CompactionSegmentSearchPolicy}. */ -class SegmentCompactorUtil +class SegmentCompactionUtil { /** * Removes {@code smallInterval} from {@code largeInterval}. The end of both intervals should be same. @@ -43,7 +43,7 @@ static Interval removeIntervalFromEnd(Interval largeInterval, Interval smallInte return new Interval(largeInterval.getStart(), smallInterval.getStart()); } - private SegmentCompactorUtil() + private SegmentCompactionUtil() { } } diff --git a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorCleanupUnneeded.java b/server/src/main/java/org/apache/druid/server/coordinator/duty/UnloadUnusedSegments.java similarity index 83% rename from server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorCleanupUnneeded.java rename to server/src/main/java/org/apache/druid/server/coordinator/duty/UnloadUnusedSegments.java index af7ccc1cd0a1..bea7a9d1cc79 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorCleanupUnneeded.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/duty/UnloadUnusedSegments.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import org.apache.druid.client.ImmutableDruidDataSource; import org.apache.druid.client.ImmutableDruidServer; @@ -33,11 +33,11 @@ import java.util.SortedSet; /** - * + * Unloads segments that are no longer marked as used from Historical servers. */ -public class DruidCoordinatorCleanupUnneeded implements DruidCoordinatorHelper +public class UnloadUnusedSegments implements CoordinatorDuty { - private static final Logger log = new Logger(DruidCoordinatorCleanupUnneeded.class); + private static final Logger log = new Logger(UnloadUnusedSegments.class); @Override public DruidCoordinatorRuntimeParams run(DruidCoordinatorRuntimeParams params) @@ -46,9 +46,6 @@ public DruidCoordinatorRuntimeParams run(DruidCoordinatorRuntimeParams params) Set usedSegments = params.getUsedSegments(); DruidCluster cluster = params.getDruidCluster(); - // Unload segments that are no longer marked as used from historical servers, *if* the usedSegments collection has - // been populated. Used segments must be already populated because otherwise the earlier helper - // DruidCoordinatorUsedSegmentsLoader would have canceled the Coordinator's run. for (SortedSet serverHolders : cluster.getSortedHistoricalsByTier()) { for (ServerHolder serverHolder : serverHolders) { ImmutableDruidServer server = serverHolder.getServer(); diff --git a/server/src/main/java/org/apache/druid/server/coordinator/rules/Rule.java b/server/src/main/java/org/apache/druid/server/coordinator/rules/Rule.java index dc12e4dc9bf3..d475f67d4c1b 100644 --- a/server/src/main/java/org/apache/druid/server/coordinator/rules/Rule.java +++ b/server/src/main/java/org/apache/druid/server/coordinator/rules/Rule.java @@ -55,10 +55,11 @@ public interface Rule * {@link DruidCoordinatorRuntimeParams#getUsedSegments()} must not be called in Rule's code, because the used * segments are not specified for the {@link DruidCoordinatorRuntimeParams} passed into Rule's code. This is because * {@link DruidCoordinatorRuntimeParams} entangles two slightly different (nonexistent yet) abstractions: - * "DruidCoordinatorHelperParams" and "RuleParams" which contain params that only {@link - * org.apache.druid.server.coordinator.helper.DruidCoordinatorHelper}s and Rules need, respectively. - * For example, {@link org.apache.druid.server.coordinator.ReplicationThrottler} needs to belong only to "RuleParams", - * but not "DruidCoordinatorHelperParams". The opposite for the collection of used segments. + * "CoordinatorDutyParams" and "RuleParams" which contain params that only {@link + * org.apache.druid.server.coordinator.duty.CoordinatorDuty} objects and Rules need, respectively. For example, + * {@link org.apache.druid.server.coordinator.ReplicationThrottler} needs to belong only to "RuleParams", but not to + * "CoordinatorDutyParams". The opposite for the collection of used segments and {@link + * org.apache.druid.client.DataSourcesSnapshot}. * * See https://github.com/apache/druid/issues/7228 */ diff --git a/server/src/main/java/org/apache/druid/server/http/CoordinatorCompactionConfigsResource.java b/server/src/main/java/org/apache/druid/server/http/CoordinatorCompactionConfigsResource.java index 8f7bf26721b8..da66b333fcb8 100644 --- a/server/src/main/java/org/apache/druid/server/http/CoordinatorCompactionConfigsResource.java +++ b/server/src/main/java/org/apache/druid/server/http/CoordinatorCompactionConfigsResource.java @@ -63,7 +63,7 @@ public CoordinatorCompactionConfigsResource(JacksonConfigManager manager) @GET @Produces(MediaType.APPLICATION_JSON) - public Response getCompactConfig() + public Response getCompactionConfig() { return Response.ok(CoordinatorCompactionConfig.current(manager)).build(); } diff --git a/server/src/main/java/org/apache/druid/server/http/CoordinatorResource.java b/server/src/main/java/org/apache/druid/server/http/CoordinatorResource.java index 9522ca87a697..c595b932b1d5 100644 --- a/server/src/main/java/org/apache/druid/server/http/CoordinatorResource.java +++ b/server/src/main/java/org/apache/druid/server/http/CoordinatorResource.java @@ -27,7 +27,6 @@ import com.sun.jersey.spi.container.ResourceFilters; import org.apache.druid.server.coordinator.DruidCoordinator; import org.apache.druid.server.coordinator.LoadQueuePeon; -import org.apache.druid.server.coordinator.helper.CompactionSegmentIterator; import org.apache.druid.server.http.security.StateResourceFilter; import org.apache.druid.timeline.DataSegment; @@ -166,12 +165,12 @@ public Object apply(LoadQueuePeon peon) @GET @Path("/remainingSegmentSizeForCompaction") @Produces(MediaType.APPLICATION_JSON) - public Response remainingSegmentSizeForCompaction( + public Response getTotalSizeOfSegmentsAwaitingCompaction( @QueryParam("dataSource") String dataSource ) { - final long notCompactedSegmentSizeBytes = coordinator.remainingSegmentSizeBytesForCompaction(dataSource); - if (notCompactedSegmentSizeBytes == CompactionSegmentIterator.UNKNOWN_REMAINING_SEGMENT_SIZE) { + final Long notCompactedSegmentSizeBytes = coordinator.getTotalSizeOfSegmentsAwaitingCompaction(dataSource); + if (notCompactedSegmentSizeBytes == null) { return Response.status(Status.BAD_REQUEST).entity(ImmutableMap.of("error", "unknown dataSource")).build(); } else { return Response.ok(ImmutableMap.of("remainingSegmentSize", notCompactedSegmentSizeBytes)).build(); diff --git a/server/src/main/java/org/apache/druid/server/http/DataSourcesResource.java b/server/src/main/java/org/apache/druid/server/http/DataSourcesResource.java index 7d4976711c35..040297521b80 100644 --- a/server/src/main/java/org/apache/druid/server/http/DataSourcesResource.java +++ b/server/src/main/java/org/apache/druid/server/http/DataSourcesResource.java @@ -44,8 +44,8 @@ import org.apache.druid.java.util.common.guava.FunctionalIterable; import org.apache.druid.java.util.common.logger.Logger; import org.apache.druid.metadata.MetadataRuleManager; -import org.apache.druid.metadata.MetadataSegmentManager; -import org.apache.druid.metadata.UnknownSegmentIdException; +import org.apache.druid.metadata.SegmentsMetadataManager; +import org.apache.druid.metadata.UnknownSegmentIdsException; import org.apache.druid.query.SegmentDescriptor; import org.apache.druid.query.TableDataSource; import org.apache.druid.server.coordination.DruidServerMetadata; @@ -98,7 +98,7 @@ public class DataSourcesResource private static final Logger log = new Logger(DataSourcesResource.class); private final CoordinatorServerView serverInventoryView; - private final MetadataSegmentManager segmentsMetadata; + private final SegmentsMetadataManager segmentsMetadataManager; private final MetadataRuleManager metadataRuleManager; private final IndexingServiceClient indexingServiceClient; private final AuthorizerMapper authorizerMapper; @@ -106,14 +106,14 @@ public class DataSourcesResource @Inject public DataSourcesResource( CoordinatorServerView serverInventoryView, - MetadataSegmentManager segmentsMetadata, + SegmentsMetadataManager segmentsMetadataManager, MetadataRuleManager metadataRuleManager, @Nullable IndexingServiceClient indexingServiceClient, AuthorizerMapper authorizerMapper ) { this.serverInventoryView = serverInventoryView; - this.segmentsMetadata = segmentsMetadata; + this.segmentsMetadataManager = segmentsMetadataManager; this.metadataRuleManager = metadataRuleManager; this.indexingServiceClient = indexingServiceClient; this.authorizerMapper = authorizerMapper; @@ -122,8 +122,8 @@ public DataSourcesResource( @GET @Produces(MediaType.APPLICATION_JSON) public Response getQueryableDataSources( - @QueryParam("full") String full, - @QueryParam("simple") String simple, + @QueryParam("full") @Nullable String full, + @QueryParam("simple") @Nullable String simple, @Context final HttpServletRequest req ) { @@ -168,7 +168,7 @@ public Response getDataSource( private interface MarkSegments { - int markSegments() throws UnknownSegmentIdException; + int markSegments() throws UnknownSegmentIdsException; } @POST @@ -177,7 +177,7 @@ private interface MarkSegments @ResourceFilters(DatasourceResourceFilter.class) public Response markAsUsedAllNonOvershadowedSegments(@PathParam("dataSourceName") final String dataSourceName) { - MarkSegments markSegments = () -> segmentsMetadata.markAsUsedAllNonOvershadowedSegmentsInDataSource(dataSourceName); + MarkSegments markSegments = () -> segmentsMetadataManager.markAsUsedAllNonOvershadowedSegmentsInDataSource(dataSourceName); return doMarkSegments("markAsUsedAllNonOvershadowedSegments", dataSourceName, markSegments); } @@ -193,10 +193,10 @@ public Response markAsUsedNonOvershadowedSegments( MarkSegments markSegments = () -> { final Interval interval = payload.getInterval(); if (interval != null) { - return segmentsMetadata.markAsUsedNonOvershadowedSegmentsInInterval(dataSourceName, interval); + return segmentsMetadataManager.markAsUsedNonOvershadowedSegmentsInInterval(dataSourceName, interval); } else { final Set segmentIds = payload.getSegmentIds(); - return segmentsMetadata.markAsUsedNonOvershadowedSegments(dataSourceName, segmentIds); + return segmentsMetadataManager.markAsUsedNonOvershadowedSegments(dataSourceName, segmentIds); } }; return doMarkSegmentsWithPayload("markAsUsedNonOvershadowedSegments", dataSourceName, payload, markSegments); @@ -215,10 +215,10 @@ public Response markSegmentsAsUnused( MarkSegments markSegments = () -> { final Interval interval = payload.getInterval(); if (interval != null) { - return segmentsMetadata.markAsUnusedSegmentsInInterval(dataSourceName, interval); + return segmentsMetadataManager.markAsUnusedSegmentsInInterval(dataSourceName, interval); } else { final Set segmentIds = payload.getSegmentIds(); - return segmentsMetadata.markSegmentsAsUnused(dataSourceName, segmentIds); + return segmentsMetadataManager.markSegmentsAsUnused(dataSourceName, segmentIds); } }; return doMarkSegmentsWithPayload("markSegmentsAsUnused", dataSourceName, payload, markSegments); @@ -259,7 +259,7 @@ private static Response doMarkSegments(String method, String dataSourceName, Mar int numChangedSegments = markSegments.markSegments(); return Response.ok(ImmutableMap.of("numChangedSegments", numChangedSegments)).build(); } - catch (UnknownSegmentIdException e) { + catch (UnknownSegmentIdsException e) { log.warn("Segment ids %s are not found", e.getUnknownSegmentIds()); return Response .status(Response.Status.NOT_FOUND) @@ -279,15 +279,15 @@ private static Response doMarkSegments(String method, String dataSourceName, Mar * When this method is removed, a new method needs to be introduced corresponding to * the end point "DELETE /druid/coordinator/v1/datasources/{dataSourceName}" (with no query parameters). * Ultimately we want to have no method with kill parameter - - * DELETE `{dataSourceName}` will be used to mark all segments belonging to a data source as unused, and - * DELETE `{dataSourceName}/intervals/{interval}` will be used to kill segments within an interval + * DELETE `{dataSourceName}` to mark all segments belonging to a data source as unused, and + * DELETE `{dataSourceName}/intervals/{interval}` to kill unused segments within an interval */ @DELETE @Deprecated @Path("/{dataSourceName}") @ResourceFilters(DatasourceResourceFilter.class) @Produces(MediaType.APPLICATION_JSON) - public Response markAsUnusedAllSegmentsOrKillSegmentsInInterval( + public Response markAsUnusedAllSegmentsOrKillUnusedSegmentsInInterval( @PathParam("dataSourceName") final String dataSourceName, @QueryParam("kill") final String kill, @QueryParam("interval") final String interval @@ -299,9 +299,9 @@ public Response markAsUnusedAllSegmentsOrKillSegmentsInInterval( boolean killSegments = kill != null && Boolean.valueOf(kill); if (killSegments) { - return killSegmentsInInterval(dataSourceName, interval); + return killUnusedSegmentsInInterval(dataSourceName, interval); } else { - MarkSegments markSegments = () -> segmentsMetadata.markAsUnusedAllSegmentsInDataSource(dataSourceName); + MarkSegments markSegments = () -> segmentsMetadataManager.markAsUnusedAllSegmentsInDataSource(dataSourceName); return doMarkSegments("markAsUnusedAllSegments", dataSourceName, markSegments); } } @@ -310,7 +310,7 @@ public Response markAsUnusedAllSegmentsOrKillSegmentsInInterval( @Path("/{dataSourceName}/intervals/{interval}") @ResourceFilters(DatasourceResourceFilter.class) @Produces(MediaType.APPLICATION_JSON) - public Response killSegmentsInInterval( + public Response killUnusedSegmentsInInterval( @PathParam("dataSourceName") final String dataSourceName, @PathParam("interval") final String interval ) @@ -323,7 +323,7 @@ public Response killSegmentsInInterval( } final Interval theInterval = Intervals.of(interval.replace('_', '/')); try { - indexingServiceClient.killSegments(dataSourceName, theInterval); + indexingServiceClient.killUnusedSegments(dataSourceName, theInterval); return Response.ok().build(); } catch (Exception e) { @@ -502,7 +502,7 @@ public Response markSegmentAsUnused( @PathParam("segmentId") String segmentId ) { - boolean segmentStateChanged = segmentsMetadata.markSegmentAsUnused(segmentId); + boolean segmentStateChanged = segmentsMetadataManager.markSegmentAsUnused(segmentId); return Response.ok(ImmutableMap.of("segmentStateChanged", segmentStateChanged)).build(); } @@ -515,7 +515,7 @@ public Response markSegmentAsUsed( @PathParam("segmentId") String segmentId ) { - boolean segmentStateChanged = segmentsMetadata.markSegmentAsUsed(segmentId); + boolean segmentStateChanged = segmentsMetadataManager.markSegmentAsUsed(segmentId); return Response.ok().entity(ImmutableMap.of("segmentStateChanged", segmentStateChanged)).build(); } diff --git a/server/src/main/java/org/apache/druid/server/http/MetadataResource.java b/server/src/main/java/org/apache/druid/server/http/MetadataResource.java index fec9556a7b60..148299b30a2e 100644 --- a/server/src/main/java/org/apache/druid/server/http/MetadataResource.java +++ b/server/src/main/java/org/apache/druid/server/http/MetadataResource.java @@ -30,7 +30,7 @@ import org.apache.druid.guice.annotations.Json; import org.apache.druid.indexing.overlord.IndexerMetadataStorageCoordinator; import org.apache.druid.indexing.overlord.Segments; -import org.apache.druid.metadata.MetadataSegmentManager; +import org.apache.druid.metadata.SegmentsMetadataManager; import org.apache.druid.server.JettyUtils; import org.apache.druid.server.http.security.DatasourceResourceFilter; import org.apache.druid.server.security.AuthorizationUtils; @@ -66,19 +66,19 @@ @Path("/druid/coordinator/v1/metadata") public class MetadataResource { - private final MetadataSegmentManager segmentsMetadata; + private final SegmentsMetadataManager segmentsMetadataManager; private final IndexerMetadataStorageCoordinator metadataStorageCoordinator; private final AuthorizerMapper authorizerMapper; @Inject public MetadataResource( - MetadataSegmentManager segmentsMetadata, + SegmentsMetadataManager segmentsMetadataManager, IndexerMetadataStorageCoordinator metadataStorageCoordinator, AuthorizerMapper authorizerMapper, @Json ObjectMapper jsonMapper ) { - this.segmentsMetadata = segmentsMetadata; + this.segmentsMetadataManager = segmentsMetadataManager; this.metadataStorageCoordinator = metadataStorageCoordinator; this.authorizerMapper = authorizerMapper; } @@ -96,9 +96,9 @@ public Response getDataSources( Collection druidDataSources = null; final TreeSet dataSourceNamesPreAuth; if (includeUnused) { - dataSourceNamesPreAuth = new TreeSet<>(segmentsMetadata.retrieveAllDataSourceNames()); + dataSourceNamesPreAuth = new TreeSet<>(segmentsMetadataManager.retrieveAllDataSourceNames()); } else { - druidDataSources = segmentsMetadata.getImmutableDataSourcesWithAllUsedSegments(); + druidDataSources = segmentsMetadataManager.getImmutableDataSourcesWithAllUsedSegments(); dataSourceNamesPreAuth = druidDataSources .stream() .map(ImmutableDruidDataSource::getName) @@ -136,7 +136,7 @@ public Response getDataSources( public Response getAllUsedSegments( @Context final HttpServletRequest req, @QueryParam("datasources") final @Nullable Set dataSources, - @QueryParam("includeOvershadowedStatus") final String includeOvershadowedStatus + @QueryParam("includeOvershadowedStatus") final @Nullable String includeOvershadowedStatus ) { if (includeOvershadowedStatus != null) { @@ -144,7 +144,7 @@ public Response getAllUsedSegments( } Collection dataSourcesWithUsedSegments = - segmentsMetadata.getImmutableDataSourcesWithAllUsedSegments(); + segmentsMetadataManager.getImmutableDataSourcesWithAllUsedSegments(); if (dataSources != null && !dataSources.isEmpty()) { dataSourcesWithUsedSegments = dataSourcesWithUsedSegments .stream() @@ -170,7 +170,7 @@ private Response getAllUsedSegmentsWithOvershadowedStatus( @Nullable Set dataSources ) { - DataSourcesSnapshot dataSourcesSnapshot = segmentsMetadata.getSnapshotOfDataSourcesWithAllUsedSegments(); + DataSourcesSnapshot dataSourcesSnapshot = segmentsMetadataManager.getSnapshotOfDataSourcesWithAllUsedSegments(); Collection dataSourcesWithUsedSegments = dataSourcesSnapshot.getDataSourcesWithAllUsedSegments(); if (dataSources != null && !dataSources.isEmpty()) { @@ -185,10 +185,7 @@ private Response getAllUsedSegmentsWithOvershadowedStatus( final Set overshadowedSegments = dataSourcesSnapshot.getOvershadowedSegments(); final Stream usedSegmentsWithOvershadowedStatus = usedSegments - .map(segment -> new SegmentWithOvershadowedStatus( - segment, - overshadowedSegments.contains(segment.getId()) - )); + .map(segment -> new SegmentWithOvershadowedStatus(segment, overshadowedSegments.contains(segment.getId()))); final Function> raGenerator = segment -> Collections .singletonList(AuthorizationUtils.DATASOURCE_READ_RA_GENERATOR.apply(segment.getDataSegment().getDataSource())); @@ -215,7 +212,7 @@ private Response getAllUsedSegmentsWithOvershadowedStatus( public Response getDataSourceWithUsedSegments(@PathParam("dataSourceName") final String dataSourceName) { ImmutableDruidDataSource dataSource = - segmentsMetadata.getImmutableDataSourceWithUsedSegments(dataSourceName); + segmentsMetadataManager.getImmutableDataSourceWithUsedSegments(dataSourceName); if (dataSource == null) { return Response.status(Response.Status.NOT_FOUND).build(); } @@ -229,11 +226,11 @@ public Response getDataSourceWithUsedSegments(@PathParam("dataSourceName") final @ResourceFilters(DatasourceResourceFilter.class) public Response getUsedSegmentsInDataSource( @PathParam("dataSourceName") String dataSourceName, - @QueryParam("full") String full + @QueryParam("full") @Nullable String full ) { ImmutableDruidDataSource dataSource = - segmentsMetadata.getImmutableDataSourceWithUsedSegments(dataSourceName); + segmentsMetadataManager.getImmutableDataSourceWithUsedSegments(dataSourceName); if (dataSource == null) { return Response.status(Response.Status.NOT_FOUND).build(); } @@ -256,12 +253,12 @@ public Response getUsedSegmentsInDataSource( @ResourceFilters(DatasourceResourceFilter.class) public Response getUsedSegmentsInDataSourceForIntervals( @PathParam("dataSourceName") String dataSourceName, - @QueryParam("full") String full, + @QueryParam("full") @Nullable String full, List intervals ) { Collection segments = metadataStorageCoordinator - .getUsedSegmentsForIntervals(dataSourceName, intervals, Segments.INCLUDING_OVERSHADOWED); + .retrieveUsedSegmentsForIntervals(dataSourceName, intervals, Segments.INCLUDING_OVERSHADOWED); Response.ResponseBuilder builder = Response.status(Response.Status.OK); if (full != null) { @@ -280,7 +277,7 @@ public Response isSegmentUsed( @PathParam("segmentId") String segmentId ) { - ImmutableDruidDataSource dataSource = segmentsMetadata.getImmutableDataSourceWithUsedSegments(dataSourceName); + ImmutableDruidDataSource dataSource = segmentsMetadataManager.getImmutableDataSourceWithUsedSegments(dataSourceName); if (dataSource == null) { return Response.status(Response.Status.NOT_FOUND).build(); } diff --git a/server/src/main/java/org/apache/druid/server/http/ServersResource.java b/server/src/main/java/org/apache/druid/server/http/ServersResource.java index 9b31a67aa13b..c6b105ad16c6 100644 --- a/server/src/main/java/org/apache/druid/server/http/ServersResource.java +++ b/server/src/main/java/org/apache/druid/server/http/ServersResource.java @@ -173,11 +173,11 @@ public Response getServerSegments(@PathParam("serverName") String serverName, @Q } if (full != null) { - return builder.entity(Iterables.toString(server.iterateAllSegments())).build(); + return builder.entity(server.iterateAllSegments()).build(); } return builder - .entity(Iterables.toString(Iterables.transform(server.iterateAllSegments(), DataSegment::getId))) + .entity(Iterables.transform(server.iterateAllSegments(), DataSegment::getId)) .build(); } diff --git a/server/src/test/java/org/apache/druid/client/indexing/ClientKillQueryTest.java b/server/src/test/java/org/apache/druid/client/indexing/ClientKillUnusedSegmentsQueryTest.java similarity index 89% rename from server/src/test/java/org/apache/druid/client/indexing/ClientKillQueryTest.java rename to server/src/test/java/org/apache/druid/client/indexing/ClientKillUnusedSegmentsQueryTest.java index 0b6c235b6a7d..b1fdcc22f8f4 100644 --- a/server/src/test/java/org/apache/druid/client/indexing/ClientKillQueryTest.java +++ b/server/src/test/java/org/apache/druid/client/indexing/ClientKillUnusedSegmentsQueryTest.java @@ -27,17 +27,18 @@ import org.junit.Before; import org.junit.Test; -public class ClientKillQueryTest +public class ClientKillUnusedSegmentsQueryTest { private static final String DATA_SOURCE = "data_source"; public static final DateTime START = DateTimes.nowUtc(); private static final Interval INTERVAL = new Interval(START, START.plus(1)); - ClientKillQuery clientKillUnusedSegmentsQuery; + + ClientKillUnusedSegmentsTaskQuery clientKillUnusedSegmentsQuery; @Before public void setUp() { - clientKillUnusedSegmentsQuery = new ClientKillQuery(DATA_SOURCE, INTERVAL); + clientKillUnusedSegmentsQuery = new ClientKillUnusedSegmentsTaskQuery(DATA_SOURCE, INTERVAL); } @After diff --git a/server/src/test/java/org/apache/druid/client/indexing/NoopIndexingServiceClient.java b/server/src/test/java/org/apache/druid/client/indexing/NoopIndexingServiceClient.java index 172a211604c5..10ae4e04cda7 100644 --- a/server/src/test/java/org/apache/druid/client/indexing/NoopIndexingServiceClient.java +++ b/server/src/test/java/org/apache/druid/client/indexing/NoopIndexingServiceClient.java @@ -33,7 +33,7 @@ public class NoopIndexingServiceClient implements IndexingServiceClient { @Override - public void killSegments(String dataSource, Interval interval) + public void killUnusedSegments(String dataSource, Interval interval) { } @@ -48,7 +48,7 @@ public int killPendingSegments(String dataSource, DateTime end) public String compactSegments( List segments, int compactionTaskPriority, - @Nullable ClientCompactQueryTuningConfig tuningConfig, + @Nullable ClientCompactionTaskQueryTuningConfig tuningConfig, @Nullable Map context ) { @@ -68,7 +68,7 @@ public String runTask(Object taskObject) } @Override - public String killTask(String taskId) + public String cancelTask(String taskId) { return null; } diff --git a/server/src/test/java/org/apache/druid/indexing/ClientCompactQueryTuningConfigTest.java b/server/src/test/java/org/apache/druid/indexing/ClientCompactQueryTuningConfigTest.java index eb7f42c7eb90..df2986cdceca 100644 --- a/server/src/test/java/org/apache/druid/indexing/ClientCompactQueryTuningConfigTest.java +++ b/server/src/test/java/org/apache/druid/indexing/ClientCompactQueryTuningConfigTest.java @@ -20,7 +20,7 @@ package org.apache.druid.indexing; import nl.jqno.equalsverifier.EqualsVerifier; -import org.apache.druid.client.indexing.ClientCompactQueryTuningConfig; +import org.apache.druid.client.indexing.ClientCompactionTaskQueryTuningConfig; import org.junit.Test; public class ClientCompactQueryTuningConfigTest @@ -29,6 +29,6 @@ public class ClientCompactQueryTuningConfigTest public void testEqualsContract() { // If this test failed, make sure to validate that toString was also updated correctly! - EqualsVerifier.forClass(ClientCompactQueryTuningConfig.class).usingGetClass().verify(); + EqualsVerifier.forClass(ClientCompactionTaskQueryTuningConfig.class).usingGetClass().verify(); } } diff --git a/server/src/test/java/org/apache/druid/metadata/IndexerSQLMetadataStorageCoordinatorTest.java b/server/src/test/java/org/apache/druid/metadata/IndexerSQLMetadataStorageCoordinatorTest.java index 1ea7f5fbcf8d..90aeb9b72a62 100644 --- a/server/src/test/java/org/apache/druid/metadata/IndexerSQLMetadataStorageCoordinatorTest.java +++ b/server/src/test/java/org/apache/druid/metadata/IndexerSQLMetadataStorageCoordinatorTest.java @@ -220,7 +220,7 @@ protected DataSourceMetadataUpdateResult updateDataSourceMetadataWithHandle( }; } - private void unUseSegment() + private void markAllSegmentsUnused() { for (final DataSegment segment : SEGMENTS) { Assert.assertEquals( @@ -243,7 +243,7 @@ public Integer withHandle(Handle handle) } } - private List getUsedSegmentIds() + private List retrieveUsedSegmentIds() { final String table = derbyConnectorRule.metadataTablesConfigSupplier().get().getSegmentsTable(); return derbyConnector.retryWithHandle( @@ -278,7 +278,7 @@ public void testSimpleAnnounce() throws IOException Assert.assertEquals( ImmutableList.of(defaultSegment.getId().toString(), defaultSegment2.getId().toString()), - getUsedSegmentIds() + retrieveUsedSegmentIds() ); // Should not update dataSource metadata. @@ -304,7 +304,7 @@ public void testOvershadowingAnnounce() throws IOException ); } - Assert.assertEquals(ImmutableList.of(defaultSegment4.getId().toString()), getUsedSegmentIds()); + Assert.assertEquals(ImmutableList.of(defaultSegment4.getId().toString()), retrieveUsedSegmentIds()); } @Test @@ -349,7 +349,7 @@ public void testTransactionalAnnounceSuccess() throws IOException // Examine metadata. Assert.assertEquals( new ObjectMetadata(ImmutableMap.of("foo", "baz")), - coordinator.getDataSourceMetadata("fooDataSource") + coordinator.retrieveDataSourceMetadata("fooDataSource") ); // Should only be tried once per call. @@ -426,7 +426,7 @@ protected DataSourceMetadataUpdateResult updateDataSourceMetadataWithHandle( // Examine metadata. Assert.assertEquals( new ObjectMetadata(ImmutableMap.of("foo", "baz")), - failOnceCoordinator.getDataSourceMetadata("fooDataSource") + failOnceCoordinator.retrieveDataSourceMetadata("fooDataSource") ); // Should be tried twice per call. @@ -496,7 +496,7 @@ public void testSimpleUsedList() throws IOException Assert.assertEquals( SEGMENTS, ImmutableSet.copyOf( - coordinator.getUsedSegmentsForInterval( + coordinator.retrieveUsedSegmentsForInterval( defaultSegment.getDataSource(), defaultSegment.getInterval(), Segments.ONLY_VISIBLE @@ -512,7 +512,7 @@ public void testMultiIntervalUsedList() throws IOException coordinator.announceHistoricalSegments(ImmutableSet.of(defaultSegment3)); Assertions.assertThat( - coordinator.getUsedSegmentsForIntervals( + coordinator.retrieveUsedSegmentsForIntervals( defaultSegment.getDataSource(), ImmutableList.of(defaultSegment.getInterval()), Segments.ONLY_VISIBLE @@ -520,7 +520,7 @@ public void testMultiIntervalUsedList() throws IOException ).containsOnlyOnce(SEGMENTS.toArray(new DataSegment[0])); Assertions.assertThat( - coordinator.getUsedSegmentsForIntervals( + coordinator.retrieveUsedSegmentsForIntervals( defaultSegment.getDataSource(), ImmutableList.of(defaultSegment3.getInterval()), Segments.ONLY_VISIBLE @@ -528,7 +528,7 @@ public void testMultiIntervalUsedList() throws IOException ).containsOnlyOnce(defaultSegment3); Assertions.assertThat( - coordinator.getUsedSegmentsForIntervals( + coordinator.retrieveUsedSegmentsForIntervals( defaultSegment.getDataSource(), ImmutableList.of(defaultSegment.getInterval(), defaultSegment3.getInterval()), Segments.ONLY_VISIBLE @@ -537,7 +537,7 @@ public void testMultiIntervalUsedList() throws IOException //case to check no duplication if two intervals overlapped with the interval of same segment. Assertions.assertThat( - coordinator.getUsedSegmentsForIntervals( + coordinator.retrieveUsedSegmentsForIntervals( defaultSegment.getDataSource(), ImmutableList.of( Intervals.of("2015-01-03T00Z/2015-01-03T05Z"), @@ -549,14 +549,14 @@ public void testMultiIntervalUsedList() throws IOException } @Test - public void testSimpleUnUsedList() throws IOException + public void testSimpleUnusedList() throws IOException { coordinator.announceHistoricalSegments(SEGMENTS); - unUseSegment(); + markAllSegmentsUnused(); Assert.assertEquals( SEGMENTS, ImmutableSet.copyOf( - coordinator.getUnusedSegmentsForInterval( + coordinator.retrieveUnusedSegmentsForInterval( defaultSegment.getDataSource(), defaultSegment.getInterval() ) @@ -570,7 +570,7 @@ public void testUsedOverlapLow() throws IOException { coordinator.announceHistoricalSegments(SEGMENTS); Set actualSegments = ImmutableSet.copyOf( - coordinator.getUsedSegmentsForInterval( + coordinator.retrieveUsedSegmentsForInterval( defaultSegment.getDataSource(), Intervals.of("2014-12-31T23:59:59.999Z/2015-01-01T00:00:00.001Z"), // end is exclusive Segments.ONLY_VISIBLE @@ -590,7 +590,7 @@ public void testUsedOverlapHigh() throws IOException Assert.assertEquals( SEGMENTS, ImmutableSet.copyOf( - coordinator.getUsedSegmentsForInterval( + coordinator.retrieveUsedSegmentsForInterval( defaultSegment.getDataSource(), Intervals.of("2015-1-1T23:59:59.999Z/2015-02-01T00Z"), Segments.ONLY_VISIBLE @@ -604,7 +604,7 @@ public void testUsedOutOfBoundsLow() throws IOException { coordinator.announceHistoricalSegments(SEGMENTS); Assert.assertTrue( - coordinator.getUsedSegmentsForInterval( + coordinator.retrieveUsedSegmentsForInterval( defaultSegment.getDataSource(), new Interval(defaultSegment.getInterval().getStart().minus(1), defaultSegment.getInterval().getStart()), Segments.ONLY_VISIBLE @@ -618,7 +618,7 @@ public void testUsedOutOfBoundsHigh() throws IOException { coordinator.announceHistoricalSegments(SEGMENTS); Assert.assertTrue( - coordinator.getUsedSegmentsForInterval( + coordinator.retrieveUsedSegmentsForInterval( defaultSegment.getDataSource(), new Interval(defaultSegment.getInterval().getEnd(), defaultSegment.getInterval().getEnd().plusDays(10)), Segments.ONLY_VISIBLE @@ -633,7 +633,7 @@ public void testUsedWithinBoundsEnd() throws IOException Assert.assertEquals( SEGMENTS, ImmutableSet.copyOf( - coordinator.getUsedSegmentsForInterval( + coordinator.retrieveUsedSegmentsForInterval( defaultSegment.getDataSource(), defaultSegment.getInterval().withEnd(defaultSegment.getInterval().getEnd().minusMillis(1)), Segments.ONLY_VISIBLE @@ -649,7 +649,7 @@ public void testUsedOverlapEnd() throws IOException Assert.assertEquals( SEGMENTS, ImmutableSet.copyOf( - coordinator.getUsedSegmentsForInterval( + coordinator.retrieveUsedSegmentsForInterval( defaultSegment.getDataSource(), defaultSegment.getInterval().withEnd(defaultSegment.getInterval().getEnd().plusMillis(1)), Segments.ONLY_VISIBLE @@ -660,12 +660,12 @@ public void testUsedOverlapEnd() throws IOException @Test - public void testUnUsedOverlapLow() throws IOException + public void testUnusedOverlapLow() throws IOException { coordinator.announceHistoricalSegments(SEGMENTS); - unUseSegment(); + markAllSegmentsUnused(); Assert.assertTrue( - coordinator.getUnusedSegmentsForInterval( + coordinator.retrieveUnusedSegmentsForInterval( defaultSegment.getDataSource(), new Interval( defaultSegment.getInterval().getStart().minus(1), @@ -676,12 +676,12 @@ public void testUnUsedOverlapLow() throws IOException } @Test - public void testUnUsedUnderlapLow() throws IOException + public void testUnusedUnderlapLow() throws IOException { coordinator.announceHistoricalSegments(SEGMENTS); - unUseSegment(); + markAllSegmentsUnused(); Assert.assertTrue( - coordinator.getUnusedSegmentsForInterval( + coordinator.retrieveUnusedSegmentsForInterval( defaultSegment.getDataSource(), new Interval(defaultSegment.getInterval().getStart().plus(1), defaultSegment.getInterval().getEnd()) ).isEmpty() @@ -690,12 +690,12 @@ public void testUnUsedUnderlapLow() throws IOException @Test - public void testUnUsedUnderlapHigh() throws IOException + public void testUnusedUnderlapHigh() throws IOException { coordinator.announceHistoricalSegments(SEGMENTS); - unUseSegment(); + markAllSegmentsUnused(); Assert.assertTrue( - coordinator.getUnusedSegmentsForInterval( + coordinator.retrieveUnusedSegmentsForInterval( defaultSegment.getDataSource(), new Interval(defaultSegment.getInterval().getStart(), defaultSegment.getInterval().getEnd().minus(1)) ).isEmpty() @@ -703,12 +703,12 @@ public void testUnUsedUnderlapHigh() throws IOException } @Test - public void testUnUsedOverlapHigh() throws IOException + public void testUnusedOverlapHigh() throws IOException { coordinator.announceHistoricalSegments(SEGMENTS); - unUseSegment(); + markAllSegmentsUnused(); Assert.assertTrue( - coordinator.getUnusedSegmentsForInterval( + coordinator.retrieveUnusedSegmentsForInterval( defaultSegment.getDataSource(), defaultSegment.getInterval().withStart(defaultSegment.getInterval().getEnd().minus(1)) ).isEmpty() @@ -716,14 +716,14 @@ public void testUnUsedOverlapHigh() throws IOException } @Test - public void testUnUsedBigOverlap() throws IOException + public void testUnusedBigOverlap() throws IOException { coordinator.announceHistoricalSegments(SEGMENTS); - unUseSegment(); + markAllSegmentsUnused(); Assert.assertEquals( SEGMENTS, ImmutableSet.copyOf( - coordinator.getUnusedSegmentsForInterval( + coordinator.retrieveUnusedSegmentsForInterval( defaultSegment.getDataSource(), Intervals.of("2000/2999") ) @@ -732,14 +732,14 @@ public void testUnUsedBigOverlap() throws IOException } @Test - public void testUnUsedLowRange() throws IOException + public void testUnusedLowRange() throws IOException { coordinator.announceHistoricalSegments(SEGMENTS); - unUseSegment(); + markAllSegmentsUnused(); Assert.assertEquals( SEGMENTS, ImmutableSet.copyOf( - coordinator.getUnusedSegmentsForInterval( + coordinator.retrieveUnusedSegmentsForInterval( defaultSegment.getDataSource(), defaultSegment.getInterval().withStart(defaultSegment.getInterval().getStart().minus(1)) ) @@ -748,7 +748,7 @@ public void testUnUsedLowRange() throws IOException Assert.assertEquals( SEGMENTS, ImmutableSet.copyOf( - coordinator.getUnusedSegmentsForInterval( + coordinator.retrieveUnusedSegmentsForInterval( defaultSegment.getDataSource(), defaultSegment.getInterval().withStart(defaultSegment.getInterval().getStart().minusYears(1)) ) @@ -757,14 +757,14 @@ public void testUnUsedLowRange() throws IOException } @Test - public void testUnUsedHighRange() throws IOException + public void testUnusedHighRange() throws IOException { coordinator.announceHistoricalSegments(SEGMENTS); - unUseSegment(); + markAllSegmentsUnused(); Assert.assertEquals( SEGMENTS, ImmutableSet.copyOf( - coordinator.getUnusedSegmentsForInterval( + coordinator.retrieveUnusedSegmentsForInterval( defaultSegment.getDataSource(), defaultSegment.getInterval().withEnd(defaultSegment.getInterval().getEnd().plus(1)) ) @@ -773,7 +773,7 @@ public void testUnUsedHighRange() throws IOException Assert.assertEquals( SEGMENTS, ImmutableSet.copyOf( - coordinator.getUnusedSegmentsForInterval( + coordinator.retrieveUnusedSegmentsForInterval( defaultSegment.getDataSource(), defaultSegment.getInterval().withEnd(defaultSegment.getInterval().getEnd().plusYears(1)) ) @@ -792,13 +792,13 @@ public void testDeleteDataSourceMetadata() throws IOException Assert.assertEquals( new ObjectMetadata(ImmutableMap.of("foo", "bar")), - coordinator.getDataSourceMetadata("fooDataSource") + coordinator.retrieveDataSourceMetadata("fooDataSource") ); Assert.assertFalse("deleteInvalidDataSourceMetadata", coordinator.deleteDataSourceMetadata("nonExistentDS")); Assert.assertTrue("deleteValidDataSourceMetadata", coordinator.deleteDataSourceMetadata("fooDataSource")); - Assert.assertNull("getDataSourceMetadataNullAfterDelete", coordinator.getDataSourceMetadata("fooDataSource")); + Assert.assertNull("getDataSourceMetadataNullAfterDelete", coordinator.retrieveDataSourceMetadata("fooDataSource")); } @Test @@ -843,7 +843,7 @@ private void additionalNumberedShardTest(Set segments) throws IOExc Assert.assertEquals( segments.stream().map(segment -> segment.getId().toString()).collect(Collectors.toList()), - getUsedSegmentIds() + retrieveUsedSegmentIds() ); // Should not update dataSource metadata. @@ -956,7 +956,7 @@ public void testDeletePendingSegment() throws InterruptedException prevSegmentId = identifier.toString(); } - final int numDeleted = coordinator.deletePendingSegments(dataSource, new Interval(begin, secondBegin)); + final int numDeleted = coordinator.deletePendingSegmentsCreatedInInterval(dataSource, new Interval(begin, secondBegin)); Assert.assertEquals(10, numDeleted); } @@ -1004,7 +1004,7 @@ public void testAllocatePendingSegmentsWithOvershadowingSegments() throws IOExce } final Collection visibleSegments = - coordinator.getUsedSegmentsForInterval(dataSource, interval, Segments.ONLY_VISIBLE); + coordinator.retrieveUsedSegmentsForInterval(dataSource, interval, Segments.ONLY_VISIBLE); Assert.assertEquals(1, visibleSegments.size()); Assert.assertEquals( diff --git a/server/src/test/java/org/apache/druid/metadata/SQLMetadataSegmentManagerEmptyTest.java b/server/src/test/java/org/apache/druid/metadata/SqlSegmentsMetadataManagerEmptyTest.java similarity index 68% rename from server/src/test/java/org/apache/druid/metadata/SQLMetadataSegmentManagerEmptyTest.java rename to server/src/test/java/org/apache/druid/metadata/SqlSegmentsMetadataManagerEmptyTest.java index 1ca5d84de29f..cd8edd6148d0 100644 --- a/server/src/test/java/org/apache/druid/metadata/SQLMetadataSegmentManagerEmptyTest.java +++ b/server/src/test/java/org/apache/druid/metadata/SqlSegmentsMetadataManagerEmptyTest.java @@ -38,28 +38,28 @@ /** * Like {@link SQLMetadataRuleManagerTest} except with no segments to make sure it behaves when it's empty */ -public class SQLMetadataSegmentManagerEmptyTest +public class SqlSegmentsMetadataManagerEmptyTest { @Rule public final TestDerbyConnector.DerbyConnectorRule derbyConnectorRule = new TestDerbyConnector.DerbyConnectorRule(); - private SQLMetadataSegmentManager sqlSegmentsMetadata; + private SqlSegmentsMetadataManager sqlSegmentsMetadataManager; private final ObjectMapper jsonMapper = TestHelper.makeJsonMapper(); @Before public void setUp() throws Exception { TestDerbyConnector connector = derbyConnectorRule.getConnector(); - MetadataSegmentManagerConfig config = new MetadataSegmentManagerConfig(); + SegmentsMetadataManagerConfig config = new SegmentsMetadataManagerConfig(); config.setPollDuration(Period.seconds(1)); - sqlSegmentsMetadata = new SQLMetadataSegmentManager( + sqlSegmentsMetadataManager = new SqlSegmentsMetadataManager( jsonMapper, Suppliers.ofInstance(config), derbyConnectorRule.metadataTablesConfigSupplier(), connector ); - sqlSegmentsMetadata.start(); + sqlSegmentsMetadataManager.start(); connector.createSegmentTable(); } @@ -67,25 +67,25 @@ public void setUp() throws Exception @After public void teardown() { - if (sqlSegmentsMetadata.isPollingDatabasePeriodically()) { - sqlSegmentsMetadata.stopPollingDatabasePeriodically(); + if (sqlSegmentsMetadataManager.isPollingDatabasePeriodically()) { + sqlSegmentsMetadataManager.stopPollingDatabasePeriodically(); } - sqlSegmentsMetadata.stop(); + sqlSegmentsMetadataManager.stop(); } @Test public void testPollEmpty() { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); Assert.assertEquals( ImmutableSet.of(), - sqlSegmentsMetadata.retrieveAllDataSourceNames() + sqlSegmentsMetadataManager.retrieveAllDataSourceNames() ); Assert.assertEquals( ImmutableList.of(), - sqlSegmentsMetadata + sqlSegmentsMetadataManager .getImmutableDataSourcesWithAllUsedSegments() .stream() .map(ImmutableDruidDataSource::getName) @@ -93,11 +93,11 @@ public void testPollEmpty() ); Assert.assertEquals( null, - sqlSegmentsMetadata.getImmutableDataSourceWithUsedSegments("wikipedia") + sqlSegmentsMetadataManager.getImmutableDataSourceWithUsedSegments("wikipedia") ); Assert.assertEquals( ImmutableSet.of(), - ImmutableSet.copyOf(sqlSegmentsMetadata.iterateAllUsedSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.iterateAllUsedSegments()) ); } @@ -105,9 +105,9 @@ public void testPollEmpty() public void testStopAndStart() { // Simulate successive losing and getting the coordinator leadership - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.stopPollingDatabasePeriodically(); - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.stopPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.stopPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.stopPollingDatabasePeriodically(); } } diff --git a/server/src/test/java/org/apache/druid/metadata/SQLMetadataSegmentManagerTest.java b/server/src/test/java/org/apache/druid/metadata/SqlSegmentsMetadataManagerTest.java similarity index 68% rename from server/src/test/java/org/apache/druid/metadata/SQLMetadataSegmentManagerTest.java rename to server/src/test/java/org/apache/druid/metadata/SqlSegmentsMetadataManagerTest.java index bbfcf137b844..be6354a63c75 100644 --- a/server/src/test/java/org/apache/druid/metadata/SQLMetadataSegmentManagerTest.java +++ b/server/src/test/java/org/apache/druid/metadata/SqlSegmentsMetadataManagerTest.java @@ -46,7 +46,7 @@ import java.util.stream.Collectors; -public class SQLMetadataSegmentManagerTest +public class SqlSegmentsMetadataManagerTest { private static DataSegment createSegment( String dataSource, @@ -76,7 +76,7 @@ private static DataSegment createSegment( @Rule public final TestDerbyConnector.DerbyConnectorRule derbyConnectorRule = new TestDerbyConnector.DerbyConnectorRule(); - private SQLMetadataSegmentManager sqlSegmentsMetadata; + private SqlSegmentsMetadataManager sqlSegmentsMetadataManager; private SQLMetadataSegmentPublisher publisher; private final ObjectMapper jsonMapper = TestHelper.makeJsonMapper(); @@ -116,15 +116,15 @@ private void publish(DataSegment segment, boolean used) throws IOException public void setUp() throws Exception { TestDerbyConnector connector = derbyConnectorRule.getConnector(); - MetadataSegmentManagerConfig config = new MetadataSegmentManagerConfig(); + SegmentsMetadataManagerConfig config = new SegmentsMetadataManagerConfig(); config.setPollDuration(Period.seconds(1)); - sqlSegmentsMetadata = new SQLMetadataSegmentManager( + sqlSegmentsMetadataManager = new SqlSegmentsMetadataManager( jsonMapper, Suppliers.ofInstance(config), derbyConnectorRule.metadataTablesConfigSupplier(), connector ); - sqlSegmentsMetadata.start(); + sqlSegmentsMetadataManager.start(); publisher = new SQLMetadataSegmentPublisher( jsonMapper, @@ -141,25 +141,25 @@ public void setUp() throws Exception @After public void teardown() { - if (sqlSegmentsMetadata.isPollingDatabasePeriodically()) { - sqlSegmentsMetadata.stopPollingDatabasePeriodically(); + if (sqlSegmentsMetadataManager.isPollingDatabasePeriodically()) { + sqlSegmentsMetadataManager.stopPollingDatabasePeriodically(); } - sqlSegmentsMetadata.stop(); + sqlSegmentsMetadataManager.stop(); } @Test public void testPoll() { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); Assert.assertEquals( ImmutableSet.of("wikipedia"), - sqlSegmentsMetadata.retrieveAllDataSourceNames() + sqlSegmentsMetadataManager.retrieveAllDataSourceNames() ); Assert.assertEquals( ImmutableList.of("wikipedia"), - sqlSegmentsMetadata + sqlSegmentsMetadataManager .getImmutableDataSourcesWithAllUsedSegments() .stream() .map(ImmutableDruidDataSource::getName) @@ -167,11 +167,11 @@ public void testPoll() ); Assert.assertEquals( ImmutableSet.of(segment1, segment2), - ImmutableSet.copyOf(sqlSegmentsMetadata.getImmutableDataSourceWithUsedSegments("wikipedia").getSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.getImmutableDataSourceWithUsedSegments("wikipedia").getSegments()) ); Assert.assertEquals( ImmutableSet.of(segment1, segment2), - ImmutableSet.copyOf(sqlSegmentsMetadata.iterateAllUsedSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.iterateAllUsedSegments()) ); } @@ -181,7 +181,7 @@ public void testPrepareImmutableDataSourceWithUsedSegmentsAwaitsPollOnRestart() DataSegment newSegment = pollThenStopThenStartIntro(); Assert.assertEquals( ImmutableSet.of(newSegment), - ImmutableSet.copyOf(sqlSegmentsMetadata.getImmutableDataSourceWithUsedSegments("wikipedia2").getSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.getImmutableDataSourceWithUsedSegments("wikipedia2").getSegments()) ); } @@ -191,7 +191,7 @@ public void testGetDataSourceWithUsedSegmentsAwaitsPollOnRestart() throws IOExce DataSegment newSegment = pollThenStopThenStartIntro(); Assert.assertEquals( ImmutableSet.of(newSegment), - ImmutableSet.copyOf(sqlSegmentsMetadata.getImmutableDataSourceWithUsedSegments("wikipedia2").getSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.getImmutableDataSourceWithUsedSegments("wikipedia2").getSegments()) ); } @@ -202,7 +202,7 @@ public void testPrepareImmutableDataSourcesWithAllUsedSegmentsAwaitsPollOnRestar Assert.assertEquals( ImmutableSet.of(segment1, segment2, newSegment), ImmutableSet.copyOf( - sqlSegmentsMetadata + sqlSegmentsMetadataManager .getImmutableDataSourcesWithAllUsedSegments() .stream() .flatMap((ImmutableDruidDataSource dataSource) -> dataSource.getSegments().stream()) @@ -217,23 +217,23 @@ public void testIterateAllUsedSegmentsAwaitsPollOnRestart() throws IOException DataSegment newSegment = pollThenStopThenStartIntro(); Assert.assertEquals( ImmutableSet.of(segment1, segment2, newSegment), - ImmutableSet.copyOf(sqlSegmentsMetadata.iterateAllUsedSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.iterateAllUsedSegments()) ); } private DataSegment pollThenStopThenStartIntro() throws IOException { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - sqlSegmentsMetadata.stopPollingDatabasePeriodically(); - Assert.assertFalse(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + sqlSegmentsMetadataManager.stopPollingDatabasePeriodically(); + Assert.assertFalse(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); Assert.assertEquals( ImmutableSet.of("wikipedia"), - sqlSegmentsMetadata.retrieveAllDataSourceNames() + sqlSegmentsMetadataManager.retrieveAllDataSourceNames() ); DataSegment newSegment = createNewSegment1("wikipedia2"); publisher.publishSegment(newSegment); - sqlSegmentsMetadata.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); return newSegment; } @@ -256,41 +256,41 @@ public void testPollWithCorruptedSegment() ); EmittingLogger.registerEmitter(new NoopServiceEmitter()); - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); Assert.assertEquals( "wikipedia", - Iterables.getOnlyElement(sqlSegmentsMetadata.getImmutableDataSourcesWithAllUsedSegments()).getName() + Iterables.getOnlyElement(sqlSegmentsMetadataManager.getImmutableDataSourcesWithAllUsedSegments()).getName() ); } @Test public void testGetUnusedSegmentIntervals() { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); - int numChangedSegments = sqlSegmentsMetadata.markAsUnusedAllSegmentsInDataSource("wikipedia"); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); + int numChangedSegments = sqlSegmentsMetadataManager.markAsUnusedAllSegmentsInDataSource("wikipedia"); Assert.assertEquals(2, numChangedSegments); Assert.assertEquals( ImmutableList.of(segment2.getInterval()), - sqlSegmentsMetadata.getUnusedSegmentIntervals("wikipedia", DateTimes.of("3000"), 1) + sqlSegmentsMetadataManager.getUnusedSegmentIntervals("wikipedia", DateTimes.of("3000"), 1) ); Assert.assertEquals( ImmutableList.of(segment2.getInterval(), segment1.getInterval()), - sqlSegmentsMetadata.getUnusedSegmentIntervals("wikipedia", DateTimes.of("3000"), 5) + sqlSegmentsMetadataManager.getUnusedSegmentIntervals("wikipedia", DateTimes.of("3000"), 5) ); } @Test(timeout = 60_000) public void testMarkAsUnusedAllSegmentsInDataSource() throws IOException, InterruptedException { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); final String newDataSource = "wikipedia2"; final DataSegment newSegment = createNewSegment1(newDataSource); @@ -298,10 +298,10 @@ public void testMarkAsUnusedAllSegmentsInDataSource() throws IOException, Interr publisher.publishSegment(newSegment); awaitDataSourceAppeared(newDataSource); - int numChangedSegments = sqlSegmentsMetadata.markAsUnusedAllSegmentsInDataSource(newDataSource); + int numChangedSegments = sqlSegmentsMetadataManager.markAsUnusedAllSegmentsInDataSource(newDataSource); Assert.assertEquals(1, numChangedSegments); awaitDataSourceDisappeared(newDataSource); - Assert.assertNull(sqlSegmentsMetadata.getImmutableDataSourceWithUsedSegments(newDataSource)); + Assert.assertNull(sqlSegmentsMetadataManager.getImmutableDataSourceWithUsedSegments(newDataSource)); } private static DataSegment createNewSegment1(String newDataSource) @@ -329,9 +329,9 @@ private static DataSegment createNewSegment2(String newDataSource) @Test(timeout = 60_000) public void testMarkSegmentAsUnused() throws IOException, InterruptedException { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); final String newDataSource = "wikipedia2"; final DataSegment newSegment = createSegment( @@ -344,23 +344,23 @@ public void testMarkSegmentAsUnused() throws IOException, InterruptedException publisher.publishSegment(newSegment); awaitDataSourceAppeared(newDataSource); - Assert.assertNotNull(sqlSegmentsMetadata.getImmutableDataSourceWithUsedSegments(newDataSource)); + Assert.assertNotNull(sqlSegmentsMetadataManager.getImmutableDataSourceWithUsedSegments(newDataSource)); - Assert.assertTrue(sqlSegmentsMetadata.markSegmentAsUnused(newSegment.getId().toString())); + Assert.assertTrue(sqlSegmentsMetadataManager.markSegmentAsUnused(newSegment.getId().toString())); awaitDataSourceDisappeared(newDataSource); - Assert.assertNull(sqlSegmentsMetadata.getImmutableDataSourceWithUsedSegments(newDataSource)); + Assert.assertNull(sqlSegmentsMetadataManager.getImmutableDataSourceWithUsedSegments(newDataSource)); } private void awaitDataSourceAppeared(String newDataSource) throws InterruptedException { - while (sqlSegmentsMetadata.getImmutableDataSourceWithUsedSegments(newDataSource) == null) { + while (sqlSegmentsMetadataManager.getImmutableDataSourceWithUsedSegments(newDataSource) == null) { Thread.sleep(1000); } } private void awaitDataSourceDisappeared(String dataSource) throws InterruptedException { - while (sqlSegmentsMetadata.getImmutableDataSourceWithUsedSegments(dataSource) != null) { + while (sqlSegmentsMetadataManager.getImmutableDataSourceWithUsedSegments(dataSource) != null) { Thread.sleep(1000); } } @@ -368,9 +368,9 @@ private void awaitDataSourceDisappeared(String dataSource) throws InterruptedExc @Test public void testMarkAsUsedNonOvershadowedSegments() throws Exception { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); final String newDataSource = "wikipedia2"; final DataSegment newSegment1 = createSegment( @@ -407,25 +407,25 @@ public void testMarkAsUsedNonOvershadowedSegments() throws Exception newSegment3.getId().toString() ); - sqlSegmentsMetadata.poll(); + sqlSegmentsMetadataManager.poll(); Assert.assertEquals( ImmutableSet.of(segment1, segment2), - ImmutableSet.copyOf(sqlSegmentsMetadata.iterateAllUsedSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.iterateAllUsedSegments()) ); - Assert.assertEquals(2, sqlSegmentsMetadata.markAsUsedNonOvershadowedSegments(newDataSource, segmentIds)); - sqlSegmentsMetadata.poll(); + Assert.assertEquals(2, sqlSegmentsMetadataManager.markAsUsedNonOvershadowedSegments(newDataSource, segmentIds)); + sqlSegmentsMetadataManager.poll(); Assert.assertEquals( ImmutableSet.of(segment1, segment2, newSegment1, newSegment2), - ImmutableSet.copyOf(sqlSegmentsMetadata.iterateAllUsedSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.iterateAllUsedSegments()) ); } - @Test(expected = UnknownSegmentIdException.class) + @Test(expected = UnknownSegmentIdsException.class) public void testMarkAsUsedNonOvershadowedSegmentsInvalidDataSource() throws Exception { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); final String newDataSource = "wikipedia2"; final DataSegment newSegment1 = createNewSegment1(newDataSource); @@ -436,21 +436,21 @@ public void testMarkAsUsedNonOvershadowedSegmentsInvalidDataSource() throws Exce publish(newSegment2, false); final ImmutableSet segmentIds = ImmutableSet.of(newSegment1.getId().toString(), newSegment2.getId().toString()); - sqlSegmentsMetadata.poll(); + sqlSegmentsMetadataManager.poll(); Assert.assertEquals( ImmutableSet.of(segment1, segment2), - ImmutableSet.copyOf(sqlSegmentsMetadata.iterateAllUsedSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.iterateAllUsedSegments()) ); // none of the segments are in data source - Assert.assertEquals(0, sqlSegmentsMetadata.markAsUsedNonOvershadowedSegments("wrongDataSource", segmentIds)); + Assert.assertEquals(0, sqlSegmentsMetadataManager.markAsUsedNonOvershadowedSegments("wrongDataSource", segmentIds)); } - @Test(expected = UnknownSegmentIdException.class) - public void testMarkAsUsedNonOvershadowedSegmentsWithInvalidSegmentIds() throws UnknownSegmentIdException + @Test(expected = UnknownSegmentIdsException.class) + public void testMarkAsUsedNonOvershadowedSegmentsWithInvalidSegmentIds() throws UnknownSegmentIdsException { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); final String newDataSource = "wikipedia2"; final DataSegment newSegment1 = createNewSegment1(newDataSource); @@ -459,21 +459,21 @@ public void testMarkAsUsedNonOvershadowedSegmentsWithInvalidSegmentIds() throws final ImmutableSet segmentIds = ImmutableSet.of(newSegment1.getId().toString(), newSegment2.getId().toString()); - sqlSegmentsMetadata.poll(); + sqlSegmentsMetadataManager.poll(); Assert.assertEquals( ImmutableSet.of(segment1, segment2), - ImmutableSet.copyOf(sqlSegmentsMetadata.iterateAllUsedSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.iterateAllUsedSegments()) ); // none of the segments are in data source - Assert.assertEquals(0, sqlSegmentsMetadata.markAsUsedNonOvershadowedSegments(newDataSource, segmentIds)); + Assert.assertEquals(0, sqlSegmentsMetadataManager.markAsUsedNonOvershadowedSegments(newDataSource, segmentIds)); } @Test public void testMarkAsUsedNonOvershadowedSegmentsInInterval() throws IOException { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); final String newDataSource = "wikipedia2"; final DataSegment newSegment1 = createNewSegment1(newDataSource); @@ -503,28 +503,28 @@ public void testMarkAsUsedNonOvershadowedSegmentsInInterval() throws IOException publish(newSegment4, false); final Interval theInterval = Intervals.of("2017-10-15T00:00:00.000/2017-10-18T00:00:00.000"); - sqlSegmentsMetadata.poll(); + sqlSegmentsMetadataManager.poll(); Assert.assertEquals( ImmutableSet.of(segment1, segment2), - ImmutableSet.copyOf(sqlSegmentsMetadata.iterateAllUsedSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.iterateAllUsedSegments()) ); // 2 out of 3 segments match the interval - Assert.assertEquals(2, sqlSegmentsMetadata.markAsUsedNonOvershadowedSegmentsInInterval(newDataSource, theInterval)); + Assert.assertEquals(2, sqlSegmentsMetadataManager.markAsUsedNonOvershadowedSegmentsInInterval(newDataSource, theInterval)); - sqlSegmentsMetadata.poll(); + sqlSegmentsMetadataManager.poll(); Assert.assertEquals( ImmutableSet.of(segment1, segment2, newSegment1, newSegment2), - ImmutableSet.copyOf(sqlSegmentsMetadata.iterateAllUsedSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.iterateAllUsedSegments()) ); } @Test(expected = IllegalArgumentException.class) public void testMarkAsUsedNonOvershadowedSegmentsInIntervalWithInvalidInterval() throws IOException { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); final String newDataSource = "wikipedia2"; final DataSegment newSegment1 = createNewSegment1(newDataSource); @@ -535,15 +535,15 @@ public void testMarkAsUsedNonOvershadowedSegmentsInIntervalWithInvalidInterval() publish(newSegment2, false); // invalid interval start > end final Interval theInterval = Intervals.of("2017-10-22T00:00:00.000/2017-10-02T00:00:00.000"); - sqlSegmentsMetadata.markAsUsedNonOvershadowedSegmentsInInterval(newDataSource, theInterval); + sqlSegmentsMetadataManager.markAsUsedNonOvershadowedSegmentsInInterval(newDataSource, theInterval); } @Test public void testMarkAsUsedNonOvershadowedSegmentsInIntervalWithOverlappingInterval() throws IOException { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); final String newDataSource = "wikipedia2"; final DataSegment newSegment1 = createSegment( @@ -579,28 +579,28 @@ public void testMarkAsUsedNonOvershadowedSegmentsInIntervalWithOverlappingInterv publish(newSegment4, false); final Interval theInterval = Intervals.of("2017-10-16T00:00:00.000/2017-10-20T00:00:00.000"); - sqlSegmentsMetadata.poll(); + sqlSegmentsMetadataManager.poll(); Assert.assertEquals( ImmutableSet.of(segment1, segment2), - ImmutableSet.copyOf(sqlSegmentsMetadata.iterateAllUsedSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.iterateAllUsedSegments()) ); // 1 out of 3 segments match the interval, other 2 overlap, only the segment fully contained will be marked unused - Assert.assertEquals(1, sqlSegmentsMetadata.markAsUsedNonOvershadowedSegmentsInInterval(newDataSource, theInterval)); + Assert.assertEquals(1, sqlSegmentsMetadataManager.markAsUsedNonOvershadowedSegmentsInInterval(newDataSource, theInterval)); - sqlSegmentsMetadata.poll(); + sqlSegmentsMetadataManager.poll(); Assert.assertEquals( ImmutableSet.of(segment1, segment2, newSegment2), - ImmutableSet.copyOf(sqlSegmentsMetadata.iterateAllUsedSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.iterateAllUsedSegments()) ); } @Test public void testMarkSegmentsAsUnused() throws IOException { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); final String newDataSource = "wikipedia2"; final DataSegment newSegment1 = createNewSegment1(newDataSource); @@ -612,20 +612,20 @@ public void testMarkSegmentsAsUnused() throws IOException final ImmutableSet segmentIds = ImmutableSet.of(newSegment1.getId().toString(), newSegment1.getId().toString()); - Assert.assertEquals(segmentIds.size(), sqlSegmentsMetadata.markSegmentsAsUnused(newDataSource, segmentIds)); - sqlSegmentsMetadata.poll(); + Assert.assertEquals(segmentIds.size(), sqlSegmentsMetadataManager.markSegmentsAsUnused(newDataSource, segmentIds)); + sqlSegmentsMetadataManager.poll(); Assert.assertEquals( ImmutableSet.of(segment1, segment2), - ImmutableSet.copyOf(sqlSegmentsMetadata.iterateAllUsedSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.iterateAllUsedSegments()) ); } @Test public void testMarkSegmentsAsUnusedInvalidDataSource() throws IOException { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); final String newDataSource = "wikipedia2"; final DataSegment newSegment1 = createNewSegment1(newDataSource); @@ -637,20 +637,20 @@ public void testMarkSegmentsAsUnusedInvalidDataSource() throws IOException final ImmutableSet segmentIds = ImmutableSet.of(newSegment1.getId().toString(), newSegment2.getId().toString()); // none of the segments are in data source - Assert.assertEquals(0, sqlSegmentsMetadata.markSegmentsAsUnused("wrongDataSource", segmentIds)); - sqlSegmentsMetadata.poll(); + Assert.assertEquals(0, sqlSegmentsMetadataManager.markSegmentsAsUnused("wrongDataSource", segmentIds)); + sqlSegmentsMetadataManager.poll(); Assert.assertEquals( ImmutableSet.of(segment1, segment2, newSegment1, newSegment2), - ImmutableSet.copyOf(sqlSegmentsMetadata.iterateAllUsedSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.iterateAllUsedSegments()) ); } @Test public void testMarkAsUnusedSegmentsInInterval() throws IOException { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); final String newDataSource = "wikipedia2"; final DataSegment newSegment1 = createNewSegment1(newDataSource); @@ -671,21 +671,21 @@ public void testMarkAsUnusedSegmentsInInterval() throws IOException final Interval theInterval = Intervals.of("2017-10-15T00:00:00.000/2017-10-18T00:00:00.000"); // 2 out of 3 segments match the interval - Assert.assertEquals(2, sqlSegmentsMetadata.markAsUnusedSegmentsInInterval(newDataSource, theInterval)); + Assert.assertEquals(2, sqlSegmentsMetadataManager.markAsUnusedSegmentsInInterval(newDataSource, theInterval)); - sqlSegmentsMetadata.poll(); + sqlSegmentsMetadataManager.poll(); Assert.assertEquals( ImmutableSet.of(segment1, segment2, newSegment3), - ImmutableSet.copyOf(sqlSegmentsMetadata.iterateAllUsedSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.iterateAllUsedSegments()) ); } @Test(expected = IllegalArgumentException.class) public void testMarkAsUnusedSegmentsInIntervalWithInvalidInterval() throws IOException { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); final String newDataSource = "wikipedia2"; final DataSegment newSegment1 = createNewSegment1(newDataSource); @@ -696,15 +696,15 @@ public void testMarkAsUnusedSegmentsInIntervalWithInvalidInterval() throws IOExc publisher.publishSegment(newSegment2); // invalid interval start > end final Interval theInterval = Intervals.of("2017-10-22T00:00:00.000/2017-10-02T00:00:00.000"); - sqlSegmentsMetadata.markAsUnusedSegmentsInInterval(newDataSource, theInterval); + sqlSegmentsMetadataManager.markAsUnusedSegmentsInInterval(newDataSource, theInterval); } @Test public void testMarkAsUnusedSegmentsInIntervalWithOverlappingInterval() throws IOException { - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.poll(); - Assert.assertTrue(sqlSegmentsMetadata.isPollingDatabasePeriodically()); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.poll(); + Assert.assertTrue(sqlSegmentsMetadataManager.isPollingDatabasePeriodically()); final String newDataSource = "wikipedia2"; final DataSegment newSegment1 = createSegment( @@ -731,12 +731,12 @@ public void testMarkAsUnusedSegmentsInIntervalWithOverlappingInterval() throws I final Interval theInterval = Intervals.of("2017-10-16T00:00:00.000/2017-10-20T00:00:00.000"); // 1 out of 3 segments match the interval, other 2 overlap, only the segment fully contained will be marked unused - Assert.assertEquals(1, sqlSegmentsMetadata.markAsUnusedSegmentsInInterval(newDataSource, theInterval)); + Assert.assertEquals(1, sqlSegmentsMetadataManager.markAsUnusedSegmentsInInterval(newDataSource, theInterval)); - sqlSegmentsMetadata.poll(); + sqlSegmentsMetadataManager.poll(); Assert.assertEquals( ImmutableSet.of(segment1, segment2, newSegment1, newSegment3), - ImmutableSet.copyOf(sqlSegmentsMetadata.iterateAllUsedSegments()) + ImmutableSet.copyOf(sqlSegmentsMetadataManager.iterateAllUsedSegments()) ); } @@ -744,9 +744,9 @@ public void testMarkAsUnusedSegmentsInIntervalWithOverlappingInterval() throws I public void testStopAndStart() { // Simulate successive losing and getting the coordinator leadership - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.stopPollingDatabasePeriodically(); - sqlSegmentsMetadata.startPollingDatabasePeriodically(); - sqlSegmentsMetadata.stopPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.stopPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.startPollingDatabasePeriodically(); + sqlSegmentsMetadataManager.stopPollingDatabasePeriodically(); } } diff --git a/server/src/test/java/org/apache/druid/segment/realtime/appenderator/AppenderatorTest.java b/server/src/test/java/org/apache/druid/segment/realtime/appenderator/AppenderatorTest.java index 6590e2c5e073..e5f811c74f50 100644 --- a/server/src/test/java/org/apache/druid/segment/realtime/appenderator/AppenderatorTest.java +++ b/server/src/test/java/org/apache/druid/segment/realtime/appenderator/AppenderatorTest.java @@ -120,17 +120,17 @@ public void testSimpleIngestion() throws Exception Assert.assertTrue(thrown); // push all - final SegmentsAndMetadata segmentsAndMetadata = appenderator.push( + final SegmentsAndCommitMetadata segmentsAndCommitMetadata = appenderator.push( appenderator.getSegments(), committerSupplier.get(), false ).get(); - Assert.assertEquals(ImmutableMap.of("x", "3"), (Map) segmentsAndMetadata.getCommitMetadata()); + Assert.assertEquals(ImmutableMap.of("x", "3"), (Map) segmentsAndCommitMetadata.getCommitMetadata()); Assert.assertEquals( IDENTIFIERS.subList(0, 2), sorted( Lists.transform( - segmentsAndMetadata.getSegments(), + segmentsAndCommitMetadata.getSegments(), new Function() { @Override @@ -142,7 +142,7 @@ public SegmentIdWithShardSpec apply(DataSegment input) ) ) ); - Assert.assertEquals(sorted(tester.getPushedSegments()), sorted(segmentsAndMetadata.getSegments())); + Assert.assertEquals(sorted(tester.getPushedSegments()), sorted(segmentsAndCommitMetadata.getSegments())); // clear appenderator.clear(); diff --git a/server/src/test/java/org/apache/druid/segment/realtime/appenderator/BatchAppenderatorDriverTest.java b/server/src/test/java/org/apache/druid/segment/realtime/appenderator/BatchAppenderatorDriverTest.java index f01495d469e7..fbf33238f0b5 100644 --- a/server/src/test/java/org/apache/druid/segment/realtime/appenderator/BatchAppenderatorDriverTest.java +++ b/server/src/test/java/org/apache/druid/segment/realtime/appenderator/BatchAppenderatorDriverTest.java @@ -115,10 +115,8 @@ public void testSimple() throws Exception checkSegmentStates(2, SegmentState.PUSHED_AND_DROPPED); - final SegmentsAndMetadata published = driver.publishAll(null, makeOkPublisher()).get( - TIMEOUT, - TimeUnit.MILLISECONDS - ); + final SegmentsAndCommitMetadata published = + driver.publishAll(null, makeOkPublisher()).get(TIMEOUT, TimeUnit.MILLISECONDS); Assert.assertEquals( ImmutableSet.of( @@ -151,10 +149,8 @@ public void testIncrementalPush() throws Exception checkSegmentStates(++i, SegmentState.PUSHED_AND_DROPPED); } - final SegmentsAndMetadata published = driver.publishAll(null, makeOkPublisher()).get( - TIMEOUT, - TimeUnit.MILLISECONDS - ); + final SegmentsAndCommitMetadata published = + driver.publishAll(null, makeOkPublisher()).get(TIMEOUT, TimeUnit.MILLISECONDS); Assert.assertEquals( ImmutableSet.of( diff --git a/server/src/test/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderatorDriverFailTest.java b/server/src/test/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderatorDriverFailTest.java index 0254bd31cb1d..2f1c92f0f033 100644 --- a/server/src/test/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderatorDriverFailTest.java +++ b/server/src/test/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderatorDriverFailTest.java @@ -225,7 +225,7 @@ public void testFailDuringDrop() throws IOException, InterruptedException, Timeo Assert.assertTrue(driver.add(ROWS.get(i), "dummy", committerSupplier, false, true).isOk()); } - final SegmentsAndMetadata published = driver.publish( + final SegmentsAndCommitMetadata published = driver.publish( StreamAppenderatorDriverTest.makeOkPublisher(), committerSupplier.get(), ImmutableList.of("dummy") @@ -473,7 +473,7 @@ public ListenableFuture persistAll(Committer committer) } @Override - public ListenableFuture push( + public ListenableFuture push( Collection identifiers, Committer committer, boolean useUniquePath @@ -497,21 +497,21 @@ public ListenableFuture push( .collect(Collectors.toList()); return Futures.transform( persistAll(committer), - (Function) commitMetadata -> new SegmentsAndMetadata(segments, commitMetadata) + (Function) commitMetadata -> new SegmentsAndCommitMetadata(segments, commitMetadata) ); } else { if (interruptPush) { - return new AbstractFuture() + return new AbstractFuture() { @Override - public SegmentsAndMetadata get(long timeout, TimeUnit unit) + public SegmentsAndCommitMetadata get(long timeout, TimeUnit unit) throws InterruptedException { throw new InterruptedException("Interrupt test while pushing segments"); } @Override - public SegmentsAndMetadata get() throws InterruptedException + public SegmentsAndCommitMetadata get() throws InterruptedException { throw new InterruptedException("Interrupt test while pushing segments"); } diff --git a/server/src/test/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderatorDriverTest.java b/server/src/test/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderatorDriverTest.java index 0dbe905ad8f5..1fa7f370d9f0 100644 --- a/server/src/test/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderatorDriverTest.java +++ b/server/src/test/java/org/apache/druid/segment/realtime/appenderator/StreamAppenderatorDriverTest.java @@ -140,7 +140,7 @@ public void testSimple() throws Exception Assert.assertTrue(driver.add(ROWS.get(i), "dummy", committerSupplier, false, true).isOk()); } - final SegmentsAndMetadata published = driver.publish( + final SegmentsAndCommitMetadata published = driver.publish( makeOkPublisher(), committerSupplier.get(), ImmutableList.of("dummy") @@ -150,18 +150,18 @@ public void testSimple() throws Exception Thread.sleep(100); } - final SegmentsAndMetadata segmentsAndMetadata = driver.registerHandoff(published) - .get(HANDOFF_CONDITION_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); + final SegmentsAndCommitMetadata segmentsAndCommitMetadata = driver.registerHandoff(published) + .get(HANDOFF_CONDITION_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); Assert.assertEquals( ImmutableSet.of( new SegmentIdWithShardSpec(DATA_SOURCE, Intervals.of("2000/PT1H"), VERSION, new NumberedShardSpec(0, 0)), new SegmentIdWithShardSpec(DATA_SOURCE, Intervals.of("2000T01/PT1H"), VERSION, new NumberedShardSpec(0, 0)) ), - asIdentifiers(segmentsAndMetadata.getSegments()) + asIdentifiers(segmentsAndCommitMetadata.getSegments()) ); - Assert.assertEquals(3, segmentsAndMetadata.getCommitMetadata()); + Assert.assertEquals(3, segmentsAndCommitMetadata.getCommitMetadata()); } @Test @@ -190,7 +190,7 @@ public void testMaxRowsPerSegment() throws Exception } } - final SegmentsAndMetadata published = driver.publish( + final SegmentsAndCommitMetadata published = driver.publish( makeOkPublisher(), committerSupplier.get(), ImmutableList.of("dummy") @@ -200,10 +200,10 @@ public void testMaxRowsPerSegment() throws Exception Thread.sleep(100); } - final SegmentsAndMetadata segmentsAndMetadata = driver.registerHandoff(published) - .get(HANDOFF_CONDITION_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); - Assert.assertEquals(numSegments, segmentsAndMetadata.getSegments().size()); - Assert.assertEquals(numSegments * MAX_ROWS_PER_SEGMENT, segmentsAndMetadata.getCommitMetadata()); + final SegmentsAndCommitMetadata segmentsAndCommitMetadata = driver.registerHandoff(published) + .get(HANDOFF_CONDITION_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); + Assert.assertEquals(numSegments, segmentsAndCommitMetadata.getSegments().size()); + Assert.assertEquals(numSegments * MAX_ROWS_PER_SEGMENT, segmentsAndCommitMetadata.getCommitMetadata()); } @Test(timeout = 60_000L, expected = TimeoutException.class) @@ -219,7 +219,7 @@ public void testHandoffTimeout() throws Exception Assert.assertTrue(driver.add(ROWS.get(i), "dummy", committerSupplier, false, true).isOk()); } - final SegmentsAndMetadata published = driver.publish( + final SegmentsAndCommitMetadata published = driver.publish( makeOkPublisher(), committerSupplier.get(), ImmutableList.of("dummy") @@ -244,7 +244,7 @@ public void testPublishPerRow() throws IOException, InterruptedException, Timeou committerSupplier.setMetadata(1); Assert.assertTrue(driver.add(ROWS.get(0), "dummy", committerSupplier, false, true).isOk()); - final SegmentsAndMetadata segmentsAndMetadata = driver.publishAndRegisterHandoff( + final SegmentsAndCommitMetadata segmentsAndCommitMetadata = driver.publishAndRegisterHandoff( makeOkPublisher(), committerSupplier.get(), ImmutableList.of("dummy") @@ -254,10 +254,10 @@ public void testPublishPerRow() throws IOException, InterruptedException, Timeou ImmutableSet.of( new SegmentIdWithShardSpec(DATA_SOURCE, Intervals.of("2000/PT1H"), VERSION, new NumberedShardSpec(0, 0)) ), - asIdentifiers(segmentsAndMetadata.getSegments()) + asIdentifiers(segmentsAndCommitMetadata.getSegments()) ); - Assert.assertEquals(1, segmentsAndMetadata.getCommitMetadata()); + Assert.assertEquals(1, segmentsAndCommitMetadata.getCommitMetadata()); } // Add the second and third rows and publish immediately @@ -265,7 +265,7 @@ public void testPublishPerRow() throws IOException, InterruptedException, Timeou committerSupplier.setMetadata(i + 1); Assert.assertTrue(driver.add(ROWS.get(i), "dummy", committerSupplier, false, true).isOk()); - final SegmentsAndMetadata segmentsAndMetadata = driver.publishAndRegisterHandoff( + final SegmentsAndCommitMetadata segmentsAndCommitMetadata = driver.publishAndRegisterHandoff( makeOkPublisher(), committerSupplier.get(), ImmutableList.of("dummy") @@ -277,16 +277,16 @@ public void testPublishPerRow() throws IOException, InterruptedException, Timeou // different partitionNum new SegmentIdWithShardSpec(DATA_SOURCE, Intervals.of("2000T01/PT1H"), VERSION, new NumberedShardSpec(i - 1, 0)) ), - asIdentifiers(segmentsAndMetadata.getSegments()) + asIdentifiers(segmentsAndCommitMetadata.getSegments()) ); - Assert.assertEquals(i + 1, segmentsAndMetadata.getCommitMetadata()); + Assert.assertEquals(i + 1, segmentsAndCommitMetadata.getCommitMetadata()); } driver.persist(committerSupplier.get()); // There is no remaining rows in the driver, and thus the result must be empty - final SegmentsAndMetadata segmentsAndMetadata = driver.publishAndRegisterHandoff( + final SegmentsAndCommitMetadata segmentsAndCommitMetadata = driver.publishAndRegisterHandoff( makeOkPublisher(), committerSupplier.get(), ImmutableList.of("dummy") @@ -294,10 +294,10 @@ public void testPublishPerRow() throws IOException, InterruptedException, Timeou Assert.assertEquals( ImmutableSet.of(), - asIdentifiers(segmentsAndMetadata.getSegments()) + asIdentifiers(segmentsAndCommitMetadata.getSegments()) ); - Assert.assertEquals(3, segmentsAndMetadata.getCommitMetadata()); + Assert.assertEquals(3, segmentsAndCommitMetadata.getCommitMetadata()); } @Test @@ -315,23 +315,23 @@ public void testIncrementalHandoff() throws Exception Assert.assertTrue(driver.add(ROWS.get(i), "sequence_1", committerSupplier, false, true).isOk()); } - final ListenableFuture futureForSequence0 = driver.publishAndRegisterHandoff( + final ListenableFuture futureForSequence0 = driver.publishAndRegisterHandoff( makeOkPublisher(), committerSupplier.get(), ImmutableList.of("sequence_0") ); - final ListenableFuture futureForSequence1 = driver.publishAndRegisterHandoff( + final ListenableFuture futureForSequence1 = driver.publishAndRegisterHandoff( makeOkPublisher(), committerSupplier.get(), ImmutableList.of("sequence_1") ); - final SegmentsAndMetadata handedoffFromSequence0 = futureForSequence0.get( + final SegmentsAndCommitMetadata handedoffFromSequence0 = futureForSequence0.get( HANDOFF_CONDITION_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS ); - final SegmentsAndMetadata handedoffFromSequence1 = futureForSequence1.get( + final SegmentsAndCommitMetadata handedoffFromSequence1 = futureForSequence1.get( HANDOFF_CONDITION_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS ); diff --git a/server/src/test/java/org/apache/druid/server/coordinator/DruidCoordinatorBalancerProfiler.java b/server/src/test/java/org/apache/druid/server/coordinator/BalanceSegmentsProfiler.java similarity index 95% rename from server/src/test/java/org/apache/druid/server/coordinator/DruidCoordinatorBalancerProfiler.java rename to server/src/test/java/org/apache/druid/server/coordinator/BalanceSegmentsProfiler.java index fa0954fac0dc..5d53a53fd106 100644 --- a/server/src/test/java/org/apache/druid/server/coordinator/DruidCoordinatorBalancerProfiler.java +++ b/server/src/test/java/org/apache/druid/server/coordinator/BalanceSegmentsProfiler.java @@ -28,7 +28,7 @@ import org.apache.druid.java.util.emitter.EmittingLogger; import org.apache.druid.java.util.emitter.service.ServiceEmitter; import org.apache.druid.metadata.MetadataRuleManager; -import org.apache.druid.server.coordinator.helper.DruidCoordinatorRuleRunner; +import org.apache.druid.server.coordinator.duty.RunRules; import org.apache.druid.server.coordinator.rules.PeriodLoadRule; import org.apache.druid.server.coordinator.rules.Rule; import org.apache.druid.timeline.DataSegment; @@ -47,7 +47,7 @@ /** * TODO convert benchmarks to JMH */ -public class DruidCoordinatorBalancerProfiler +public class BalanceSegmentsProfiler { private static final int MAX_SEGMENTS_TO_MOVE = 5; private DruidCoordinator coordinator; @@ -151,8 +151,8 @@ public void bigProfiler() .withReplicationManager(new ReplicationThrottler(2, 500)) .build(); - DruidCoordinatorBalancerTester tester = new DruidCoordinatorBalancerTester(coordinator); - DruidCoordinatorRuleRunner runner = new DruidCoordinatorRuleRunner(coordinator); + BalanceSegmentsTester tester = new BalanceSegmentsTester(coordinator); + RunRules runner = new RunRules(coordinator); watch.start(); DruidCoordinatorRuntimeParams balanceParams = tester.run(params); DruidCoordinatorRuntimeParams assignParams = runner.run(params); @@ -207,7 +207,7 @@ public void profileRun() .withUsedSegmentsInTest(segments) .withDynamicConfigs(CoordinatorDynamicConfig.builder().withMaxSegmentsToMove(MAX_SEGMENTS_TO_MOVE).build()) .build(); - DruidCoordinatorBalancerTester tester = new DruidCoordinatorBalancerTester(coordinator); + BalanceSegmentsTester tester = new BalanceSegmentsTester(coordinator); watch.start(); DruidCoordinatorRuntimeParams balanceParams = tester.run(params); System.out.println(watch.stop()); diff --git a/server/src/test/java/org/apache/druid/server/coordinator/DruidCoordinatorBalancerTest.java b/server/src/test/java/org/apache/druid/server/coordinator/BalanceSegmentsTest.java similarity index 96% rename from server/src/test/java/org/apache/druid/server/coordinator/DruidCoordinatorBalancerTest.java rename to server/src/test/java/org/apache/druid/server/coordinator/BalanceSegmentsTest.java index 585a06164e93..084a119ebe76 100644 --- a/server/src/test/java/org/apache/druid/server/coordinator/DruidCoordinatorBalancerTest.java +++ b/server/src/test/java/org/apache/druid/server/coordinator/BalanceSegmentsTest.java @@ -48,7 +48,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -public class DruidCoordinatorBalancerTest +public class BalanceSegmentsTest { private static final int MAX_SEGMENTS_TO_MOVE = 5; private DruidCoordinator coordinator; @@ -189,7 +189,7 @@ public void testMoveToEmptyServerBalancer() .withBalancerStrategy(predefinedPickOrderStrategy) .build(); - params = new DruidCoordinatorBalancerTester(coordinator).run(params); + params = new BalanceSegmentsTester(coordinator).run(params); Assert.assertEquals(2, params.getCoordinatorStats().getTieredStat("movedCount", "normal")); } @@ -239,7 +239,7 @@ public void testMoveDecommissioningMaxPercentOfMaxSegmentsToMove() .withBalancerStrategy(strategy) .build(); - params = new DruidCoordinatorBalancerTester(coordinator).run(params); + params = new BalanceSegmentsTester(coordinator).run(params); Assert.assertEquals(3L, params.getCoordinatorStats().getTieredStat("movedCount", "normal")); Assert.assertThat( peon3.getSegmentsToLoad(), @@ -251,7 +251,7 @@ public void testMoveDecommissioningMaxPercentOfMaxSegmentsToMove() public void testZeroDecommissioningMaxPercentOfMaxSegmentsToMove() { DruidCoordinatorRuntimeParams params = setupParamsForDecommissioningMaxPercentOfMaxSegmentsToMove(0); - params = new DruidCoordinatorBalancerTester(coordinator).run(params); + params = new BalanceSegmentsTester(coordinator).run(params); Assert.assertEquals(1L, params.getCoordinatorStats().getTieredStat("movedCount", "normal")); Assert.assertThat(peon3.getSegmentsToLoad(), Matchers.is(Matchers.equalTo(ImmutableSet.of(segment1)))); } @@ -260,7 +260,7 @@ public void testZeroDecommissioningMaxPercentOfMaxSegmentsToMove() public void testMaxDecommissioningMaxPercentOfMaxSegmentsToMove() { DruidCoordinatorRuntimeParams params = setupParamsForDecommissioningMaxPercentOfMaxSegmentsToMove(10); - params = new DruidCoordinatorBalancerTester(coordinator).run(params); + params = new BalanceSegmentsTester(coordinator).run(params); Assert.assertEquals(1L, params.getCoordinatorStats().getTieredStat("movedCount", "normal")); Assert.assertThat(peon3.getSegmentsToLoad(), Matchers.is(Matchers.equalTo(ImmutableSet.of(segment2)))); } @@ -305,7 +305,7 @@ public void testMoveDecommissioningMaxPercentOfMaxSegmentsToMoveWithNoDecommissi .withBalancerStrategy(strategy) .build(); - params = new DruidCoordinatorBalancerTester(coordinator).run(params); + params = new BalanceSegmentsTester(coordinator).run(params); Assert.assertEquals(3L, params.getCoordinatorStats().getTieredStat("movedCount", "normal")); Assert.assertThat( peon3.getSegmentsToLoad(), @@ -345,7 +345,7 @@ public void testMoveToDecommissioningServer() .withBalancerStrategy(strategy) .build(); - params = new DruidCoordinatorBalancerTester(coordinator).run(params); + params = new BalanceSegmentsTester(coordinator).run(params); Assert.assertEquals(0, params.getCoordinatorStats().getTieredStat("movedCount", "normal")); } @@ -379,7 +379,7 @@ public void testMoveFromDecommissioningServer() .withBalancerStrategy(strategy) .build(); - params = new DruidCoordinatorBalancerTester(coordinator).run(params); + params = new BalanceSegmentsTester(coordinator).run(params); Assert.assertEquals(1, params.getCoordinatorStats().getTieredStat("movedCount", "normal")); Assert.assertEquals(0, peon1.getNumberOfSegmentsInQueue()); Assert.assertEquals(1, peon2.getNumberOfSegmentsInQueue()); @@ -421,7 +421,7 @@ public void testMoveMaxLoadQueueServerBalancer() ) .build(); - params = new DruidCoordinatorBalancerTester(coordinator).run(params); + params = new BalanceSegmentsTester(coordinator).run(params); // max to move is 5, all segments on server 1, but only expect to move 1 to server 2 since max node load queue is 1 Assert.assertEquals(1, params.getCoordinatorStats().getTieredStat("movedCount", "normal")); @@ -458,7 +458,7 @@ public void testMoveSameSegmentTwice() ) .build(); - params = new DruidCoordinatorBalancerTester(coordinator).run(params); + params = new BalanceSegmentsTester(coordinator).run(params); Assert.assertEquals(1, params.getCoordinatorStats().getTieredStat("movedCount", "normal")); } @@ -480,7 +480,7 @@ public void testRun1() ImmutableList.of(peon1, peon2) ).build(); - params = new DruidCoordinatorBalancerTester(coordinator).run(params); + params = new BalanceSegmentsTester(coordinator).run(params); Assert.assertTrue(params.getCoordinatorStats().getTieredStat("movedCount", "normal") > 0); } @@ -498,7 +498,7 @@ public void testRun2() DruidCoordinatorRuntimeParams params = defaultRuntimeParamsBuilder(druidServers, peons).build(); - params = new DruidCoordinatorBalancerTester(coordinator).run(params); + params = new BalanceSegmentsTester(coordinator).run(params); Assert.assertTrue(params.getCoordinatorStats().getTieredStat("movedCount", "normal") > 0); } diff --git a/server/src/test/java/org/apache/druid/server/coordinator/DruidCoordinatorBalancerTester.java b/server/src/test/java/org/apache/druid/server/coordinator/BalanceSegmentsTester.java similarity index 91% rename from server/src/test/java/org/apache/druid/server/coordinator/DruidCoordinatorBalancerTester.java rename to server/src/test/java/org/apache/druid/server/coordinator/BalanceSegmentsTester.java index 24b8de39de9a..9a4166be74e2 100644 --- a/server/src/test/java/org/apache/druid/server/coordinator/DruidCoordinatorBalancerTester.java +++ b/server/src/test/java/org/apache/druid/server/coordinator/BalanceSegmentsTester.java @@ -21,14 +21,14 @@ import org.apache.druid.client.ImmutableDruidServer; import org.apache.druid.java.util.common.StringUtils; -import org.apache.druid.server.coordinator.helper.DruidCoordinatorBalancer; +import org.apache.druid.server.coordinator.duty.BalanceSegments; import org.apache.druid.timeline.DataSegment; import org.apache.druid.timeline.SegmentId; -public class DruidCoordinatorBalancerTester extends DruidCoordinatorBalancer +public class BalanceSegmentsTester extends BalanceSegments { - public DruidCoordinatorBalancerTester(DruidCoordinator coordinator) + public BalanceSegmentsTester(DruidCoordinator coordinator) { super(coordinator); } diff --git a/server/src/test/java/org/apache/druid/server/coordinator/CuratorDruidCoordinatorTest.java b/server/src/test/java/org/apache/druid/server/coordinator/CuratorDruidCoordinatorTest.java index 51d27463d0c3..c44c0d8d3fb3 100644 --- a/server/src/test/java/org/apache/druid/server/coordinator/CuratorDruidCoordinatorTest.java +++ b/server/src/test/java/org/apache/druid/server/coordinator/CuratorDruidCoordinatorTest.java @@ -46,7 +46,7 @@ import org.apache.druid.java.util.common.concurrent.Execs; import org.apache.druid.java.util.common.concurrent.ScheduledExecutorFactory; import org.apache.druid.metadata.MetadataRuleManager; -import org.apache.druid.metadata.MetadataSegmentManager; +import org.apache.druid.metadata.SegmentsMetadataManager; import org.apache.druid.segment.TestHelper; import org.apache.druid.server.DruidNode; import org.apache.druid.server.coordination.DruidServerMetadata; @@ -85,7 +85,7 @@ public class CuratorDruidCoordinatorTest extends CuratorTestBase { private DruidCoordinator coordinator; - private MetadataSegmentManager segmentsMetadata; + private SegmentsMetadataManager segmentsMetadataManager; private DataSourcesSnapshot dataSourcesSnapshot; private DruidCoordinatorRuntimeParams coordinatorRuntimeParams; @@ -133,7 +133,7 @@ public CuratorDruidCoordinatorTest() @Before public void setUp() throws Exception { - segmentsMetadata = EasyMock.createNiceMock(MetadataSegmentManager.class); + segmentsMetadataManager = EasyMock.createNiceMock(SegmentsMetadataManager.class); dataSourcesSnapshot = EasyMock.createNiceMock(DataSourcesSnapshot.class); coordinatorRuntimeParams = EasyMock.createNiceMock(DruidCoordinatorRuntimeParams.class); @@ -220,7 +220,7 @@ public String getBase() } }, configManager, - segmentsMetadata, + segmentsMetadataManager, baseView, metadataRuleManager, curator, @@ -383,10 +383,10 @@ public void testMoveSegment() throws Exception ImmutableDruidDataSource druidDataSource = EasyMock.createNiceMock(ImmutableDruidDataSource.class); EasyMock.expect(druidDataSource.getSegment(EasyMock.anyObject(SegmentId.class))).andReturn(sourceSegments.get(2)); EasyMock.replay(druidDataSource); - EasyMock.expect(segmentsMetadata.getImmutableDataSourceWithUsedSegments(EasyMock.anyString())) + EasyMock.expect(segmentsMetadataManager.getImmutableDataSourceWithUsedSegments(EasyMock.anyString())) .andReturn(druidDataSource); EasyMock.expect(coordinatorRuntimeParams.getDataSourcesSnapshot()).andReturn(dataSourcesSnapshot).anyTimes(); - EasyMock.replay(segmentsMetadata, coordinatorRuntimeParams); + EasyMock.replay(segmentsMetadataManager, coordinatorRuntimeParams); EasyMock.expect(dataSourcesSnapshot.getDataSource(EasyMock.anyString())).andReturn(druidDataSource).anyTimes(); EasyMock.replay(dataSourcesSnapshot); @@ -518,7 +518,7 @@ public String getBase() } }, configManager, - segmentsMetadata, + segmentsMetadataManager, baseView, metadataRuleManager, curator, diff --git a/server/src/test/java/org/apache/druid/server/coordinator/DataSourceCompactionConfigTest.java b/server/src/test/java/org/apache/druid/server/coordinator/DataSourceCompactionConfigTest.java index 7b9e3b2698bd..a2d36c1fa265 100644 --- a/server/src/test/java/org/apache/druid/server/coordinator/DataSourceCompactionConfigTest.java +++ b/server/src/test/java/org/apache/druid/server/coordinator/DataSourceCompactionConfigTest.java @@ -24,10 +24,9 @@ import org.apache.druid.data.input.SegmentsSplitHintSpec; import org.apache.druid.jackson.DefaultObjectMapper; import org.apache.druid.segment.IndexSpec; -import org.apache.druid.segment.data.CompressionFactory.LongEncodingStrategy; +import org.apache.druid.segment.data.CompressionFactory; import org.apache.druid.segment.data.CompressionStrategy; import org.apache.druid.segment.data.RoaringBitmapSerdeFactory; -import org.apache.druid.server.coordinator.DataSourceCompactionConfig.UserCompactTuningConfig; import org.joda.time.Period; import org.junit.Assert; import org.junit.Rule; @@ -91,17 +90,6 @@ public void testSerdeWithMaxRowsPerSegment() throws IOException Assert.assertEquals(config.getTaskContext(), fromJson.getTaskContext()); } - @Test - public void testSerdeUserCompactTuningConfig() throws IOException - { - final UserCompactTuningConfig config = new UserCompactTuningConfig(null, null, null, null, null, null, null, null); - final String json = OBJECT_MAPPER.writeValueAsString(config); - // Check maxRowsPerSegment doesn't exist in the JSON string - Assert.assertFalse(json.contains("maxRowsPerSegment")); - final UserCompactTuningConfig fromJson = OBJECT_MAPPER.readValue(json, UserCompactTuningConfig.class); - Assert.assertEquals(config, fromJson); - } - @Test public void testSerdeWithMaxTotalRows() throws IOException { @@ -111,7 +99,7 @@ public void testSerdeWithMaxTotalRows() throws IOException 500L, null, new Period(3600), - new UserCompactTuningConfig( + new UserCompactionTaskQueryTuningConfig( null, null, 10000L, @@ -144,7 +132,7 @@ public void testSerdeMaxTotalRowsWithMaxRowsPerSegment() throws IOException 500L, 10000, new Period(3600), - new UserCompactTuningConfig( + new UserCompactionTaskQueryTuningConfig( null, null, 10000L, @@ -172,7 +160,7 @@ public void testSerdeMaxTotalRowsWithMaxRowsPerSegment() throws IOException @Test public void testSerdeUserCompactionTuningConfig() throws IOException { - final UserCompactTuningConfig tuningConfig = new UserCompactTuningConfig( + final UserCompactionTaskQueryTuningConfig tuningConfig = new UserCompactionTaskQueryTuningConfig( 1000, 10000L, 2000L, @@ -181,7 +169,7 @@ public void testSerdeUserCompactionTuningConfig() throws IOException new RoaringBitmapSerdeFactory(false), CompressionStrategy.LZF, CompressionStrategy.UNCOMPRESSED, - LongEncodingStrategy.LONGS + CompressionFactory.LongEncodingStrategy.LONGS ), 1, 3000L, @@ -189,7 +177,8 @@ public void testSerdeUserCompactionTuningConfig() throws IOException ); final String json = OBJECT_MAPPER.writeValueAsString(tuningConfig); - final UserCompactTuningConfig fromJson = OBJECT_MAPPER.readValue(json, UserCompactTuningConfig.class); + final UserCompactionTaskQueryTuningConfig fromJson = + OBJECT_MAPPER.readValue(json, UserCompactionTaskQueryTuningConfig.class); Assert.assertEquals(tuningConfig, fromJson); } } diff --git a/server/src/test/java/org/apache/druid/server/coordinator/DruidCoordinatorTest.java b/server/src/test/java/org/apache/druid/server/coordinator/DruidCoordinatorTest.java index a20aea63473b..e48bf9430211 100644 --- a/server/src/test/java/org/apache/druid/server/coordinator/DruidCoordinatorTest.java +++ b/server/src/test/java/org/apache/druid/server/coordinator/DruidCoordinatorTest.java @@ -48,7 +48,7 @@ import org.apache.druid.java.util.emitter.core.Event; import org.apache.druid.java.util.emitter.service.ServiceEmitter; import org.apache.druid.metadata.MetadataRuleManager; -import org.apache.druid.metadata.MetadataSegmentManager; +import org.apache.druid.metadata.SegmentsMetadataManager; import org.apache.druid.server.DruidNode; import org.apache.druid.server.coordination.DruidServerMetadata; import org.apache.druid.server.coordination.ServerType; @@ -87,7 +87,7 @@ public class DruidCoordinatorTest extends CuratorTestBase private static final long COORDINATOR_PERIOD = 100; private DruidCoordinator coordinator; - private MetadataSegmentManager segmentsMetadata; + private SegmentsMetadataManager segmentsMetadataManager; private DataSourcesSnapshot dataSourcesSnapshot; private DruidCoordinatorRuntimeParams coordinatorRuntimeParams; @@ -110,7 +110,7 @@ public void setUp() throws Exception { druidServer = EasyMock.createMock(DruidServer.class); serverInventoryView = EasyMock.createMock(SingleServerInventoryView.class); - segmentsMetadata = EasyMock.createNiceMock(MetadataSegmentManager.class); + segmentsMetadataManager = EasyMock.createNiceMock(SegmentsMetadataManager.class); dataSourcesSnapshot = EasyMock.createNiceMock(DataSourcesSnapshot.class); coordinatorRuntimeParams = EasyMock.createNiceMock(DruidCoordinatorRuntimeParams.class); metadataRuleManager = EasyMock.createNiceMock(MetadataRuleManager.class); @@ -185,7 +185,7 @@ public String getBase() } }, configManager, - segmentsMetadata, + segmentsMetadataManager, serverInventoryView, metadataRuleManager, curator, @@ -253,9 +253,9 @@ public void testMoveSegment() EasyMock.expect(druidDataSource.getSegment(EasyMock.anyObject(SegmentId.class))).andReturn(segment); EasyMock.replay(druidDataSource); EasyMock - .expect(segmentsMetadata.getImmutableDataSourceWithUsedSegments(EasyMock.anyString())) + .expect(segmentsMetadataManager.getImmutableDataSourceWithUsedSegments(EasyMock.anyString())) .andReturn(druidDataSource); - EasyMock.replay(segmentsMetadata); + EasyMock.replay(segmentsMetadataManager); EasyMock.expect(dataSourcesSnapshot.getDataSource(EasyMock.anyString())).andReturn(druidDataSource).anyTimes(); EasyMock.replay(dataSourcesSnapshot); scheduledExecutorFactory = EasyMock.createNiceMock(ScheduledExecutorFactory.class); @@ -336,7 +336,7 @@ public void testCoordinatorRun() throws Exception EasyMock.replay(metadataRuleManager); - // Setup MetadataSegmentManager + // Setup SegmentsMetadataManager DruidDataSource[] dataSources = { new DruidDataSource(dataSource, Collections.emptyMap()) }; @@ -353,7 +353,7 @@ public void testCoordinatorRun() throws Exception ); dataSources[0].addSegment(dataSegment); - setupMetadataSegmentManagerMock(dataSources[0]); + setupSegmentsMetadataMock(dataSources[0]); ImmutableDruidDataSource immutableDruidDataSource = EasyMock.createNiceMock(ImmutableDruidDataSource.class); EasyMock.expect(immutableDruidDataSource.getSegments()) .andReturn(ImmutableSet.of(dataSegment)).atLeastOnce(); @@ -479,7 +479,7 @@ public void testCoordinatorTieredRun() throws Exception DruidDataSource[] druidDataSources = {new DruidDataSource(dataSource, Collections.emptyMap())}; dataSegments.values().forEach(druidDataSources[0]::addSegment); - setupMetadataSegmentManagerMock(druidDataSources[0]); + setupSegmentsMetadataMock(druidDataSources[0]); EasyMock.expect(metadataRuleManager.getRulesWithDefault(EasyMock.anyString())) .andReturn(ImmutableList.of(hotTier, coldTier)).atLeastOnce(); @@ -546,32 +546,32 @@ public void testCoordinatorTieredRun() throws Exception leaderUnannouncerLatch.await(); EasyMock.verify(serverInventoryView); - EasyMock.verify(segmentsMetadata); + EasyMock.verify(segmentsMetadataManager); EasyMock.verify(metadataRuleManager); } - private void setupMetadataSegmentManagerMock(DruidDataSource dataSource) + private void setupSegmentsMetadataMock(DruidDataSource dataSource) { - EasyMock.expect(segmentsMetadata.isPollingDatabasePeriodically()).andReturn(true).anyTimes(); + EasyMock.expect(segmentsMetadataManager.isPollingDatabasePeriodically()).andReturn(true).anyTimes(); EasyMock - .expect(segmentsMetadata.iterateAllUsedSegments()) + .expect(segmentsMetadataManager.iterateAllUsedSegments()) .andReturn(dataSource.getSegments()) .anyTimes(); EasyMock - .expect(segmentsMetadata.getImmutableDataSourcesWithAllUsedSegments()) + .expect(segmentsMetadataManager.getImmutableDataSourcesWithAllUsedSegments()) .andReturn(Collections.singleton(dataSource.toImmutableDruidDataSource())) .anyTimes(); DataSourcesSnapshot dataSourcesSnapshot = new DataSourcesSnapshot(ImmutableMap.of(dataSource.getName(), dataSource.toImmutableDruidDataSource())); EasyMock - .expect(segmentsMetadata.getSnapshotOfDataSourcesWithAllUsedSegments()) + .expect(segmentsMetadataManager.getSnapshotOfDataSourcesWithAllUsedSegments()) .andReturn(dataSourcesSnapshot) .anyTimes(); EasyMock - .expect(segmentsMetadata.retrieveAllDataSourceNames()) + .expect(segmentsMetadataManager.retrieveAllDataSourceNames()) .andReturn(Collections.singleton(dataSource.getName())) .anyTimes(); - EasyMock.replay(segmentsMetadata); + EasyMock.replay(segmentsMetadataManager); EasyMock .expect(this.dataSourcesSnapshot.iterateAllUsedSegmentsInSnapshot()) diff --git a/server/src/test/java/org/apache/druid/server/coordinator/DruidCoordinatorRuleRunnerTest.java b/server/src/test/java/org/apache/druid/server/coordinator/RunRulesTest.java similarity index 98% rename from server/src/test/java/org/apache/druid/server/coordinator/DruidCoordinatorRuleRunnerTest.java rename to server/src/test/java/org/apache/druid/server/coordinator/RunRulesTest.java index 2b7975380f7e..f5582550d8ea 100644 --- a/server/src/test/java/org/apache/druid/server/coordinator/DruidCoordinatorRuleRunnerTest.java +++ b/server/src/test/java/org/apache/druid/server/coordinator/RunRulesTest.java @@ -30,10 +30,10 @@ import org.apache.druid.java.util.emitter.service.ServiceEmitter; import org.apache.druid.java.util.emitter.service.ServiceEventBuilder; import org.apache.druid.metadata.MetadataRuleManager; -import org.apache.druid.metadata.MetadataSegmentManager; +import org.apache.druid.metadata.SegmentsMetadataManager; import org.apache.druid.segment.IndexIO; import org.apache.druid.server.coordination.ServerType; -import org.apache.druid.server.coordinator.helper.DruidCoordinatorRuleRunner; +import org.apache.druid.server.coordinator.duty.RunRules; import org.apache.druid.server.coordinator.rules.ForeverLoadRule; import org.apache.druid.server.coordinator.rules.IntervalDropRule; import org.apache.druid.server.coordinator.rules.IntervalLoadRule; @@ -57,7 +57,7 @@ /** */ -public class DruidCoordinatorRuleRunnerTest +public class RunRulesTest { public static final CoordinatorDynamicConfig COORDINATOR_CONFIG_WITH_ZERO_LEADING_TIME_BEFORE_CAN_MARK_AS_UNUSED_OVERSHADOWED_SEGMENTS = CoordinatorDynamicConfig.builder().withLeadingTimeMillisBeforeCanMarkAsUnusedOvershadowedSegments(0L).build(); @@ -65,10 +65,10 @@ public class DruidCoordinatorRuleRunnerTest private DruidCoordinator coordinator; private LoadQueuePeon mockPeon; private List usedSegments; - private DruidCoordinatorRuleRunner ruleRunner; + private RunRules ruleRunner; private ServiceEmitter emitter; private MetadataRuleManager databaseRuleManager; - private MetadataSegmentManager segmentsMetadata; + private SegmentsMetadataManager segmentsMetadataManager; @Before public void setUp() @@ -78,7 +78,7 @@ public void setUp() emitter = EasyMock.createMock(ServiceEmitter.class); EmittingLogger.registerEmitter(emitter); databaseRuleManager = EasyMock.createMock(MetadataRuleManager.class); - segmentsMetadata = EasyMock.createNiceMock(MetadataSegmentManager.class); + segmentsMetadataManager = EasyMock.createNiceMock(SegmentsMetadataManager.class); DateTime start = DateTimes.of("2012-01-01"); usedSegments = new ArrayList<>(); @@ -99,7 +99,7 @@ public void setUp() start = start.plusHours(1); } - ruleRunner = new DruidCoordinatorRuleRunner(new ReplicationThrottler(24, 1), coordinator); + ruleRunner = new RunRules(new ReplicationThrottler(24, 1), coordinator); } @After @@ -891,7 +891,7 @@ public void testReplicantThrottleAcrossTiers() DruidCoordinatorRuntimeParams params = makeCoordinatorRuntimeParams(druidCluster, balancerStrategy).build(); - DruidCoordinatorRuleRunner runner = new DruidCoordinatorRuleRunner(new ReplicationThrottler(7, 1), coordinator); + RunRules runner = new RunRules(new ReplicationThrottler(7, 1), coordinator); DruidCoordinatorRuntimeParams afterParams = runner.run(params); CoordinatorStats stats = afterParams.getCoordinatorStats(); @@ -1072,7 +1072,7 @@ private void mockCoordinator() EasyMock.expect(coordinator.getDynamicConfigs()).andReturn(createCoordinatorDynamicConfig()).anyTimes(); coordinator.markSegmentAsUnused(EasyMock.anyObject()); EasyMock.expectLastCall().anyTimes(); - EasyMock.replay(coordinator, segmentsMetadata); + EasyMock.replay(coordinator, segmentsMetadataManager); } private void mockEmptyPeon() diff --git a/server/src/test/java/org/apache/druid/server/coordinator/UserCompactionTaskQueryTuningConfigTest.java b/server/src/test/java/org/apache/druid/server/coordinator/UserCompactionTaskQueryTuningConfigTest.java new file mode 100644 index 000000000000..a1e6e86ac350 --- /dev/null +++ b/server/src/test/java/org/apache/druid/server/coordinator/UserCompactionTaskQueryTuningConfigTest.java @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.server.coordinator; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.druid.data.input.SegmentsSplitHintSpec; +import org.apache.druid.jackson.DefaultObjectMapper; +import org.apache.druid.segment.IndexSpec; +import org.apache.druid.segment.data.CompressionFactory; +import org.apache.druid.segment.data.CompressionStrategy; +import org.apache.druid.segment.data.RoaringBitmapSerdeFactory; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; + +public class UserCompactionTaskQueryTuningConfigTest +{ + private static final ObjectMapper OBJECT_MAPPER = new DefaultObjectMapper(); + + @Test + public void testSerdeNulls() throws IOException + { + final UserCompactionTaskQueryTuningConfig config = + new UserCompactionTaskQueryTuningConfig(null, null, null, null, null, null, null, null); + final String json = OBJECT_MAPPER.writeValueAsString(config); + // Check maxRowsPerSegment doesn't exist in the JSON string + Assert.assertFalse(json.contains("maxRowsPerSegment")); + final UserCompactionTaskQueryTuningConfig fromJson = + OBJECT_MAPPER.readValue(json, UserCompactionTaskQueryTuningConfig.class); + Assert.assertEquals(config, fromJson); + } + + @Test + public void testSerde() throws IOException + { + final UserCompactionTaskQueryTuningConfig tuningConfig = new UserCompactionTaskQueryTuningConfig( + 1000, + 10000L, + 2000L, + new SegmentsSplitHintSpec(42L), + new IndexSpec( + new RoaringBitmapSerdeFactory(false), + CompressionStrategy.LZF, + CompressionStrategy.UNCOMPRESSED, + CompressionFactory.LongEncodingStrategy.LONGS + ), + 1, + 3000L, + 5 + ); + + final String json = OBJECT_MAPPER.writeValueAsString(tuningConfig); + final UserCompactionTaskQueryTuningConfig fromJson = + OBJECT_MAPPER.readValue(json, UserCompactionTaskQueryTuningConfig.class); + Assert.assertEquals(tuningConfig, fromJson); + } +} diff --git a/server/src/test/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorSegmentCompactorTest.java b/server/src/test/java/org/apache/druid/server/coordinator/duty/CompactSegmentsTest.java similarity index 89% rename from server/src/test/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorSegmentCompactorTest.java rename to server/src/test/java/org/apache/druid/server/coordinator/duty/CompactSegmentsTest.java index 1398a39aa912..2024274417b0 100644 --- a/server/src/test/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorSegmentCompactorTest.java +++ b/server/src/test/java/org/apache/druid/server/coordinator/duty/CompactSegmentsTest.java @@ -17,14 +17,14 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import org.apache.druid.client.DataSourcesSnapshot; -import org.apache.druid.client.indexing.ClientCompactQueryTuningConfig; +import org.apache.druid.client.indexing.ClientCompactionTaskQueryTuningConfig; import org.apache.druid.client.indexing.IndexingServiceClient; import org.apache.druid.client.indexing.NoopIndexingServiceClient; import org.apache.druid.indexer.TaskStatusPlus; @@ -56,7 +56,7 @@ import java.util.Map; import java.util.function.Supplier; -public class DruidCoordinatorSegmentCompactorTest +public class CompactSegmentsTest { private static final String DATA_SOURCE_PREFIX = "dataSource_"; @@ -69,7 +69,7 @@ public class DruidCoordinatorSegmentCompactorTest public String compactSegments( List segments, int compactionTaskPriority, - ClientCompactQueryTuningConfig tuningConfig, + ClientCompactionTaskQueryTuningConfig tuningConfig, Map context ) { @@ -195,10 +195,7 @@ private static DataSegment createSegment(String dataSource, int startDay, boolea @Test public void testRun() { - final DruidCoordinatorSegmentCompactor compactor = new DruidCoordinatorSegmentCompactor( - new DefaultObjectMapper(), - indexingServiceClient - ); + final CompactSegments compactSegments = new CompactSegments(new DefaultObjectMapper(), indexingServiceClient); final Supplier expectedVersionSupplier = new Supplier() { @@ -215,7 +212,7 @@ public String get() // compact for 2017-01-08T12:00:00.000Z/2017-01-09T12:00:00.000Z assertCompactSegments( - compactor, + compactSegments, Intervals.of("2017-01-%02dT00:00:00/2017-01-%02dT12:00:00", 9, 9), expectedRemainingSegments, expectedCompactTaskCount, @@ -223,7 +220,7 @@ public String get() ); expectedRemainingSegments -= 40; assertCompactSegments( - compactor, + compactSegments, Intervals.of("2017-01-%02dT12:00:00/2017-01-%02dT00:00:00", 8, 9), expectedRemainingSegments, expectedCompactTaskCount, @@ -233,7 +230,7 @@ public String get() // compact for 2017-01-07T12:00:00.000Z/2017-01-08T12:00:00.000Z expectedRemainingSegments -= 40; assertCompactSegments( - compactor, + compactSegments, Intervals.of("2017-01-%02dT00:00:00/2017-01-%02dT12:00:00", 8, 8), expectedRemainingSegments, expectedCompactTaskCount, @@ -241,7 +238,7 @@ public String get() ); expectedRemainingSegments -= 40; assertCompactSegments( - compactor, + compactSegments, Intervals.of("2017-01-%02dT12:00:00/2017-01-%02dT00:00:00", 4, 5), expectedRemainingSegments, expectedCompactTaskCount, @@ -251,7 +248,7 @@ public String get() for (int endDay = 4; endDay > 1; endDay -= 1) { expectedRemainingSegments -= 40; assertCompactSegments( - compactor, + compactSegments, Intervals.of("2017-01-%02dT00:00:00/2017-01-%02dT12:00:00", endDay, endDay), expectedRemainingSegments, expectedCompactTaskCount, @@ -259,7 +256,7 @@ public String get() ); expectedRemainingSegments -= 40; assertCompactSegments( - compactor, + compactSegments, Intervals.of("2017-01-%02dT12:00:00/2017-01-%02dT00:00:00", endDay - 1, endDay), expectedRemainingSegments, expectedCompactTaskCount, @@ -267,21 +264,21 @@ public String get() ); } - assertLastSegmentNotCompacted(compactor); + assertLastSegmentNotCompacted(compactSegments); } - private CoordinatorStats runCompactor(DruidCoordinatorSegmentCompactor compactor) + private CoordinatorStats doCompactSegments(CompactSegments compactSegments) { DruidCoordinatorRuntimeParams params = CoordinatorRuntimeParamsTestHelpers .newBuilder() .withUsedSegmentsTimelinesPerDataSourceInTest(dataSources) .withCompactionConfig(CoordinatorCompactionConfig.from(createCompactionConfigs())) .build(); - return compactor.run(params).getCoordinatorStats(); + return compactSegments.run(params).getCoordinatorStats(); } private void assertCompactSegments( - DruidCoordinatorSegmentCompactor compactor, + CompactSegments compactSegments, Interval expectedInterval, int expectedRemainingSegments, int expectedCompactTaskCount, @@ -289,10 +286,10 @@ private void assertCompactSegments( ) { for (int i = 0; i < 3; i++) { - final CoordinatorStats stats = runCompactor(compactor); + final CoordinatorStats stats = doCompactSegments(compactSegments); Assert.assertEquals( expectedCompactTaskCount, - stats.getGlobalStat(DruidCoordinatorSegmentCompactor.COMPACT_TASK_COUNT) + stats.getGlobalStat(CompactSegments.COMPACTION_TASK_COUNT) ); // One of dataSource is compacted @@ -300,9 +297,9 @@ private void assertCompactSegments( // If expectedRemainingSegments is positive, we check how many dataSources have the segments waiting for // compaction. long numDataSourceOfExpectedRemainingSegments = stats - .getDataSources(DruidCoordinatorSegmentCompactor.SEGMENT_SIZE_WAIT_COMPACT) + .getDataSources(CompactSegments.TOTAL_SIZE_OF_SEGMENTS_AWAITING_COMPACTION) .stream() - .mapToLong(ds -> stats.getDataSourceStat(DruidCoordinatorSegmentCompactor.SEGMENT_SIZE_WAIT_COMPACT, ds)) + .mapToLong(ds -> stats.getDataSourceStat(CompactSegments.TOTAL_SIZE_OF_SEGMENTS_AWAITING_COMPACTION, ds)) .filter(stat -> stat == expectedRemainingSegments) .count(); Assert.assertEquals(i + 1, numDataSourceOfExpectedRemainingSegments); @@ -310,7 +307,7 @@ private void assertCompactSegments( // Otherwise, we check how many dataSources are in the coordinator stats. Assert.assertEquals( 2 - i, - stats.getDataSources(DruidCoordinatorSegmentCompactor.SEGMENT_SIZE_WAIT_COMPACT).size() + stats.getDataSources(CompactSegments.TOTAL_SIZE_OF_SEGMENTS_AWAITING_COMPACTION).size() ); } } @@ -329,7 +326,7 @@ private void assertCompactSegments( } } - private void assertLastSegmentNotCompacted(DruidCoordinatorSegmentCompactor compactor) + private void assertLastSegmentNotCompacted(CompactSegments compactSegments) { // Segments of the latest interval should not be compacted for (int i = 0; i < 3; i++) { @@ -352,18 +349,18 @@ private void assertLastSegmentNotCompacted(DruidCoordinatorSegmentCompactor comp final String dataSource = DATA_SOURCE_PREFIX + 0; addMoreData(dataSource, 9); - CoordinatorStats stats = runCompactor(compactor); + CoordinatorStats stats = doCompactSegments(compactSegments); Assert.assertEquals( 1, - stats.getGlobalStat(DruidCoordinatorSegmentCompactor.COMPACT_TASK_COUNT) + stats.getGlobalStat(CompactSegments.COMPACTION_TASK_COUNT) ); addMoreData(dataSource, 10); - stats = runCompactor(compactor); + stats = doCompactSegments(compactSegments); Assert.assertEquals( 1, - stats.getGlobalStat(DruidCoordinatorSegmentCompactor.COMPACT_TASK_COUNT) + stats.getGlobalStat(CompactSegments.COMPACTION_TASK_COUNT) ); } diff --git a/server/src/test/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorSegmentKillerTest.java b/server/src/test/java/org/apache/druid/server/coordinator/duty/KillUnusedSegmentsTest.java similarity index 86% rename from server/src/test/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorSegmentKillerTest.java rename to server/src/test/java/org/apache/druid/server/coordinator/duty/KillUnusedSegmentsTest.java index bf22e6fd8d6d..38aa78e4467c 100644 --- a/server/src/test/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorSegmentKillerTest.java +++ b/server/src/test/java/org/apache/druid/server/coordinator/duty/KillUnusedSegmentsTest.java @@ -17,12 +17,12 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import com.google.common.collect.ImmutableList; import org.apache.druid.client.indexing.IndexingServiceClient; import org.apache.druid.java.util.common.Intervals; -import org.apache.druid.metadata.MetadataSegmentManager; +import org.apache.druid.metadata.SegmentsMetadataManager; import org.apache.druid.server.coordinator.TestDruidCoordinatorConfig; import org.easymock.EasyMock; import org.joda.time.DateTime; @@ -35,7 +35,7 @@ /** */ -public class DruidCoordinatorSegmentKillerTest +public class KillUnusedSegmentsTest { @Test public void testFindIntervalForKill() @@ -87,19 +87,19 @@ public void testFindIntervalForKill() private void testFindIntervalForKill(List segmentIntervals, Interval expected) { - MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); + SegmentsMetadataManager segmentsMetadataManager = EasyMock.createMock(SegmentsMetadataManager.class); EasyMock.expect( - segmentsMetadata.getUnusedSegmentIntervals( + segmentsMetadataManager.getUnusedSegmentIntervals( EasyMock.anyString(), EasyMock.anyObject(DateTime.class), EasyMock.anyInt() ) ).andReturn(segmentIntervals); - EasyMock.replay(segmentsMetadata); + EasyMock.replay(segmentsMetadataManager); IndexingServiceClient indexingServiceClient = EasyMock.createMock(IndexingServiceClient.class); - DruidCoordinatorSegmentKiller coordinatorSegmentKiller = new DruidCoordinatorSegmentKiller( - segmentsMetadata, + KillUnusedSegments unusedSegmentsKiller = new KillUnusedSegments( + segmentsMetadataManager, indexingServiceClient, new TestDruidCoordinatorConfig( null, @@ -115,7 +115,7 @@ private void testFindIntervalForKill(List segmentIntervals, Interval e Assert.assertEquals( expected, - coordinatorSegmentKiller.findIntervalForKill("test", 10000) + unusedSegmentsKiller.findIntervalForKill("test", 10000) ); } } diff --git a/server/src/test/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorCleanupOvershadowedTest.java b/server/src/test/java/org/apache/druid/server/coordinator/duty/MarkAsUnusedOvershadowedSegmentsTest.java similarity index 90% rename from server/src/test/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorCleanupOvershadowedTest.java rename to server/src/test/java/org/apache/druid/server/coordinator/duty/MarkAsUnusedOvershadowedSegmentsTest.java index dfe41851bd65..73b95ee960ce 100644 --- a/server/src/test/java/org/apache/druid/server/coordinator/helper/DruidCoordinatorCleanupOvershadowedTest.java +++ b/server/src/test/java/org/apache/druid/server/coordinator/duty/MarkAsUnusedOvershadowedSegmentsTest.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; @@ -30,9 +30,9 @@ import org.apache.druid.server.coordinator.DruidCluster; import org.apache.druid.server.coordinator.DruidClusterBuilder; import org.apache.druid.server.coordinator.DruidCoordinator; -import org.apache.druid.server.coordinator.DruidCoordinatorRuleRunnerTest; import org.apache.druid.server.coordinator.DruidCoordinatorRuntimeParams; import org.apache.druid.server.coordinator.LoadQueuePeon; +import org.apache.druid.server.coordinator.RunRulesTest; import org.apache.druid.server.coordinator.ServerHolder; import org.apache.druid.timeline.DataSegment; import org.easymock.EasyMock; @@ -42,9 +42,9 @@ import java.util.List; -public class DruidCoordinatorCleanupOvershadowedTest +public class MarkAsUnusedOvershadowedSegmentsTest { - DruidCoordinatorCleanupOvershadowed druidCoordinatorMarkAsUnusedOvershadowedSegments; + MarkAsUnusedOvershadowedSegments markAsUnusedOvershadowedSegments; DruidCoordinator coordinator = EasyMock.createStrictMock(DruidCoordinator.class); private List usedSegments; DateTime start = DateTimes.of("2012-01-01"); @@ -71,7 +71,8 @@ public class DruidCoordinatorCleanupOvershadowedTest @Test public void testRun() { - druidCoordinatorMarkAsUnusedOvershadowedSegments = new DruidCoordinatorCleanupOvershadowed(coordinator); + markAsUnusedOvershadowedSegments = + new MarkAsUnusedOvershadowedSegments(coordinator); usedSegments = ImmutableList.of(segmentV1, segmentV0, segmentV2); // Dummy values for comparisons in TreeSet @@ -120,10 +121,10 @@ public void testRun() .withCoordinatorStats(new CoordinatorStats()) .withDruidCluster(druidCluster) .withDynamicConfigs( - DruidCoordinatorRuleRunnerTest.COORDINATOR_CONFIG_WITH_ZERO_LEADING_TIME_BEFORE_CAN_MARK_AS_UNUSED_OVERSHADOWED_SEGMENTS + RunRulesTest.COORDINATOR_CONFIG_WITH_ZERO_LEADING_TIME_BEFORE_CAN_MARK_AS_UNUSED_OVERSHADOWED_SEGMENTS ) .build(); - druidCoordinatorMarkAsUnusedOvershadowedSegments.run(params); + markAsUnusedOvershadowedSegments.run(params); EasyMock.verify(coordinator, druidDataSource, druidServer); } } diff --git a/server/src/test/java/org/apache/druid/server/coordinator/helper/NewestSegmentFirstIteratorTest.java b/server/src/test/java/org/apache/druid/server/coordinator/duty/NewestSegmentFirstIteratorTest.java similarity index 98% rename from server/src/test/java/org/apache/druid/server/coordinator/helper/NewestSegmentFirstIteratorTest.java rename to server/src/test/java/org/apache/druid/server/coordinator/duty/NewestSegmentFirstIteratorTest.java index 0e5f33397090..26199e3e8f47 100644 --- a/server/src/test/java/org/apache/druid/server/coordinator/helper/NewestSegmentFirstIteratorTest.java +++ b/server/src/test/java/org/apache/druid/server/coordinator/duty/NewestSegmentFirstIteratorTest.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; diff --git a/server/src/test/java/org/apache/druid/server/coordinator/helper/NewestSegmentFirstPolicyTest.java b/server/src/test/java/org/apache/druid/server/coordinator/duty/NewestSegmentFirstPolicyTest.java similarity index 98% rename from server/src/test/java/org/apache/druid/server/coordinator/helper/NewestSegmentFirstPolicyTest.java rename to server/src/test/java/org/apache/druid/server/coordinator/duty/NewestSegmentFirstPolicyTest.java index c5623b39809c..749f9d7c89f6 100644 --- a/server/src/test/java/org/apache/druid/server/coordinator/helper/NewestSegmentFirstPolicyTest.java +++ b/server/src/test/java/org/apache/druid/server/coordinator/duty/NewestSegmentFirstPolicyTest.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.druid.server.coordinator.helper; +package org.apache.druid.server.coordinator.duty; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -121,7 +121,7 @@ public void testLargeGapInData() DATA_SOURCE, createTimeline( new SegmentGenerateSpec(Intervals.of("2017-11-16T20:00:00/2017-11-17T04:00:00"), segmentPeriod), - // larger gap than SegmentCompactorUtil.LOOKUP_PERIOD (1 day) + // larger gap than SegmentCompactionUtil.LOOKUP_PERIOD (1 day) new SegmentGenerateSpec(Intervals.of("2017-11-14T00:00:00/2017-11-15T07:00:00"), segmentPeriod) ) ), @@ -537,7 +537,7 @@ private static VersionedIntervalTimeline createTimeline( segments.add(segment); } - remainingInterval = SegmentCompactorUtil.removeIntervalFromEnd(remainingInterval, segmentInterval); + remainingInterval = SegmentCompactionUtil.removeIntervalFromEnd(remainingInterval, segmentInterval); } } diff --git a/server/src/test/java/org/apache/druid/server/coordinator/rules/BroadcastDistributionRuleTest.java b/server/src/test/java/org/apache/druid/server/coordinator/rules/BroadcastDistributionRuleTest.java index cdb5e416da82..70ec3ebec052 100644 --- a/server/src/test/java/org/apache/druid/server/coordinator/rules/BroadcastDistributionRuleTest.java +++ b/server/src/test/java/org/apache/druid/server/coordinator/rules/BroadcastDistributionRuleTest.java @@ -412,8 +412,10 @@ public void testBroadcastToAllServers() Assert.assertFalse(stats.hasPerTierStats()); Assert.assertTrue( - druidCluster.getAllServers().stream() - .allMatch(holder -> holder.getPeon().getSegmentsToLoad().contains(smallSegment)) + druidCluster + .getAllServers() + .stream() + .allMatch(holder -> holder.getPeon().getSegmentsToLoad().contains(smallSegment)) ); } } diff --git a/server/src/test/java/org/apache/druid/server/http/DataSourcesResourceTest.java b/server/src/test/java/org/apache/druid/server/http/DataSourcesResourceTest.java index e200e700e8eb..10a7f97300c9 100644 --- a/server/src/test/java/org/apache/druid/server/http/DataSourcesResourceTest.java +++ b/server/src/test/java/org/apache/druid/server/http/DataSourcesResourceTest.java @@ -33,8 +33,8 @@ import org.apache.druid.client.indexing.IndexingServiceClient; import org.apache.druid.java.util.common.Intervals; import org.apache.druid.metadata.MetadataRuleManager; -import org.apache.druid.metadata.MetadataSegmentManager; -import org.apache.druid.metadata.UnknownSegmentIdException; +import org.apache.druid.metadata.SegmentsMetadataManager; +import org.apache.druid.metadata.UnknownSegmentIdsException; import org.apache.druid.query.SegmentDescriptor; import org.apache.druid.query.TableDataSource; import org.apache.druid.server.coordination.DruidServerMetadata; @@ -83,6 +83,7 @@ public class DataSourcesResourceTest private List listDataSources; private List dataSegmentList; private HttpServletRequest request; + private SegmentsMetadataManager segmentsMetadataManager; @Before public void setUp() @@ -137,6 +138,7 @@ public void setUp() listDataSources.add( new DruidDataSource("datasource2", new HashMap<>()).addSegment(dataSegmentList.get(1)) ); + segmentsMetadataManager = EasyMock.createMock(SegmentsMetadataManager.class); } @Test @@ -586,13 +588,13 @@ public void testKillSegmentsInIntervalInDataSource() Interval theInterval = Intervals.of(interval.replace('_', '/')); IndexingServiceClient indexingServiceClient = EasyMock.createStrictMock(IndexingServiceClient.class); - indexingServiceClient.killSegments("datasource1", theInterval); + indexingServiceClient.killUnusedSegments("datasource1", theInterval); EasyMock.expectLastCall().once(); EasyMock.replay(indexingServiceClient, server); DataSourcesResource dataSourcesResource = new DataSourcesResource(inventoryView, null, null, indexingServiceClient, null); - Response response = dataSourcesResource.killSegmentsInInterval("datasource1", interval); + Response response = dataSourcesResource.killUnusedSegmentsInInterval("datasource1", interval); Assert.assertEquals(200, response.getStatus()); Assert.assertEquals(null, response.getEntity()); @@ -608,7 +610,7 @@ public void testMarkAsUnusedAllSegmentsInDataSource() new DataSourcesResource(inventoryView, null, null, indexingServiceClient, null); try { Response response = - dataSourcesResource.markAsUnusedAllSegmentsOrKillSegmentsInInterval("datasource", "true", "???"); + dataSourcesResource.markAsUnusedAllSegmentsOrKillUnusedSegmentsInInterval("datasource", "true", "???"); // 400 (Bad Request) or an IllegalArgumentException is expected. Assert.assertEquals(400, response.getStatus()); Assert.assertNotNull(response.getEntity()); @@ -693,156 +695,147 @@ public List> lookupWithIncompleteP @Test public void testMarkSegmentAsUsed() { - MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); DataSegment segment = dataSegmentList.get(0); - EasyMock.expect(segmentsMetadata.markSegmentAsUsed(segment.getId().toString())).andReturn(true).once(); - EasyMock.replay(segmentsMetadata); + EasyMock.expect(segmentsMetadataManager.markSegmentAsUsed(segment.getId().toString())).andReturn(true).once(); + EasyMock.replay(segmentsMetadataManager); - DataSourcesResource dataSourcesResource = new DataSourcesResource(null, segmentsMetadata, null, null, null); + DataSourcesResource dataSourcesResource = new DataSourcesResource(null, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markSegmentAsUsed(segment.getDataSource(), segment.getId().toString()); Assert.assertEquals(200, response.getStatus()); - EasyMock.verify(segmentsMetadata); + EasyMock.verify(segmentsMetadataManager); } @Test public void testMarkSegmentAsUsedNoChange() { - MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); DataSegment segment = dataSegmentList.get(0); - EasyMock.expect(segmentsMetadata.markSegmentAsUsed(segment.getId().toString())).andReturn(false).once(); - EasyMock.replay(segmentsMetadata); + EasyMock.expect(segmentsMetadataManager.markSegmentAsUsed(segment.getId().toString())).andReturn(false).once(); + EasyMock.replay(segmentsMetadataManager); - DataSourcesResource dataSourcesResource = new DataSourcesResource(null, segmentsMetadata, null, null, null); + DataSourcesResource dataSourcesResource = new DataSourcesResource(null, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markSegmentAsUsed(segment.getDataSource(), segment.getId().toString()); Assert.assertEquals(200, response.getStatus()); Assert.assertEquals(ImmutableMap.of("segmentStateChanged", false), response.getEntity()); - EasyMock.verify(segmentsMetadata); + EasyMock.verify(segmentsMetadataManager); } @Test public void testMarkAsUsedNonOvershadowedSegmentsInterval() { - MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); DruidDataSource dataSource = new DruidDataSource("datasource1", new HashMap<>()); Interval interval = Intervals.of("2010-01-22/P1D"); int numUpdatedSegments = - segmentsMetadata.markAsUsedNonOvershadowedSegmentsInInterval(EasyMock.eq("datasource1"), EasyMock.eq(interval)); + segmentsMetadataManager.markAsUsedNonOvershadowedSegmentsInInterval(EasyMock.eq("datasource1"), EasyMock.eq(interval)); EasyMock.expect(numUpdatedSegments).andReturn(3).once(); EasyMock.expect(inventoryView.getInventory()).andReturn(ImmutableList.of(server)).once(); EasyMock.expect(server.getDataSource("datasource1")).andReturn(dataSource).once(); - EasyMock.replay(segmentsMetadata, inventoryView, server); + EasyMock.replay(segmentsMetadataManager, inventoryView, server); DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markAsUsedNonOvershadowedSegments( "datasource1", new DataSourcesResource.MarkDataSourceSegmentsPayload(interval, null) ); Assert.assertEquals(200, response.getStatus()); - EasyMock.verify(segmentsMetadata, inventoryView, server); + EasyMock.verify(segmentsMetadataManager, inventoryView, server); } @Test public void testMarkAsUsedNonOvershadowedSegmentsIntervalNoneUpdated() { - MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); DruidDataSource dataSource = new DruidDataSource("datasource1", new HashMap<>()); Interval interval = Intervals.of("2010-01-22/P1D"); int numUpdatedSegments = - segmentsMetadata.markAsUsedNonOvershadowedSegmentsInInterval(EasyMock.eq("datasource1"), EasyMock.eq(interval)); + segmentsMetadataManager.markAsUsedNonOvershadowedSegmentsInInterval(EasyMock.eq("datasource1"), EasyMock.eq(interval)); EasyMock.expect(numUpdatedSegments).andReturn(0).once(); EasyMock.expect(inventoryView.getInventory()).andReturn(ImmutableList.of(server)).once(); EasyMock.expect(server.getDataSource("datasource1")).andReturn(dataSource).once(); - EasyMock.replay(segmentsMetadata, inventoryView, server); + EasyMock.replay(segmentsMetadataManager, inventoryView, server); DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markAsUsedNonOvershadowedSegments( "datasource1", new DataSourcesResource.MarkDataSourceSegmentsPayload(interval, null) ); Assert.assertEquals(ImmutableMap.of("numChangedSegments", 0), response.getEntity()); - EasyMock.verify(segmentsMetadata, inventoryView, server); + EasyMock.verify(segmentsMetadataManager, inventoryView, server); } @Test - public void testMarkAsUsedNonOvershadowedSegmentsSet() throws UnknownSegmentIdException + public void testMarkAsUsedNonOvershadowedSegmentsSet() throws UnknownSegmentIdsException { - MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); DruidDataSource dataSource = new DruidDataSource("datasource1", new HashMap<>()); Set segmentIds = ImmutableSet.of(dataSegmentList.get(1).getId().toString()); int numUpdatedSegments = - segmentsMetadata.markAsUsedNonOvershadowedSegments(EasyMock.eq("datasource1"), EasyMock.eq(segmentIds)); + segmentsMetadataManager.markAsUsedNonOvershadowedSegments(EasyMock.eq("datasource1"), EasyMock.eq(segmentIds)); EasyMock.expect(numUpdatedSegments).andReturn(3).once(); EasyMock.expect(inventoryView.getInventory()).andReturn(ImmutableList.of(server)).once(); EasyMock.expect(server.getDataSource("datasource1")).andReturn(dataSource).once(); - EasyMock.replay(segmentsMetadata, inventoryView, server); + EasyMock.replay(segmentsMetadataManager, inventoryView, server); DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markAsUsedNonOvershadowedSegments( "datasource1", new DataSourcesResource.MarkDataSourceSegmentsPayload(null, segmentIds) ); Assert.assertEquals(200, response.getStatus()); - EasyMock.verify(segmentsMetadata, inventoryView, server); + EasyMock.verify(segmentsMetadataManager, inventoryView, server); } @Test public void testMarkAsUsedNonOvershadowedSegmentsIntervalException() { - MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); DruidDataSource dataSource = new DruidDataSource("datasource1", new HashMap<>()); Interval interval = Intervals.of("2010-01-22/P1D"); int numUpdatedSegments = - segmentsMetadata.markAsUsedNonOvershadowedSegmentsInInterval(EasyMock.eq("datasource1"), EasyMock.eq(interval)); + segmentsMetadataManager.markAsUsedNonOvershadowedSegmentsInInterval(EasyMock.eq("datasource1"), EasyMock.eq(interval)); EasyMock.expect(numUpdatedSegments).andThrow(new RuntimeException("Error!")).once(); EasyMock.expect(inventoryView.getInventory()).andReturn(ImmutableList.of(server)).once(); EasyMock.expect(server.getDataSource("datasource1")).andReturn(dataSource).once(); - EasyMock.replay(segmentsMetadata, inventoryView, server); + EasyMock.replay(segmentsMetadataManager, inventoryView, server); DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markAsUsedNonOvershadowedSegments( "datasource1", new DataSourcesResource.MarkDataSourceSegmentsPayload(interval, null) ); Assert.assertEquals(500, response.getStatus()); - EasyMock.verify(segmentsMetadata, inventoryView, server); + EasyMock.verify(segmentsMetadataManager, inventoryView, server); } @Test public void testMarkAsUsedNonOvershadowedSegmentsNoDataSource() { - MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); EasyMock.expect(inventoryView.getInventory()).andReturn(ImmutableList.of(server)).once(); EasyMock.expect(server.getDataSource("datasource1")).andReturn(null).once(); - EasyMock.replay(segmentsMetadata, inventoryView, server); + EasyMock.replay(segmentsMetadataManager, inventoryView, server); DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markAsUsedNonOvershadowedSegments( "datasource1", new DataSourcesResource.MarkDataSourceSegmentsPayload(Intervals.of("2010-01-22/P1D"), null) ); Assert.assertEquals(204, response.getStatus()); - EasyMock.verify(segmentsMetadata); + EasyMock.verify(segmentsMetadataManager); } @Test public void testMarkAsUsedNonOvershadowedSegmentsInvalidPayloadNoArguments() { - MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); - DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markAsUsedNonOvershadowedSegments( "datasource1", @@ -854,10 +847,8 @@ public void testMarkAsUsedNonOvershadowedSegmentsInvalidPayloadNoArguments() @Test public void testMarkAsUsedNonOvershadowedSegmentsInvalidPayloadBothArguments() { - MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); - DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markAsUsedNonOvershadowedSegments( "datasource1", @@ -869,10 +860,8 @@ public void testMarkAsUsedNonOvershadowedSegmentsInvalidPayloadBothArguments() @Test public void testMarkAsUsedNonOvershadowedSegmentsInvalidPayloadEmptyArray() { - MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); - DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markAsUsedNonOvershadowedSegments( "datasource1", @@ -884,10 +873,8 @@ public void testMarkAsUsedNonOvershadowedSegmentsInvalidPayloadEmptyArray() @Test public void testMarkAsUsedNonOvershadowedSegmentsNoPayload() { - MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); - DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markAsUsedNonOvershadowedSegments("datasource1", null); Assert.assertEquals(400, response.getStatus()); @@ -1029,22 +1016,21 @@ public void testMarkSegmentsAsUnused() final DruidDataSource dataSource1 = new DruidDataSource("datasource1", new HashMap<>()); final Set segmentIds = dataSegmentList.stream().map(ds -> ds.getId().toString()).collect(Collectors.toSet()); - final MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); EasyMock.expect(inventoryView.getInventory()).andReturn(ImmutableList.of(server)).once(); EasyMock.expect(server.getDataSource("datasource1")).andReturn(dataSource1).once(); - EasyMock.expect(segmentsMetadata.markSegmentsAsUnused("datasource1", segmentIds)).andReturn(1).once(); - EasyMock.replay(segmentsMetadata, inventoryView, server); + EasyMock.expect(segmentsMetadataManager.markSegmentsAsUnused("datasource1", segmentIds)).andReturn(1).once(); + EasyMock.replay(segmentsMetadataManager, inventoryView, server); final DataSourcesResource.MarkDataSourceSegmentsPayload payload = new DataSourcesResource.MarkDataSourceSegmentsPayload(null, segmentIds); DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markSegmentsAsUnused("datasource1", payload); Assert.assertEquals(200, response.getStatus()); Assert.assertEquals(ImmutableMap.of("numChangedSegments", 1), response.getEntity()); - EasyMock.verify(segmentsMetadata, inventoryView, server); + EasyMock.verify(segmentsMetadataManager, inventoryView, server); } @Test @@ -1053,22 +1039,21 @@ public void testMarkSegmentsAsUnusedNoChanges() final DruidDataSource dataSource1 = new DruidDataSource("datasource1", new HashMap<>()); final Set segmentIds = dataSegmentList.stream().map(ds -> ds.getId().toString()).collect(Collectors.toSet()); - final MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); EasyMock.expect(inventoryView.getInventory()).andReturn(ImmutableList.of(server)).once(); EasyMock.expect(server.getDataSource("datasource1")).andReturn(dataSource1).once(); - EasyMock.expect(segmentsMetadata.markSegmentsAsUnused("datasource1", segmentIds)).andReturn(0).once(); - EasyMock.replay(segmentsMetadata, inventoryView, server); + EasyMock.expect(segmentsMetadataManager.markSegmentsAsUnused("datasource1", segmentIds)).andReturn(0).once(); + EasyMock.replay(segmentsMetadataManager, inventoryView, server); final DataSourcesResource.MarkDataSourceSegmentsPayload payload = new DataSourcesResource.MarkDataSourceSegmentsPayload(null, segmentIds); DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markSegmentsAsUnused("datasource1", payload); Assert.assertEquals(200, response.getStatus()); Assert.assertEquals(ImmutableMap.of("numChangedSegments", 0), response.getEntity()); - EasyMock.verify(segmentsMetadata, inventoryView, server); + EasyMock.verify(segmentsMetadataManager, inventoryView, server); } @Test @@ -1077,24 +1062,23 @@ public void testMarkSegmentsAsUnusedException() final DruidDataSource dataSource1 = new DruidDataSource("datasource1", new HashMap<>()); final Set segmentIds = dataSegmentList.stream().map(ds -> ds.getId().toString()).collect(Collectors.toSet()); - final MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); EasyMock.expect(inventoryView.getInventory()).andReturn(ImmutableList.of(server)).once(); EasyMock.expect(server.getDataSource("datasource1")).andReturn(dataSource1).once(); - EasyMock.expect(segmentsMetadata.markSegmentsAsUnused("datasource1", segmentIds)) + EasyMock.expect(segmentsMetadataManager.markSegmentsAsUnused("datasource1", segmentIds)) .andThrow(new RuntimeException("Exception occurred")) .once(); - EasyMock.replay(segmentsMetadata, inventoryView, server); + EasyMock.replay(segmentsMetadataManager, inventoryView, server); final DataSourcesResource.MarkDataSourceSegmentsPayload payload = new DataSourcesResource.MarkDataSourceSegmentsPayload(null, segmentIds); DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markSegmentsAsUnused("datasource1", payload); Assert.assertEquals(500, response.getStatus()); Assert.assertNotNull(response.getEntity()); - EasyMock.verify(segmentsMetadata, inventoryView, server); + EasyMock.verify(segmentsMetadataManager, inventoryView, server); } @Test @@ -1102,23 +1086,22 @@ public void testMarkAsUnusedSegmentsInInterval() { final Interval theInterval = Intervals.of("2010-01-01/P1D"); final DruidDataSource dataSource1 = new DruidDataSource("datasource1", new HashMap<>()); - final MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); EasyMock.expect(inventoryView.getInventory()).andReturn(ImmutableList.of(server)).once(); EasyMock.expect(server.getDataSource("datasource1")).andReturn(dataSource1).once(); - EasyMock.expect(segmentsMetadata.markAsUnusedSegmentsInInterval("datasource1", theInterval)).andReturn(1).once(); - EasyMock.replay(segmentsMetadata, inventoryView, server); + EasyMock.expect(segmentsMetadataManager.markAsUnusedSegmentsInInterval("datasource1", theInterval)).andReturn(1).once(); + EasyMock.replay(segmentsMetadataManager, inventoryView, server); final DataSourcesResource.MarkDataSourceSegmentsPayload payload = new DataSourcesResource.MarkDataSourceSegmentsPayload(theInterval, null); DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markSegmentsAsUnused("datasource1", payload); Assert.assertEquals(200, response.getStatus()); Assert.assertEquals(ImmutableMap.of("numChangedSegments", 1), response.getEntity()); - EasyMock.verify(segmentsMetadata, inventoryView, server); - EasyMock.verify(segmentsMetadata, inventoryView, server); + EasyMock.verify(segmentsMetadataManager, inventoryView, server); + EasyMock.verify(segmentsMetadataManager, inventoryView, server); } @Test @@ -1126,22 +1109,21 @@ public void testMarkAsUnusedSegmentsInIntervalNoChanges() { final Interval theInterval = Intervals.of("2010-01-01/P1D"); final DruidDataSource dataSource1 = new DruidDataSource("datasource1", new HashMap<>()); - final MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); EasyMock.expect(inventoryView.getInventory()).andReturn(ImmutableList.of(server)).once(); EasyMock.expect(server.getDataSource("datasource1")).andReturn(dataSource1).once(); - EasyMock.expect(segmentsMetadata.markAsUnusedSegmentsInInterval("datasource1", theInterval)).andReturn(0).once(); - EasyMock.replay(segmentsMetadata, inventoryView, server); + EasyMock.expect(segmentsMetadataManager.markAsUnusedSegmentsInInterval("datasource1", theInterval)).andReturn(0).once(); + EasyMock.replay(segmentsMetadataManager, inventoryView, server); final DataSourcesResource.MarkDataSourceSegmentsPayload payload = new DataSourcesResource.MarkDataSourceSegmentsPayload(theInterval, null); DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markSegmentsAsUnused("datasource1", payload); Assert.assertEquals(200, response.getStatus()); Assert.assertEquals(ImmutableMap.of("numChangedSegments", 0), response.getEntity()); - EasyMock.verify(segmentsMetadata, inventoryView, server); + EasyMock.verify(segmentsMetadataManager, inventoryView, server); } @Test @@ -1149,32 +1131,30 @@ public void testMarkAsUnusedSegmentsInIntervalException() { final Interval theInterval = Intervals.of("2010-01-01/P1D"); final DruidDataSource dataSource1 = new DruidDataSource("datasource1", new HashMap<>()); - final MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); EasyMock.expect(inventoryView.getInventory()).andReturn(ImmutableList.of(server)).once(); EasyMock.expect(server.getDataSource("datasource1")).andReturn(dataSource1).once(); - EasyMock.expect(segmentsMetadata.markAsUnusedSegmentsInInterval("datasource1", theInterval)) + EasyMock.expect(segmentsMetadataManager.markAsUnusedSegmentsInInterval("datasource1", theInterval)) .andThrow(new RuntimeException("Exception occurred")) .once(); - EasyMock.replay(segmentsMetadata, inventoryView, server); + EasyMock.replay(segmentsMetadataManager, inventoryView, server); final DataSourcesResource.MarkDataSourceSegmentsPayload payload = new DataSourcesResource.MarkDataSourceSegmentsPayload(theInterval, null); DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markSegmentsAsUnused("datasource1", payload); Assert.assertEquals(500, response.getStatus()); Assert.assertNotNull(response.getEntity()); - EasyMock.verify(segmentsMetadata, inventoryView, server); + EasyMock.verify(segmentsMetadataManager, inventoryView, server); } @Test - public void testMarkSegmentsUnusedNullPayload() + public void testMarkSegmentsAsUnusedNullPayload() { - final MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); Response response = dataSourcesResource.markSegmentsAsUnused("datasource1", null); Assert.assertEquals(400, response.getStatus()); @@ -1186,11 +1166,10 @@ public void testMarkSegmentsUnusedNullPayload() } @Test - public void testMarkSegmentsUnusedInvalidPayload() + public void testMarkSegmentsAsUnusedInvalidPayload() { - final MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); final DataSourcesResource.MarkDataSourceSegmentsPayload payload = new DataSourcesResource.MarkDataSourceSegmentsPayload(null, null); @@ -1201,11 +1180,10 @@ public void testMarkSegmentsUnusedInvalidPayload() } @Test - public void testMarkSegmentsUnusedInvalidPayloadBothArguments() + public void testMarkSegmentsAsUnusedInvalidPayloadBothArguments() { - final MetadataSegmentManager segmentsMetadata = EasyMock.createMock(MetadataSegmentManager.class); DataSourcesResource dataSourcesResource = - new DataSourcesResource(inventoryView, segmentsMetadata, null, null, null); + new DataSourcesResource(inventoryView, segmentsMetadataManager, null, null, null); final DataSourcesResource.MarkDataSourceSegmentsPayload payload = new DataSourcesResource.MarkDataSourceSegmentsPayload(Intervals.of("2010-01-01/P1D"), ImmutableSet.of()); diff --git a/services/src/main/java/org/apache/druid/cli/CliCoordinator.java b/services/src/main/java/org/apache/druid/cli/CliCoordinator.java index 6e4c27fbc292..f3415d62cba1 100644 --- a/services/src/main/java/org/apache/druid/cli/CliCoordinator.java +++ b/services/src/main/java/org/apache/druid/cli/CliCoordinator.java @@ -44,7 +44,7 @@ import org.apache.druid.guice.LazySingleton; import org.apache.druid.guice.LifecycleModule; import org.apache.druid.guice.ManageLifecycle; -import org.apache.druid.guice.annotations.CoordinatorIndexingServiceHelper; +import org.apache.druid.guice.annotations.CoordinatorIndexingServiceDuty; import org.apache.druid.guice.annotations.EscalatedGlobal; import org.apache.druid.guice.http.JettyHttpClientModule; import org.apache.druid.java.util.common.concurrent.Execs; @@ -56,21 +56,21 @@ import org.apache.druid.metadata.MetadataRuleManager; import org.apache.druid.metadata.MetadataRuleManagerConfig; import org.apache.druid.metadata.MetadataRuleManagerProvider; -import org.apache.druid.metadata.MetadataSegmentManager; -import org.apache.druid.metadata.MetadataSegmentManagerConfig; -import org.apache.druid.metadata.MetadataSegmentManagerProvider; import org.apache.druid.metadata.MetadataStorage; import org.apache.druid.metadata.MetadataStorageProvider; +import org.apache.druid.metadata.SegmentsMetadataManager; +import org.apache.druid.metadata.SegmentsMetadataManagerConfig; +import org.apache.druid.metadata.SegmentsMetadataManagerProvider; import org.apache.druid.query.lookup.LookupSerdeModule; import org.apache.druid.server.audit.AuditManagerProvider; import org.apache.druid.server.coordinator.BalancerStrategyFactory; import org.apache.druid.server.coordinator.CachingCostBalancerStrategyConfig; import org.apache.druid.server.coordinator.DruidCoordinator; -import org.apache.druid.server.coordinator.DruidCoordinatorCleanupPendingSegments; import org.apache.druid.server.coordinator.DruidCoordinatorConfig; +import org.apache.druid.server.coordinator.KillStalePendingSegments; import org.apache.druid.server.coordinator.LoadQueueTaskMaster; -import org.apache.druid.server.coordinator.helper.DruidCoordinatorHelper; -import org.apache.druid.server.coordinator.helper.DruidCoordinatorSegmentKiller; +import org.apache.druid.server.coordinator.duty.CoordinatorDuty; +import org.apache.druid.server.coordinator.duty.KillUnusedSegments; import org.apache.druid.server.http.ClusterResource; import org.apache.druid.server.http.CoordinatorCompactionConfigsResource; import org.apache.druid.server.http.CoordinatorDynamicConfigsResource; @@ -152,7 +152,7 @@ public void configure(Binder binder) binder.bind(MetadataStorage.class).toProvider(MetadataStorageProvider.class); - JsonConfigProvider.bind(binder, "druid.manager.segments", MetadataSegmentManagerConfig.class); + JsonConfigProvider.bind(binder, "druid.manager.segments", SegmentsMetadataManagerConfig.class); JsonConfigProvider.bind(binder, "druid.manager.rules", MetadataRuleManagerConfig.class); JsonConfigProvider.bind(binder, "druid.manager.lookups", LookupCoordinatorManagerConfig.class); JsonConfigProvider.bind(binder, "druid.coordinator.balancer", BalancerStrategyFactory.class); @@ -170,8 +170,8 @@ public void configure(Binder binder) binder.bind(RedirectInfo.class).to(CoordinatorRedirectInfo.class).in(LazySingleton.class); } - binder.bind(MetadataSegmentManager.class) - .toProvider(MetadataSegmentManagerProvider.class) + binder.bind(SegmentsMetadataManager.class) + .toProvider(SegmentsMetadataManagerProvider.class) .in(ManageLifecycle.class); binder.bind(MetadataRuleManager.class) @@ -211,11 +211,11 @@ public void configure(Binder binder) LifecycleModule.register(binder, Server.class); LifecycleModule.register(binder, DataSourcesResource.class); - final ConditionalMultibind conditionalMultibind = ConditionalMultibind.create( + final ConditionalMultibind conditionalMultibind = ConditionalMultibind.create( properties, binder, - DruidCoordinatorHelper.class, - CoordinatorIndexingServiceHelper.class + CoordinatorDuty.class, + CoordinatorIndexingServiceDuty.class ); if (conditionalMultibind.matchCondition("druid.coordinator.merge.on", Predicates.equalTo("true"))) { @@ -231,11 +231,11 @@ public void configure(Binder binder) conditionalMultibind.addConditionBinding( "druid.coordinator.kill.on", Predicates.equalTo("true"), - DruidCoordinatorSegmentKiller.class + KillUnusedSegments.class ).addConditionBinding( "druid.coordinator.kill.pendingSegments.on", Predicates.equalTo("true"), - DruidCoordinatorCleanupPendingSegments.class + KillStalePendingSegments.class ); bindNodeRoleAndAnnouncer( diff --git a/services/src/main/java/org/apache/druid/cli/CliInternalHadoopIndexer.java b/services/src/main/java/org/apache/druid/cli/CliInternalHadoopIndexer.java index 3e9c6b64ffef..4235abbf884c 100644 --- a/services/src/main/java/org/apache/druid/cli/CliInternalHadoopIndexer.java +++ b/services/src/main/java/org/apache/druid/cli/CliInternalHadoopIndexer.java @@ -108,13 +108,11 @@ public void run() Preconditions.checkNotNull(metadataSpec.getType(), "type in metadataUpdateSpec must not be null"); injector.getInstance(Properties.class).setProperty("druid.metadata.storage.type", metadataSpec.getType()); - config = HadoopDruidIndexerConfig.fromSpec( - HadoopIngestionSpec.updateSegmentListIfDatasourcePathSpecIsUsed( - config.getSchema(), - HadoopDruidIndexerConfig.JSON_MAPPER, - new MetadataStoreBasedUsedSegmentsRetriever( - injector.getInstance(IndexerMetadataStorageCoordinator.class) - ) + HadoopIngestionSpec.updateSegmentListIfDatasourcePathSpecIsUsed( + config.getSchema(), + HadoopDruidIndexerConfig.JSON_MAPPER, + new MetadataStoreBasedUsedSegmentsRetriever( + injector.getInstance(IndexerMetadataStorageCoordinator.class) ) ); diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/schema/MetadataSegmentView.java b/sql/src/main/java/org/apache/druid/sql/calcite/schema/MetadataSegmentView.java index 18d288eb6915..05cda79fd13d 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/schema/MetadataSegmentView.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/schema/MetadataSegmentView.java @@ -41,6 +41,7 @@ import org.apache.druid.java.util.common.lifecycle.LifecycleStop; import org.apache.druid.java.util.emitter.EmittingLogger; import org.apache.druid.java.util.http.client.Request; +import org.apache.druid.metadata.SegmentsMetadataManager; import org.apache.druid.server.coordinator.BytesAccumulatingResponseHandler; import org.apache.druid.sql.calcite.planner.PlannerConfig; import org.apache.druid.timeline.DataSegment; @@ -57,8 +58,13 @@ import java.util.concurrent.TimeUnit; /** - * This class polls the coordinator in background to keep the latest published segments. + * This class polls the Coordinator in background to keep the latest published segments. * Provides {@link #getPublishedSegments()} for others to get segments in metadata store. + * + * The difference between this class and {@link SegmentsMetadataManager} is that this class resides + * in Broker's memory, while {@link SegmentsMetadataManager} resides in Coordinator's memory. In + * fact, this class polls the data from {@link SegmentsMetadataManager} object in the memory of the + * currently leading Coordinator via HTTP queries. */ @ManageLifecycle public class MetadataSegmentView @@ -160,7 +166,7 @@ private void poll() cachePopulated.countDown(); } - public Iterator getPublishedSegments() + Iterator getPublishedSegments() { if (isCacheEnabled) { Uninterruptibles.awaitUninterruptibly(cachePopulated); diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/schema/SystemSchema.java b/sql/src/main/java/org/apache/druid/sql/calcite/schema/SystemSchema.java index eb06587599b6..06478b11b7d6 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/schema/SystemSchema.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/schema/SystemSchema.java @@ -285,17 +285,14 @@ public Enumerable scan(DataContext root) partialSegmentDataMap.put(h.getSegment().getId(), partialSegmentData); } - // get published segments from metadata segment cache (if enabled in sql planner config), else directly from - // coordinator + // Get published segments from metadata segment cache (if enabled in sql planner config), else directly from + // Coordinator. final Iterator metadataStoreSegments = metadataView.getPublishedSegments(); final Set segmentsAlreadySeen = new HashSet<>(); final FluentIterable publishedSegments = FluentIterable - .from(() -> getAuthorizedPublishedSegments( - metadataStoreSegments, - root - )) + .from(() -> getAuthorizedPublishedSegments(metadataStoreSegments, root)) .transform(val -> { try { final DataSegment segment = val.getDataSegment(); @@ -353,7 +350,8 @@ public Enumerable scan(DataContext root) numReplicas, val.getValue().getNumRows(), IS_PUBLISHED_FALSE, // is_published is false for unpublished segments - IS_AVAILABLE_TRUE, // is_available is assumed to be always true for segments announced by historicals or realtime tasks + // is_available is assumed to be always true for segments announced by historicals or realtime tasks + IS_AVAILABLE_TRUE, val.getValue().isRealtime(), IS_OVERSHADOWED_FALSE, // there is an assumption here that unpublished segments are never overshadowed jsonMapper.writeValueAsString(val.getKey()) @@ -398,8 +396,10 @@ private Iterator> getAuthorizedAvaila final AuthenticationResult authenticationResult = (AuthenticationResult) root.get(PlannerContext.DATA_CTX_AUTHENTICATION_RESULT); - Function, Iterable> raGenerator = segment -> Collections - .singletonList(AuthorizationUtils.DATASOURCE_READ_RA_GENERATOR.apply(segment.getKey().getDataSource())); + Function, Iterable> raGenerator = segment -> + Collections.singletonList( + AuthorizationUtils.DATASOURCE_READ_RA_GENERATOR.apply(segment.getKey().getDataSource()) + ); final Iterable> authorizedSegments = AuthorizationUtils.filterAuthorizedResources( diff --git a/web-console/src/views/datasource-view/__snapshots__/datasource-view.spec.tsx.snap b/web-console/src/views/datasource-view/__snapshots__/datasource-view.spec.tsx.snap index 89ca696958a2..7a2e3e7953d9 100755 --- a/web-console/src/views/datasource-view/__snapshots__/datasource-view.spec.tsx.snap +++ b/web-console/src/views/datasource-view/__snapshots__/datasource-view.spec.tsx.snap @@ -31,7 +31,7 @@ exports[`data source view matches snapshot 1`] = ` ; showChart: boolean; chartWidth: number; @@ -171,7 +171,7 @@ export class DatasourcesView extends React.PureComponent< DatasourcesViewProps, DatasourcesViewState > { - static DISABLED_COLOR = '#0a1500'; + static UNUSED_COLOR = '#0a1500'; static FULLY_AVAILABLE_COLOR = '#57d500'; static PARTIALLY_AVAILABLE_COLOR = '#ffbf00'; @@ -221,9 +221,9 @@ GROUP BY 1`; defaultRules: [], datasourceFilter, - showDisabled: false, - dropReloadAction: 'drop', - dropReloadInterval: '', + showUnused: false, + useUnuseAction: 'unuse', + useUnuseInterval: '', hiddenColumns: new LocalStorageBackedArray( LocalStorageKeys.DATASOURCE_TABLE_COLUMN_SELECTION, ), @@ -279,12 +279,14 @@ GROUP BY 1`; const seen = countBy(datasources, (x: any) => x.datasource); - let disabled: string[] = []; - if (this.state.showDisabled) { - const disabledResp = await axios.get( + let unused: string[] = []; + if (this.state.showUnused) { + // Using 'includeDisabled' parameter for compatibility. + // Should be changed to 'includeUnused' in Druid 0.17 + const unusedResp = await axios.get( '/druid/coordinator/v1/metadata/datasources?includeDisabled', ); - disabled = disabledResp.data.filter((d: string) => !seen[d]); + unused = unusedResp.data.filter((d: string) => !seen[d]); } const rulesResp = await axios.get('/druid/coordinator/v1/rules'); @@ -300,7 +302,7 @@ GROUP BY 1`; const tiers = tiersResp.data; const allDatasources = (datasources as any).concat( - disabled.map(d => ({ datasource: d, disabled: true })), + unused.map(d => ({ datasource: d, unused: true })), ); allDatasources.forEach((ds: any) => { ds.rules = rules[ds.datasource] || []; @@ -346,104 +348,103 @@ GROUP BY 1`; this.datasourceQueryManager.terminate(); } - renderDropDataAction() { - const { dropDataDatasource } = this.state; - if (!dropDataDatasource) return; + renderUnuseAction() { + const { datasourceToMarkAsUnusedAllSegmentsIn } = this.state; + if (!datasourceToMarkAsUnusedAllSegmentsIn) return; return ( { const resp = await axios.delete( - `/druid/coordinator/v1/datasources/${dropDataDatasource}`, + `/druid/coordinator/v1/datasources/${datasourceToMarkAsUnusedAllSegmentsIn}`, {}, ); return resp.data; }} - confirmButtonText="Drop data" - successText="Data drop request acknowledged, next time the coordinator runs data will be dropped" - failText="Could not drop data" + confirmButtonText="Mark as unused all segments" + successText="All segments in data source have been marked as unused" + failText="Failed to mark as unused all segments in data source" intent={Intent.DANGER} onClose={() => { - this.setState({ dropDataDatasource: undefined }); + this.setState({ datasourceToMarkAsUnusedAllSegmentsIn: undefined }); }} onSuccess={() => { this.datasourceQueryManager.rerunLastQuery(); }} >

- {`Are you sure you want to drop all the data for datasource '${dropDataDatasource}'?`} + {`Are you sure you want to mark as unused all segments in '${datasourceToMarkAsUnusedAllSegmentsIn}'?`}

); } - renderEnableAction() { - const { enableDatasource } = this.state; - if (!enableDatasource) return; + renderUseAction() { + const { datasourceToMarkAllNonOvershadowedSegmentsAsUsedIn } = this.state; + if (!datasourceToMarkAllNonOvershadowedSegmentsAsUsedIn) return; return ( { const resp = await axios.post( - `/druid/coordinator/v1/datasources/${enableDatasource}`, + `/druid/coordinator/v1/datasources/${datasourceToMarkAllNonOvershadowedSegmentsAsUsedIn}`, {}, ); return resp.data; }} - confirmButtonText="Enable datasource" - successText="Datasource has been enabled" - failText="Could not enable datasource" + confirmButtonText="Mark as used all segments" + successText="All non-overshadowed segments in data source have been marked as used" + failText="Failed to mark as used all non-overshadowed segments in data source" intent={Intent.PRIMARY} onClose={() => { - this.setState({ enableDatasource: undefined }); + this.setState({ datasourceToMarkAllNonOvershadowedSegmentsAsUsedIn: undefined }); }} onSuccess={() => { this.datasourceQueryManager.rerunLastQuery(); }} > -

{`Are you sure you want to enable datasource '${enableDatasource}'?`}

+

{`Are you sure you want to mark as used all non-overshadowed segments in '${datasourceToMarkAllNonOvershadowedSegmentsAsUsedIn}'?`}

); } - renderDropReloadAction() { - const { dropReloadDatasource, dropReloadAction, dropReloadInterval } = this.state; - if (!dropReloadDatasource) return; - const isDrop = dropReloadAction === 'drop'; - + renderUseUnuseActionByInterval() { + const { datasourceToMarkSegmentsByIntervalIn, useUnuseAction, useUnuseInterval } = this.state; + if (!datasourceToMarkSegmentsByIntervalIn) return; + const isUse = useUnuseAction === 'use'; + const usedWord = isUse ? 'used' : 'unused'; return ( { - if (!dropReloadInterval) return; + if (!useUnuseInterval) return; + const param = isUse ? 'markUsed' : 'markUnused'; const resp = await axios.post( - `/druid/coordinator/v1/datasources/${dropReloadDatasource}/${ - isDrop ? 'markUnused' : 'markUsed' - }`, + `/druid/coordinator/v1/datasources/${datasourceToMarkSegmentsByIntervalIn}/${param}`, { - interval: dropReloadInterval, + interval: useUnuseInterval, }, ); return resp.data; }} - confirmButtonText={`${isDrop ? 'Drop' : 'Reload'} selected data`} - confirmButtonDisabled={!/.\/./.test(dropReloadInterval)} - successText={`${isDrop ? 'Drop' : 'Reload'} request submitted`} - failText={`Could not ${isDrop ? 'drop' : 'reload'} data`} + confirmButtonText={`Mark as ${usedWord} segments in the interval`} + confirmButtonDisabled={!/.\/./.test(useUnuseInterval)} + successText={`Segments in the interval in data source have been marked as ${usedWord}`} + failText={`Failed to mark as ${usedWord} segments in the interval in data source`} intent={Intent.PRIMARY} onClose={() => { - this.setState({ dropReloadDatasource: undefined }); + this.setState({ datasourceToMarkSegmentsByIntervalIn: undefined }); }} onSuccess={() => { this.datasourceQueryManager.rerunLastQuery(); }} > -

{`Please select the interval that you want to ${isDrop ? 'drop' : 'reload'}?`}

+

{`Please select the interval in which you want to mark segments as ${usedWord} in '${datasourceToMarkSegmentsByIntervalIn}'?`}

{ const v = e.target.value; - this.setState({ dropReloadInterval: v.toUpperCase() }); + this.setState({ useUnuseInterval: v.toUpperCase() }); }} placeholder="2018-01-01T00:00:00/2018-01-03T00:00:00" /> @@ -465,9 +466,9 @@ GROUP BY 1`; ); return resp.data; }} - confirmButtonText="Permanently delete data" - successText="Kill task was issued. Datasource will be deleted" - failText="Could not submit kill task" + confirmButtonText="Permanently delete unused segments" + successText="Kill task was issued. Unused segments in data source will be deleted" + failText="Failed submit kill task" intent={Intent.DANGER} onClose={() => { this.setState({ killDatasource: undefined }); @@ -477,7 +478,7 @@ GROUP BY 1`; }} >

- {`Are you sure you want to permanently delete the deep storage data for datasource '${killDatasource}'?`} + {`Are you sure you want to permanently delete unused segments in '${killDatasource}'?`}

This action is not reversible and the data deleted will be lost.

@@ -578,16 +579,16 @@ GROUP BY 1`; }); }; - private toggleDisabled(showDisabled: boolean) { - if (!showDisabled) { + private toggleUnused(showUnused: boolean) { + if (!showUnused) { this.datasourceQueryManager.rerunLastQuery(); } - this.setState({ showDisabled: !showDisabled }); + this.setState({ showUnused: !showUnused }); } getDatasourceActions( datasource: string, - disabled: boolean, + unused: boolean, rules: any[], compactionConfig: Record, ): BasicAction[] { @@ -610,12 +611,16 @@ GROUP BY 1`; return goToActions; } - if (disabled) { + if (unused) { return [ { icon: IconNames.EXPORT, - title: 'Enable', - onAction: () => this.setState({ enableDatasource: datasource }), + title: 'Mark as used all segments', + + onAction: () => + this.setState({ + datasourceToMarkAllNonOvershadowedSegmentsAsUsedIn: datasource, + }), }, { icon: IconNames.TRASH, @@ -640,8 +645,11 @@ GROUP BY 1`; }, { icon: IconNames.REFRESH, - title: 'Enable (reapply retention rules)', - onAction: () => this.setState({ enableDatasource: datasource }), + title: 'Mark as used all segments (will lead to reapplying retention rules)', + onAction: () => + this.setState({ + datasourceToMarkAllNonOvershadowedSegmentsAsUsedIn: datasource, + }), }, { icon: IconNames.COMPRESSED, @@ -657,21 +665,29 @@ GROUP BY 1`; }, { icon: IconNames.EXPORT, - title: 'Reload data by interval', + title: 'Mark as used segments by interval', + onAction: () => - this.setState({ dropReloadDatasource: datasource, dropReloadAction: 'reload' }), + this.setState({ + datasourceToMarkSegmentsByIntervalIn: datasource, + useUnuseAction: 'use', + }), }, { icon: IconNames.IMPORT, - title: 'Drop data by interval', + title: 'Mark as unused segments by interval', + onAction: () => - this.setState({ dropReloadDatasource: datasource, dropReloadAction: 'drop' }), + this.setState({ + datasourceToMarkSegmentsByIntervalIn: datasource, + useUnuseAction: 'unuse', + }), }, { icon: IconNames.IMPORT, - title: 'Drop datasource (disable)', + title: 'Mark as unused all segments', intent: Intent.DANGER, - onAction: () => this.setState({ dropDataDatasource: datasource }), + onAction: () => this.setState({ datasourceToMarkAsUnusedAllSegmentsIn: datasource }), }, { icon: IconNames.TRASH, @@ -723,12 +739,12 @@ GROUP BY 1`; datasourcesLoading, datasourcesError, datasourceFilter, - showDisabled, + showUnused, hiddenColumns, } = this.state; let data = datasources || []; - if (!showDisabled) { - data = data.filter(d => !d.disabled); + if (!showUnused) { + data = data.filter(d => !d.unused); } return ( <> @@ -777,13 +793,13 @@ GROUP BY 1`; }; }, Cell: row => { - const { datasource, num_available_segments, num_segments, disabled } = row.original; + const { datasource, num_available_segments, num_segments, unused } = row.original; - if (disabled) { + if (unused) { return ( - ●  - Disabled + ●  + Unused ); } @@ -952,10 +968,10 @@ GROUP BY 1`; filterable: false, Cell: row => { const datasource = row.value; - const { disabled, rules, compaction } = row.original; + const { unused, rules, compaction } = row.original; const datasourceActions = this.getDatasourceActions( datasource, - disabled, + unused, rules, compaction, ); @@ -976,9 +992,9 @@ GROUP BY 1`; ]} defaultPageSize={50} /> - {this.renderDropDataAction()} - {this.renderEnableAction()} - {this.renderDropReloadAction()} + {this.renderUnuseAction()} + {this.renderUseAction()} + {this.renderUseUnuseActionByInterval()} {this.renderKillAction()} {this.renderRetentionDialog()} {this.renderCompactionDialog()} @@ -989,7 +1005,7 @@ GROUP BY 1`; render(): JSX.Element { const { capabilities } = this.props; const { - showDisabled, + showUnused, hiddenColumns, showChart, chartHeight, @@ -1017,9 +1033,9 @@ GROUP BY 1`; disabled={!capabilities.hasSqlOrCoordinatorAccess()} /> this.toggleDisabled(showDisabled)} + checked={showUnused} + label="Show unused" + onChange={() => this.toggleUnused(showUnused)} disabled={!capabilities.hasCoordinatorAccess()} />