Skip to content

Commit 4081cf8

Browse files
author
Xin Gao
committed
Resolve comments
1 parent 8f8863e commit 4081cf8

4 files changed

Lines changed: 41 additions & 28 deletions

File tree

pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/realtime/PinotLLCRealtimeSegmentManager.java

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -977,11 +977,16 @@ private void createNewSegmentZKMetadataWithOffsetAutoReset(TableConfig tableConf
977977
startOffset);
978978
}
979979

980-
private String computeStartOffset(
981-
String nextOffset, StreamConfig streamConfig, int partitionId) {
980+
private String computeStartOffset(String nextOffset, StreamConfig streamConfig, int partitionId) {
981+
if (!streamConfig.isEnableOffsetAutoReset()) {
982+
return nextOffset;
983+
}
982984
long timeThreshold = streamConfig.getOffsetAutoResetTimeSecThreshold();
983985
int offsetThreshold = streamConfig.getOffsetAutoResetOffsetThreshold();
984986
if (timeThreshold <= 0 && offsetThreshold <= 0) {
987+
LOGGER.warn("Invalid offset auto reset configuration for table: {}, topic: {}. "
988+
+ "timeThreshold: {}, offsetThreshold: {}",
989+
streamConfig.getTableNameWithType(), streamConfig.getTopicName(), timeThreshold, offsetThreshold);
985990
return nextOffset;
986991
}
987992
String clientId =
@@ -990,40 +995,38 @@ private String computeStartOffset(
990995
StreamConsumerFactory consumerFactory = StreamConsumerFactoryProvider.create(streamConfig);
991996
StreamPartitionMsgOffset offsetAtSLA;
992997
StreamPartitionMsgOffset latestOffset;
993-
try (StreamMetadataProvider metadataProvider = consumerFactory.createPartitionMetadataProvider(
994-
clientId, partitionId)) {
998+
try (StreamMetadataProvider metadataProvider = consumerFactory.createPartitionMetadataProvider(clientId,
999+
partitionId)) {
9951000
// Fetching timestamp from an offset is an expensive operation which requires reading the data,
9961001
// while fetching offset from timestamp is lightweight and only needs to read metadata.
9971002
// Hence, instead of checking if latestOffset's time - nextOffset's time < SLA, we would check
9981003
// (CurrentTime - SLA)'s offset > nextOffset.
9991004
// TODO: it is relying on System.currentTimeMillis() which might be affected by time drift. If we are able to
10001005
// get nextOffset's time, we should instead check (nextOffset's time + SLA)'s offset < latestOffset
10011006
latestOffset = metadataProvider.fetchStreamPartitionOffset(OffsetCriteria.LARGEST_OFFSET_CRITERIA, 5000);
1002-
LOGGER.info("Latest offset of topic {} and partition {} is {}",
1003-
streamConfig.getTopicName(), partitionId, latestOffset);
1004-
offsetAtSLA = metadataProvider.getOffsetAtTimestamp(
1005-
partitionId, System.currentTimeMillis() - timeThreshold * 1000);
1006-
LOGGER.info("Offset at SLA of topic {} and partition {} is {}",
1007-
streamConfig.getTopicName(), partitionId, offsetAtSLA);
1007+
LOGGER.info("Latest offset of topic {} and partition {} is {}", streamConfig.getTopicName(), partitionId,
1008+
latestOffset);
1009+
offsetAtSLA =
1010+
metadataProvider.getOffsetAtTimestamp(partitionId, System.currentTimeMillis() - timeThreshold * 1000);
1011+
LOGGER.info("Offset at SLA of topic {} and partition {} is {}", streamConfig.getTopicName(), partitionId,
1012+
offsetAtSLA);
10081013
} catch (Exception e) {
10091014
LOGGER.warn("Not able to fetch the offset metadata, skip auto resetting offsets", e);
10101015
return nextOffset;
10111016
}
10121017
try {
1013-
if (timeThreshold > 0 && offsetAtSLA != null
1014-
&& Long.valueOf(offsetAtSLA.toString()) > Long.valueOf(nextOffset)) {
1015-
LOGGER.info("Auto reset offset from {} to {} on partition {} because time threshold reached",
1016-
nextOffset, latestOffset, partitionId);
1018+
if (timeThreshold > 0 && offsetAtSLA != null && Long.valueOf(offsetAtSLA.toString()) > Long.valueOf(nextOffset)) {
1019+
LOGGER.info("Auto reset offset from {} to {} on partition {} because time threshold reached", nextOffset,
1020+
latestOffset, partitionId);
10171021
return latestOffset.toString();
10181022
}
1019-
if (offsetThreshold > 0
1020-
&& Long.valueOf(latestOffset.toString()) - Long.valueOf(nextOffset) > offsetThreshold) {
1023+
if (offsetThreshold > 0 && Long.valueOf(latestOffset.toString()) - Long.valueOf(nextOffset) > offsetThreshold) {
10211024
LOGGER.info("Auto reset offset from {} to {} on partition {} because number of offsets threshold reached",
10221025
nextOffset, latestOffset, partitionId);
10231026
return latestOffset.toString();
10241027
}
10251028
} catch (Exception e) {
1026-
LOGGER.warn("Not able to convert the offset to LONG type, skip auto resetting offsets", e);
1029+
LOGGER.warn("Not able to compare the offsets, skip auto resetting offsets", e);
10271030
}
10281031
return nextOffset;
10291032
}

pinot-controller/src/test/java/org/apache/pinot/controller/helix/core/realtime/PinotLLCRealtimeSegmentManagerTest.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -333,27 +333,25 @@ public void testCommitSegment() {
333333
}
334334

335335
@Test
336-
public void testCommitSegmentWithOffsetAutoReset() throws Exception {
336+
public void testCommitSegmentWithOffsetAutoReset()
337+
throws Exception {
337338
// Set up a new table with 2 replicas, 5 instances, 4 partition
338339
PinotHelixResourceManager mockHelixResourceManager = mock(PinotHelixResourceManager.class);
339340
FakePinotLLCRealtimeSegmentManager segmentManager =
340341
new FakePinotLLCRealtimeSegmentManager(mockHelixResourceManager);
341342
setUpNewTable(segmentManager, 2, 5, 4);
342343
Map<String, Map<String, String>> instanceStatesMap = segmentManager._idealState.getRecord().getMapFields();
343344
Map<String, String> streamConfigMap = IngestionConfigUtils.getStreamConfigMaps(segmentManager._tableConfig).get(0);
344-
streamConfigMap.put(
345-
StreamConfigProperties.OFFSET_AUTO_RESET_OFFSET_THRESHOLD_KEY, "100"
346-
);
345+
streamConfigMap.put(StreamConfigProperties.ENABLE_OFFSET_AUTO_RESET, String.valueOf(true));
346+
streamConfigMap.put(StreamConfigProperties.OFFSET_AUTO_RESET_OFFSET_THRESHOLD_KEY, "100");
347347
segmentManager.makeTableConfig(streamConfigMap);
348348

349349
StreamConsumerFactory mockConsumerFactory = mock(StreamConsumerFactory.class);
350350
StreamMetadataProvider mockMetadataProvider = mock(StreamMetadataProvider.class);
351-
when(mockConsumerFactory.createPartitionMetadataProvider(anyString(), anyInt()))
352-
.thenReturn(mockMetadataProvider);
353-
when(mockMetadataProvider.fetchStreamPartitionOffset(eq(OffsetCriteria.LARGEST_OFFSET_CRITERIA), anyLong()))
354-
.thenReturn(new LongMsgOffset(LATEST_OFFSET));
355-
when(mockMetadataProvider.getOffsetAtTimestamp(eq(0), anyLong()))
356-
.thenReturn(PARTITION_OFFSET);
351+
when(mockConsumerFactory.createPartitionMetadataProvider(anyString(), anyInt())).thenReturn(mockMetadataProvider);
352+
when(mockMetadataProvider.fetchStreamPartitionOffset(eq(OffsetCriteria.LARGEST_OFFSET_CRITERIA),
353+
anyLong())).thenReturn(new LongMsgOffset(LATEST_OFFSET));
354+
when(mockMetadataProvider.getOffsetAtTimestamp(eq(0), anyLong())).thenReturn(PARTITION_OFFSET);
357355

358356
try (MockedStatic<StreamConsumerFactoryProvider> mockedStaticProvider = mockStatic(
359357
StreamConsumerFactoryProvider.class)) {

pinot-spi/src/main/java/org/apache/pinot/spi/stream/StreamConfig.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public class StreamConfig {
7575

7676
private final double _topicConsumptionRateLimit;
7777

78+
private final boolean _enableOffsetAutoReset;
7879
private final int _offsetAutoResetOffsetThreshold;
7980
private final long _offsetAutoResetTimeSecThreshold;
8081

@@ -202,6 +203,7 @@ public StreamConfig(String tableNameWithType, Map<String, String> streamConfigMa
202203
String rate = streamConfigMap.get(StreamConfigProperties.TOPIC_CONSUMPTION_RATE_LIMIT);
203204
_topicConsumptionRateLimit = rate != null ? Double.parseDouble(rate) : CONSUMPTION_RATE_LIMIT_NOT_SPECIFIED;
204205

206+
_enableOffsetAutoReset = Boolean.parseBoolean(streamConfigMap.get(StreamConfigProperties.ENABLE_OFFSET_AUTO_RESET));
205207
String offsetThreshold = streamConfigMap.get(StreamConfigProperties.OFFSET_AUTO_RESET_OFFSET_THRESHOLD_KEY);
206208
_offsetAutoResetOffsetThreshold = offsetThreshold != null ? Integer.valueOf(offsetThreshold) : -1;
207209
String timeSecThreshold = streamConfigMap.get(StreamConfigProperties.OFFSET_AUTO_RESET_TIMESEC_THRESHOLD_KEY);
@@ -391,6 +393,10 @@ public Optional<Double> getTopicConsumptionRateLimit() {
391393
: Optional.of(_topicConsumptionRateLimit);
392394
}
393395

396+
public boolean isEnableOffsetAutoReset() {
397+
return _enableOffsetAutoReset;
398+
}
399+
394400
public int getOffsetAutoResetOffsetThreshold() {
395401
return _offsetAutoResetOffsetThreshold;
396402
}
@@ -447,6 +453,7 @@ public boolean equals(Object o) {
447453
that._decoderClass) && Objects.equals(_decoderProperties, that._decoderProperties) && Objects.equals(_groupId,
448454
that._groupId) && Objects.equals(_streamConfigMap, that._streamConfigMap) && Objects.equals(_offsetCriteria,
449455
that._offsetCriteria) && Objects.equals(_flushThresholdVarianceFraction, that._flushThresholdVarianceFraction)
456+
&& _enableOffsetAutoReset == that._enableOffsetAutoReset
450457
&& _offsetAutoResetOffsetThreshold == that._offsetAutoResetOffsetThreshold
451458
&& _offsetAutoResetTimeSecThreshold == that._offsetAutoResetTimeSecThreshold;
452459
}
@@ -458,6 +465,6 @@ public int hashCode() {
458465
_flushThresholdSegmentRows, _flushThresholdTimeMillis, _flushThresholdSegmentSizeBytes,
459466
_flushAutotuneInitialRows, _groupId, _topicConsumptionRateLimit, _streamConfigMap, _offsetCriteria,
460467
_serverUploadToDeepStore, _flushThresholdVarianceFraction, _offsetAutoResetOffsetThreshold,
461-
_offsetAutoResetTimeSecThreshold);
468+
_enableOffsetAutoReset, _offsetAutoResetTimeSecThreshold);
462469
}
463470
}

pinot-spi/src/main/java/org/apache/pinot/spi/stream/StreamConfigProperties.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,11 @@ private StreamConfigProperties() {
143143
public static final String PAUSELESS_SEGMENT_DOWNLOAD_TIMEOUT_SECONDS =
144144
"realtime.segment.pauseless.download.timeoutSeconds";
145145

146+
/**
147+
* Config used to enable offset auto reset during segment commit.
148+
*/
149+
public static final String ENABLE_OFFSET_AUTO_RESET = "realtime.segment.offsetAutoReset.enable";
150+
146151
/**
147152
* During segment commit, the new segment startOffset would skip to the latest offset if thisValue is set as positive
148153
* and (latestStreamOffset - latestIngestedOffset > thisValue)

0 commit comments

Comments
 (0)