Do not allocate week granular segments unless requested (#15589)

* Do not allocate week granular segments unless explicitly requested
This commit is contained in:
AmatyaAvadhanula 2024-01-05 12:14:52 +05:30 committed by GitHub
parent d8830b64fc
commit c41e99e10c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 102 additions and 10 deletions

View File

@ -20,7 +20,7 @@
], ],
"granularitySpec" : { "granularitySpec" : {
"type" : "uniform", "type" : "uniform",
"segmentGranularity" : "week", "segmentGranularity" : "day",
"queryGranularity" : "minute", "queryGranularity" : "minute",
"intervals" : ["2018-01-01/2018-01-03"], "intervals" : ["2018-01-01/2018-01-03"],
"rollup" : true "rollup" : true

View File

@ -20,7 +20,7 @@
], ],
"granularitySpec" : { "granularitySpec" : {
"type" : "uniform", "type" : "uniform",
"segmentGranularity" : "week", "segmentGranularity" : "day",
"queryGranularity" : "minute", "queryGranularity" : "minute",
"intervals" : ["2018-01-01/2018-01-03"], "intervals" : ["2018-01-01/2018-01-03"],
"rollup" : true "rollup" : true

View File

@ -18,7 +18,7 @@
], ],
"granularitySpec": { "granularitySpec": {
"type": "uniform", "type": "uniform",
"segmentGranularity": "week", "segmentGranularity": "day",
"queryGranularity": "minute", "queryGranularity": "minute",
"intervals": ["2018-01-01/2018-01-03"], "intervals": ["2018-01-01/2018-01-03"],
"rollup": true "rollup": true

View File

@ -18,7 +18,7 @@
], ],
"granularitySpec" : { "granularitySpec" : {
"type" : "uniform", "type" : "uniform",
"segmentGranularity" : "week", "segmentGranularity" : "day",
"queryGranularity" : "minute", "queryGranularity" : "minute",
"intervals" : ["2018-01-01/2018-01-03"], "intervals" : ["2018-01-01/2018-01-03"],
"rollup" : true "rollup" : true

View File

@ -18,7 +18,7 @@
], ],
"granularitySpec" : { "granularitySpec" : {
"type" : "uniform", "type" : "uniform",
"segmentGranularity" : "week", "segmentGranularity" : "day",
"queryGranularity" : "minute", "queryGranularity" : "minute",
"intervals" : ["2018-01-01/2018-01-03"], "intervals" : ["2018-01-01/2018-01-03"],
"rollup" : true "rollup" : true

View File

@ -18,7 +18,7 @@
], ],
"granularitySpec" : { "granularitySpec" : {
"type" : "uniform", "type" : "uniform",
"segmentGranularity" : "week", "segmentGranularity" : "day",
"queryGranularity" : "minute", "queryGranularity" : "minute",
"intervals" : ["2018-01-01/2018-01-03"], "intervals" : ["2018-01-01/2018-01-03"],
"rollup" : true "rollup" : true

View File

@ -52,9 +52,13 @@ import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* Allocates a pending segment for a given timestamp. The preferredSegmentGranularity is used if there are no prior * Allocates a pending segment for a given timestamp.
* segments for the given timestamp, or if the prior segments for the given timestamp are already at the * If a visible chunk of used segments contains the interval with the query granularity containing the timestamp,
* preferredSegmentGranularity. Otherwise, the prior segments will take precedence. * the pending segment is allocated with its interval.
* Else, if the interval with the preferred segment granularity containing the timestamp has no overlap
* with the existing used segments, the preferred segment granularity is used.
* Else, find the coarsest segment granularity, containing the interval with the query granularity for the timestamp,
* that does not overlap with the existing used segments. This granularity is used for allocation if it exists.
* <p/> * <p/>
* This action implicitly acquires some task locks when it allocates segments. You do not have to acquire them * This action implicitly acquires some task locks when it allocates segments. You do not have to acquire them
* beforehand, although you *do* have to release them yourself. (Note that task locks are automatically released when * beforehand, although you *do* have to release them yourself. (Note that task locks are automatically released when
@ -62,6 +66,8 @@ import java.util.stream.Collectors;
* <p/> * <p/>
* If this action cannot acquire an appropriate task lock, or if it cannot expand an existing segment set, it returns * If this action cannot acquire an appropriate task lock, or if it cannot expand an existing segment set, it returns
* null. * null.
* </p>
* Do NOT allocate WEEK granularity segments unless the preferred segment granularity is WEEK.
*/ */
public class SegmentAllocateAction implements TaskAction<SegmentIdWithShardSpec> public class SegmentAllocateAction implements TaskAction<SegmentIdWithShardSpec>
{ {

View File

@ -59,6 +59,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.Parameterized; import org.junit.runners.Parameterized;
import java.io.IOException; import java.io.IOException;
import java.time.Duration;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -995,6 +996,66 @@ public class SegmentAllocateActionTest
Assert.assertEquals(Intervals.ETERNITY, id2.getInterval()); Assert.assertEquals(Intervals.ETERNITY, id2.getInterval());
} }
@Test
public void testAllocateWeekOnlyWhenWeekIsPreferred()
{
final Task task = NoopTask.create();
taskActionTestKit.getTaskLockbox().add(task);
final SegmentIdWithShardSpec id1 = allocate(
task,
DateTimes.of("2023-12-16"),
Granularities.MINUTE,
Granularities.HOUR,
"s1",
null
);
final SegmentIdWithShardSpec id2 = allocate(
task,
DateTimes.of("2023-12-18"),
Granularities.MINUTE,
Granularities.WEEK,
"s2",
null
);
Assert.assertNotNull(id1);
Assert.assertNotNull(id2);
Assert.assertEquals(Duration.ofHours(1).toMillis(), id1.getInterval().toDurationMillis());
Assert.assertEquals(Duration.ofDays(7).toMillis(), id2.getInterval().toDurationMillis());
}
@Test
public void testAllocateDayWhenMonthNotPossible()
{
final Task task = NoopTask.create();
taskActionTestKit.getTaskLockbox().add(task);
final SegmentIdWithShardSpec id1 = allocate(
task,
DateTimes.of("2023-12-16"),
Granularities.MINUTE,
Granularities.HOUR,
"s1",
null
);
final SegmentIdWithShardSpec id2 = allocate(
task,
DateTimes.of("2023-12-18"),
Granularities.MINUTE,
Granularities.MONTH,
"s2",
null
);
Assert.assertNotNull(id1);
Assert.assertNotNull(id2);
Assert.assertEquals(Duration.ofHours(1).toMillis(), id1.getInterval().toDurationMillis());
Assert.assertEquals(Duration.ofDays(1).toMillis(), id2.getInterval().toDurationMillis());
}
private SegmentIdWithShardSpec allocate( private SegmentIdWithShardSpec allocate(
final Task task, final Task task,
final DateTime timestamp, final DateTime timestamp,

View File

@ -106,6 +106,8 @@ public abstract class Granularity implements Cacheable
* ALL will not be returned unless the provided granularity is ALL. NONE will never be returned, even if the * ALL will not be returned unless the provided granularity is ALL. NONE will never be returned, even if the
* provided granularity is NONE. This is because the main usage of this function in production is segment * provided granularity is NONE. This is because the main usage of this function in production is segment
* allocation, and we do not wish to generate NONE-granular segments. * allocation, and we do not wish to generate NONE-granular segments.
*
* The list of granularities returned contains WEEK only if the requested granularity is WEEK.
*/ */
public static List<Granularity> granularitiesFinerThan(final Granularity gran0) public static List<Granularity> granularitiesFinerThan(final Granularity gran0)
{ {
@ -117,6 +119,9 @@ public abstract class Granularity implements Cacheable
if ((gran == GranularityType.ALL && !gran0.equals(Granularities.ALL)) || gran == GranularityType.NONE) { if ((gran == GranularityType.ALL && !gran0.equals(Granularities.ALL)) || gran == GranularityType.NONE) {
continue; continue;
} }
if (gran == GranularityType.WEEK && !gran0.equals(Granularities.WEEK)) {
continue;
}
final Granularity segmentGranularity = gran.create(origin, tz); final Granularity segmentGranularity = gran.create(origin, tz);
final long segmentGranularityDurationMillis = segmentGranularity.bucket(DateTimes.EPOCH).toDurationMillis(); final long segmentGranularityDurationMillis = segmentGranularity.bucket(DateTimes.EPOCH).toDurationMillis();
final long gran0DurationMillis = gran0.bucket(DateTimes.EPOCH).toDurationMillis(); final long gran0DurationMillis = gran0.bucket(DateTimes.EPOCH).toDurationMillis();

View File

@ -1002,6 +1002,27 @@ public class GranularityTest
); );
} }
@Test
public void testGranularitiesFinerThanWeek()
{
Assert.assertEquals(
ImmutableList.of(
Granularities.WEEK,
Granularities.DAY,
Granularities.EIGHT_HOUR,
Granularities.SIX_HOUR,
Granularities.HOUR,
Granularities.THIRTY_MINUTE,
Granularities.FIFTEEN_MINUTE,
Granularities.TEN_MINUTE,
Granularities.FIVE_MINUTE,
Granularities.MINUTE,
Granularities.SECOND
),
Granularity.granularitiesFinerThan(Granularities.WEEK)
);
}
@Test @Test
public void testGranularitiesFinerThanAll() public void testGranularitiesFinerThanAll()
{ {
@ -1011,7 +1032,6 @@ public class GranularityTest
Granularities.YEAR, Granularities.YEAR,
Granularities.QUARTER, Granularities.QUARTER,
Granularities.MONTH, Granularities.MONTH,
Granularities.WEEK,
Granularities.DAY, Granularities.DAY,
Granularities.EIGHT_HOUR, Granularities.EIGHT_HOUR,
Granularities.SIX_HOUR, Granularities.SIX_HOUR,