Improve ZkClientMonitor and ZkClientPathMonitor performance (#2021)
Previously, regex matches were used, which was inefficient. This commit does this following:
Replace String#matches with more efficient String#contains in ZkClientPathMonitor
Refactor record* methods in ZkClientMonitor to avoid repetition and simplify matching logic
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/metric/ZkClientMonitor.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/metric/ZkClientMonitor.java
index 1f71e42..d0a37bb 100644
--- a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/metric/ZkClientMonitor.java
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/metric/ZkClientMonitor.java
@@ -20,12 +20,12 @@
*/
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Consumer;
import javax.management.JMException;
import javax.management.MBeanAttributeInfo;
import javax.management.MalformedObjectNameException;
@@ -81,11 +81,11 @@
_monitorInstanceName = monitorInstanceName;
_monitorRootOnly = monitorRootOnly;
- _stateChangeEventCounter = new SimpleDynamicMetric("StateChangeEventCounter", 0l);
- _expiredSessionCounter = new SimpleDynamicMetric("ExpiredSessionCounter", 0l);
- _dataChangeEventCounter = new SimpleDynamicMetric("DataChangeEventCounter", 0l);
- _outstandingRequestGauge = new SimpleDynamicMetric("OutstandingRequestGauge", 0l);
- _znodeCompressCounter = new SimpleDynamicMetric("CompressedZnodeWriteCounter", 0l);
+ _stateChangeEventCounter = new SimpleDynamicMetric<>("StateChangeEventCounter", 0L);
+ _expiredSessionCounter = new SimpleDynamicMetric<>("ExpiredSessionCounter", 0L);
+ _dataChangeEventCounter = new SimpleDynamicMetric<>("DataChangeEventCounter", 0L);
+ _outstandingRequestGauge = new SimpleDynamicMetric<>("OutstandingRequestGauge", 0L);
+ _znodeCompressCounter = new SimpleDynamicMetric<>("CompressedZnodeWriteCounter", 0L);
if (zkEventThread != null) {
boolean result = setAndInitZkEventThreadMonitor(zkEventThread);
@@ -198,32 +198,12 @@
}
public void recordDataPropagationLatency(String path, long latencyMilliSec) {
- if (null == path) {
- return;
- }
- Arrays.stream(ZkClientPathMonitor.PredefinedPath.values())
- .filter(predefinedPath -> predefinedPath.match(path))
- .forEach(predefinedPath -> {
- ZkClientPathMonitor zkClientPathMonitor = _zkClientPathMonitorMap.get(predefinedPath);
- if (zkClientPathMonitor != null) {
- zkClientPathMonitor.recordDataPropagationLatency(latencyMilliSec);
- }
- });
+ findZkClientPathMonitor(path, (m) -> m.recordDataPropagationLatency(latencyMilliSec));
}
private void record(String path, int bytes, long latencyMilliSec, boolean isFailure,
boolean isRead) {
- if (null == path) {
- return;
- }
- Arrays.stream(ZkClientPathMonitor.PredefinedPath.values())
- .filter(predefinedPath -> predefinedPath.match(path))
- .forEach(predefinedPath -> {
- ZkClientPathMonitor zkClientPathMonitor = _zkClientPathMonitorMap.get(predefinedPath);
- if (zkClientPathMonitor != null) {
- zkClientPathMonitor.record(bytes, latencyMilliSec, isFailure, isRead);
- }
- });
+ findZkClientPathMonitor(path, (m) -> m.record(bytes, latencyMilliSec, isFailure, isRead));
}
public void record(String path, int dataSize, long startTimeMilliSec, AccessType accessType) {
@@ -257,17 +237,7 @@
*/
private void recordAsync(String path, int bytes, long latencyMilliSec, boolean isFailure,
AccessType accessType) {
- if (null == path) {
- return;
- }
- Arrays.stream(ZkClientPathMonitor.PredefinedPath.values())
- .filter(predefinedPath -> predefinedPath.match(path))
- .forEach(predefinedPath -> {
- ZkClientPathMonitor zkClientPathMonitor = _zkClientPathMonitorMap.get(predefinedPath);
- if (zkClientPathMonitor != null) {
- zkClientPathMonitor.recordAsync(bytes, latencyMilliSec, isFailure, accessType);
- }
- });
+ findZkClientPathMonitor(path, (m) -> m.recordAsync(bytes, latencyMilliSec, isFailure, accessType));
}
public void recordAsync(String path, int dataSize, long startTimeMilliSec, AccessType accessType) {
@@ -278,6 +248,17 @@
recordAsync(path, 0, 0, true, accessType);
}
+ private void findZkClientPathMonitor(String path, Consumer<ZkClientPathMonitor> onMatch) {
+ if (path == null) {
+ return;
+ }
+ _zkClientPathMonitorMap.forEach((predefinedPath, zkClientPathMonitor) -> {
+ if (predefinedPath.match(path)) {
+ onMatch.accept(zkClientPathMonitor);
+ }
+ });
+ }
+
class ZkThreadMetric extends DynamicMetric<ZkEventThread, ZkEventThread> {
public ZkThreadMetric(ZkEventThread eventThread) {
super("ZkEventThead", eventThread);
diff --git a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/metric/ZkClientPathMonitor.java b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/metric/ZkClientPathMonitor.java
index 59643f1..18ae26f 100644
--- a/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/metric/ZkClientPathMonitor.java
+++ b/zookeeper-api/src/main/java/org/apache/helix/zookeeper/zkclient/metric/ZkClientPathMonitor.java
@@ -42,16 +42,16 @@
private final PredefinedPath _path;
public enum PredefinedPath {
- IdealStates(".*/IDEALSTATES/.*"),
- Instances(".*/INSTANCES/.*"),
- Configs(".*/CONFIGS/.*"),
- Controller(".*/CONTROLLER/.*"),
- ExternalView(".*/EXTERNALVIEW/.*"),
- LiveInstances(".*/LIVEINSTANCES/.*"),
- PropertyStore(".*/PROPERTYSTORE/.*"),
- CurrentStates(".*/CURRENTSTATES/.*"),
- Messages(".*/MESSAGES/.*"),
- Root(".*");
+ IdealStates("/IDEALSTATES/"),
+ Instances("/INSTANCES/"),
+ Configs("/CONFIGS/"),
+ Controller("/CONTROLLER/"),
+ ExternalView("/EXTERNALVIEW/"),
+ LiveInstances("/LIVEINSTANCES/"),
+ PropertyStore("/PROPERTYSTORE/"),
+ CurrentStates("/CURRENTSTATES/"),
+ Messages("/MESSAGES/"),
+ Root("");
private final String _matchString;
@@ -60,7 +60,7 @@
}
public boolean match(String path) {
- return path.matches(this._matchString);
+ return path.contains(this._matchString);
}
}
@@ -135,27 +135,27 @@
path.name());
_writeTotalLatencyCounter =
- new SimpleDynamicMetric(PredefinedMetricDomains.WriteTotalLatencyCounter.name(), 0l);
+ new SimpleDynamicMetric<>(PredefinedMetricDomains.WriteTotalLatencyCounter.name(), 0L);
_readTotalLatencyCounter =
- new SimpleDynamicMetric(PredefinedMetricDomains.ReadTotalLatencyCounter.name(), 0l);
+ new SimpleDynamicMetric<>(PredefinedMetricDomains.ReadTotalLatencyCounter.name(), 0L);
_writeFailureCounter =
- new SimpleDynamicMetric(PredefinedMetricDomains.WriteFailureCounter.name(), 0l);
+ new SimpleDynamicMetric<>(PredefinedMetricDomains.WriteFailureCounter.name(), 0L);
_readFailureCounter =
- new SimpleDynamicMetric(PredefinedMetricDomains.ReadFailureCounter.name(), 0l);
+ new SimpleDynamicMetric<>(PredefinedMetricDomains.ReadFailureCounter.name(), 0L);
_writeAsyncFailureCounter =
- new SimpleDynamicMetric(PredefinedMetricDomains.WriteAsyncFailureCounter.name(), 0l);
+ new SimpleDynamicMetric<>(PredefinedMetricDomains.WriteAsyncFailureCounter.name(), 0L);
_readAsyncFailureCounter =
- new SimpleDynamicMetric(PredefinedMetricDomains.ReadAsyncFailureCounter.name(), 0l);
+ new SimpleDynamicMetric<>(PredefinedMetricDomains.ReadAsyncFailureCounter.name(), 0L);
_writeBytesCounter =
- new SimpleDynamicMetric(PredefinedMetricDomains.WriteBytesCounter.name(), 0l);
+ new SimpleDynamicMetric<>(PredefinedMetricDomains.WriteBytesCounter.name(), 0L);
_readBytesCounter =
- new SimpleDynamicMetric(PredefinedMetricDomains.ReadBytesCounter.name(), 0l);
- _writeCounter = new SimpleDynamicMetric(PredefinedMetricDomains.WriteCounter.name(), 0l);
- _readCounter = new SimpleDynamicMetric(PredefinedMetricDomains.ReadCounter.name(), 0l);
+ new SimpleDynamicMetric<>(PredefinedMetricDomains.ReadBytesCounter.name(), 0L);
+ _writeCounter = new SimpleDynamicMetric<>(PredefinedMetricDomains.WriteCounter.name(), 0L);
+ _readCounter = new SimpleDynamicMetric<>(PredefinedMetricDomains.ReadCounter.name(), 0L);
_writeAsyncCounter =
- new SimpleDynamicMetric(PredefinedMetricDomains.WriteAsyncCounter.name(), 0l);
+ new SimpleDynamicMetric<>(PredefinedMetricDomains.WriteAsyncCounter.name(), 0L);
_readAsyncCounter =
- new SimpleDynamicMetric(PredefinedMetricDomains.ReadAsyncCounter.name(), 0l);
+ new SimpleDynamicMetric<>(PredefinedMetricDomains.ReadAsyncCounter.name(), 0L);
_readLatencyGauge = new HistogramDynamicMetric(PredefinedMetricDomains.ReadLatencyGauge.name(),
new Histogram(