This is an automated email from the ASF dual-hosted git repository. xiangfu pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push: new 19fde79121 Metrics for monitoring PROPERTYSTORE/SEGMENTS/<table>'s getChildren response size (#15345) 19fde79121 is described below commit 19fde7912113508def6515b9678fd7e7b10246b5 Author: Songqiao Su <andysongq...@gmail.com> AuthorDate: Wed Mar 26 16:51:55 2025 -0700 Metrics for monitoring PROPERTYSTORE/SEGMENTS/<table>'s getChildren response size (#15345) * track bytes * format * check null * remove .sdkmanrc --- .../pinot/common/metrics/ControllerGauge.java | 2 ++ .../controller/helix/SegmentStatusChecker.java | 17 +++++++++++++++ .../ControllerPeriodicTasksIntegrationTest.java | 24 ++++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/pinot-common/src/main/java/org/apache/pinot/common/metrics/ControllerGauge.java b/pinot-common/src/main/java/org/apache/pinot/common/metrics/ControllerGauge.java index 9ea6008b3f..cd6215228c 100644 --- a/pinot-common/src/main/java/org/apache/pinot/common/metrics/ControllerGauge.java +++ b/pinot-common/src/main/java/org/apache/pinot/common/metrics/ControllerGauge.java @@ -54,6 +54,8 @@ public enum ControllerGauge implements AbstractMetrics.Gauge { // be queried from the table. SEGMENT_COUNT_INCLUDING_REPLACED("SegmentCount", false), + // Track response size of getChildren from /PROPERTYSTORE/SEGMENTS/<table> + PROPERTYSTORE_SEGMENT_CHILDREN_BYTE_SIZE("propertystore", false), IDEALSTATE_ZNODE_SIZE("idealstate", false), IDEALSTATE_ZNODE_BYTE_SIZE("idealstate", false), EXTERNALVIEW_ZNODE_SIZE("externalview", false), diff --git a/pinot-controller/src/main/java/org/apache/pinot/controller/helix/SegmentStatusChecker.java b/pinot-controller/src/main/java/org/apache/pinot/controller/helix/SegmentStatusChecker.java index 1cf773871d..bc3f2fb263 100644 --- a/pinot-controller/src/main/java/org/apache/pinot/controller/helix/SegmentStatusChecker.java +++ b/pinot-controller/src/main/java/org/apache/pinot/controller/helix/SegmentStatusChecker.java @@ -27,6 +27,7 @@ import java.util.Properties; import java.util.Set; import java.util.concurrent.TimeUnit; import org.apache.commons.lang3.tuple.Pair; +import org.apache.helix.AccessOption; import org.apache.helix.model.ExternalView; import org.apache.helix.model.IdealState; import org.apache.helix.store.zk.ZkHelixPropertyStore; @@ -36,6 +37,7 @@ import org.apache.pinot.common.exception.InvalidConfigException; import org.apache.pinot.common.lineage.SegmentLineage; import org.apache.pinot.common.lineage.SegmentLineageAccessHelper; import org.apache.pinot.common.lineage.SegmentLineageUtils; +import org.apache.pinot.common.metadata.ZKMetadataProvider; import org.apache.pinot.common.metadata.segment.SegmentZKMetadata; import org.apache.pinot.common.metrics.ControllerGauge; import org.apache.pinot.common.metrics.ControllerMeter; @@ -244,6 +246,21 @@ public class SegmentStatusChecker extends ControllerPeriodicTask<SegmentStatusCh // Get the segments excluding the replaced segments which are specified in the segment lineage entries and cannot // be queried from the table. ZkHelixPropertyStore<ZNRecord> propertyStore = _pinotHelixResourceManager.getPropertyStore(); + + if (propertyStore != null) { + String segmentsPath = ZKMetadataProvider.constructPropertyStorePathForResource(tableNameWithType); + List<String> segmentNames = propertyStore.getChildNames(segmentsPath, AccessOption.PERSISTENT); + long segmentNamesBytesSize = 0; + if (segmentNames != null) { + for (String segmentName : segmentNames) { + segmentNamesBytesSize += segmentName.getBytes().length; + } + } + _controllerMetrics.setValueOfTableGauge(tableNameWithType, + ControllerGauge.PROPERTYSTORE_SEGMENT_CHILDREN_BYTE_SIZE, + segmentNamesBytesSize); + } + Set<String> segments; if (segmentsIncludingReplaced.isEmpty()) { segments = Set.of(); diff --git a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/ControllerPeriodicTasksIntegrationTest.java b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/ControllerPeriodicTasksIntegrationTest.java index 2a34c5cc22..e103357d13 100644 --- a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/ControllerPeriodicTasksIntegrationTest.java +++ b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/ControllerPeriodicTasksIntegrationTest.java @@ -29,10 +29,14 @@ import java.util.Map; import java.util.Set; import javax.annotation.Nullable; import org.apache.commons.io.FileUtils; +import org.apache.helix.AccessOption; import org.apache.helix.model.ExternalView; import org.apache.helix.model.IdealState; import org.apache.helix.model.InstanceConfig; +import org.apache.helix.store.zk.ZkHelixPropertyStore; +import org.apache.helix.zookeeper.datamodel.ZNRecord; import org.apache.helix.zookeeper.datamodel.serializer.ZNRecordSerializer; +import org.apache.pinot.common.metadata.ZKMetadataProvider; import org.apache.pinot.common.metrics.ControllerGauge; import org.apache.pinot.common.metrics.ControllerMetrics; import org.apache.pinot.common.metrics.MetricValueUtils; @@ -244,6 +248,7 @@ public class ControllerPeriodicTasksIntegrationTest extends BaseClusterIntegrati 0, 0)) { return false; } + String tableNameWithType = TableNameBuilder.OFFLINE.tableNameWithType(getTableName()); IdealState idealState = _helixResourceManager.getTableIdealState(tableNameWithType); ExternalView externalView = _helixResourceManager.getTableExternalView(tableNameWithType); @@ -319,7 +324,25 @@ public class ControllerPeriodicTasksIntegrationTest extends BaseClusterIntegrati idealState.getPartitionSet().size())) { return false; } + + ZkHelixPropertyStore<ZNRecord> propertyStore = _helixResourceManager.getPropertyStore(); + String segmentsPath = ZKMetadataProvider.constructPropertyStorePathForResource(tableNameWithType); + List<String> segmentNames = propertyStore.getChildNames(segmentsPath, AccessOption.PERSISTENT); + long expectedBytesSize = 0; + if (segmentNames != null) { + for (String segmentName : segmentNames) { + expectedBytesSize += segmentName.getBytes().length; + } + } + + // Check if the metric matches the calculated byte size + long bytesSize = MetricValueUtils.getTableGaugeValue(ControllerMetrics.get(), tableNameWithType, + ControllerGauge.PROPERTYSTORE_SEGMENT_CHILDREN_BYTE_SIZE); + if (bytesSize != expectedBytesSize) { + return false; + } } + if (externalView != null) { if (!checkTableGaugeValue(ControllerGauge.EXTERNALVIEW_ZNODE_SIZE, tableNameWithType, externalView.toString().length())) { @@ -330,6 +353,7 @@ public class ControllerPeriodicTasksIntegrationTest extends BaseClusterIntegrati return false; } } + return checkTableGaugeValue(ControllerGauge.NUMBER_OF_REPLICAS, tableNameWithType, expectedNumReplicas) && checkTableGaugeValue(ControllerGauge.PERCENT_OF_REPLICAS, tableNameWithType, expectedPercentReplicas) && checkTableGaugeValue(ControllerGauge.SEGMENTS_IN_ERROR_STATE, tableNameWithType, --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org For additional commands, e-mail: commits-h...@pinot.apache.org