Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Huge Number of Watches in ZooKeeper #17482

Open
wants to merge 49 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
50c1f7a
* Fix huge number of watches in zk
asdf2014 Jan 12, 2020
8420d73
Patch comments
asdf2014 Jan 19, 2020
da8538b
Add license
asdf2014 Jan 19, 2020
67b5064
Patch comments
asdf2014 Jan 23, 2020
23cd4d8
Merge branch 'master' into tmp
asdf2014 Mar 28, 2020
ce64445
Merge reduce ZK
GWphua Nov 11, 2024
da2f212
Update to use CloseableUtils instead of CloseQuietly.
GWphua Nov 11, 2024
a5d0669
Add Javadocs for Announceable class
GWphua Nov 11, 2024
f3b21a4
Javadocs on Announcers
GWphua Nov 11, 2024
1053042
Refactor announce method
GWphua Nov 12, 2024
903db88
Refactor NodeAnnouncer
GWphua Nov 12, 2024
954fa53
Add Unit Tests
GWphua Nov 12, 2024
25de238
Remove humor from logs
GWphua Nov 13, 2024
a7733e3
Add unit test for NodeAnnouncer announcing same path different payload.
GWphua Nov 13, 2024
31f1d3d
Merge branch 'apache:master' into zk-fix
GWphua Nov 15, 2024
f541b84
Tweak import and change Javadocs
GWphua Nov 15, 2024
20cfb0f
Update Druid unannouncement logging to make sense
GWphua Nov 18, 2024
2a1f803
Replace deprecated inTransaction() with transaction()
GWphua Nov 18, 2024
a857bfc
Refactor buildParentPath
GWphua Nov 19, 2024
1cbfa99
Merge branch 'github' into zk-fix
GWphua Nov 21, 2024
e50e2aa
Merge branch 'github' into zk-fix
GWphua Nov 29, 2024
582691e
Add executorService for NodeCache
GWphua Nov 29, 2024
a305748
Try replace all Announcer
GWphua Nov 29, 2024
438bfd9
Add JavaDocs
GWphua Dec 2, 2024
c6bfbd6
Refactor Test classes
GWphua Dec 2, 2024
1aea321
Add JavaDocs and logging messages
GWphua Dec 2, 2024
6e262f8
Fix Checkstyle
GWphua Dec 2, 2024
b412415
Add debug logs for update
GWphua Dec 2, 2024
6c9bb94
Replace CloseableExecutorService within NodeCaches with ExecutorService
GWphua Dec 3, 2024
c8636d2
Debug logs for NodeAnnouncer starting and stopping
GWphua Dec 3, 2024
f12e09d
Add debug logs for Announcer.java
GWphua Dec 3, 2024
8d3cd1c
Merge branch 'github' into zk-fix
GWphua Dec 4, 2024
eb350fb
Merge branch 'github' into zk-fix
GWphua Dec 20, 2024
cf7c45e
Merge remote-tracking branch 'origin/master' into zk-fix
GWphua Feb 27, 2025
64bce5c
Remove ZKPathsUtils
GWphua Feb 27, 2025
431f7b5
Remove usage of ZKPathUtils in NodeAnnouncer.java
GWphua Feb 27, 2025
c58d8a5
Remove ZKPathUtils usage in test classes
GWphua Feb 27, 2025
1a5f663
Migrate unit tests away from ZkPathUtils
GWphua Feb 27, 2025
948d721
Use computeIfAbsent where necessary
GWphua Feb 27, 2025
f964497
Use JUnit5 for new Test class
GWphua Feb 27, 2025
6f6b12d
Fix checkstyle
GWphua Feb 27, 2025
d27e27e
Revert NodeAnnouncer changes
GWphua Feb 28, 2025
9648155
Fix compile
GWphua Feb 28, 2025
a0513b9
Upgrade to CuratorCache
GWphua Mar 11, 2025
c3d89fc
Revert logging of exceptions
GWphua Mar 17, 2025
384849c
Changes to avoid race conditions when announcing
GWphua Mar 17, 2025
7a9e09f
Feature flag for announcers
GWphua Mar 17, 2025
5e67ed2
Checkstyle
GWphua Mar 17, 2025
c0fc475
Dependency injection for Announcers
GWphua Mar 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/api-reference/tasks-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1059,9 +1059,9 @@ Host: http://ROUTER_IP:ROUTER_PORT
2023-07-03T22:11:17,933 INFO [task-runner-0-priority-0] org.apache.kafka.common.metrics.Metrics - Closing reporter org.apache.kafka.common.metrics.JmxReporter
2023-07-03T22:11:17,933 INFO [task-runner-0-priority-0] org.apache.kafka.common.metrics.Metrics - Metrics reporters closed
2023-07-03T22:11:17,935 INFO [task-runner-0-priority-0] org.apache.kafka.common.utils.AppInfoParser - App info kafka.consumer for consumer-kafka-supervisor-dcanhmig-1 unregistered
2023-07-03T22:11:17,936 INFO [task-runner-0-priority-0] org.apache.druid.curator.announcement.Announcer - Unannouncing [/druid/internal-discovery/PEON/localhost:8100]
2023-07-03T22:11:17,936 INFO [task-runner-0-priority-0] org.apache.druid.curator.announcement.PathChildrenAnnouncer - Unannouncing [/druid/internal-discovery/PEON/localhost:8100]
2023-07-03T22:11:17,972 INFO [task-runner-0-priority-0] org.apache.druid.curator.discovery.CuratorDruidNodeAnnouncer - Unannounced self [{"druidNode":{"service":"druid/middleManager","host":"localhost","bindOnHost":false,"plaintextPort":8100,"port":-1,"tlsPort":-1,"enablePlaintextPort":true,"enableTlsPort":false},"nodeType":"peon","services":{"dataNodeService":{"type":"dataNodeService","tier":"_default_tier","maxSize":0,"type":"indexer-executor","serverType":"indexer-executor","priority":0},"lookupNodeService":{"type":"lookupNodeService","lookupTier":"__default"}}}].
2023-07-03T22:11:17,972 INFO [task-runner-0-priority-0] org.apache.druid.curator.announcement.Announcer - Unannouncing [/druid/announcements/localhost:8100]
2023-07-03T22:11:17,972 INFO [task-runner-0-priority-0] org.apache.druid.curator.announcement.PathChildrenAnnouncer - Unannouncing [/druid/announcements/localhost:8100]
2023-07-03T22:11:17,996 INFO [task-runner-0-priority-0] org.apache.druid.indexing.worker.executor.ExecutorLifecycle - Task completed with status: {
"id" : "index_kafka_social_media_0e905aa31037879_nommnaeg",
"status" : "SUCCESS",
Expand Down
1 change: 1 addition & 0 deletions docs/configuration/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ We recommend just setting the base ZK path and the ZK service host, but all ZK p
|`druid.zk.service.connectionTimeoutMs`|ZooKeeper connection timeout, in milliseconds.|`15000`|
|`druid.zk.service.compress`|Boolean flag for whether or not created Znodes should be compressed.|`true`|
|`druid.zk.service.acl`|Boolean flag for whether or not to enable ACL security for ZooKeeper. If ACL is enabled, zNode creators will have all permissions.|`false`|
|`druid.zk.service.pathChildrenCacheStrategy`|Dictates the underlying caching strategy for service announcements. Set true to let announcers to use Apache Curator's PathChildrenCache strategy, otherwise NodeCache strategy. Consider using NodeCache strategy when you are dealing with huge number of ZooKeeper watches in your cluster.|`true`|

#### Path configuration

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
import org.apache.curator.framework.CuratorFramework;
import org.apache.druid.curator.CuratorUtils;
import org.apache.druid.curator.announcement.Announcer;
import org.apache.druid.guice.annotations.DirectExecutorAnnouncer;
import org.apache.druid.indexing.overlord.config.RemoteTaskRunnerConfig;
import org.apache.druid.java.util.common.DateTimes;
import org.apache.druid.java.util.common.ISE;
import org.apache.druid.java.util.common.concurrent.Execs;
import org.apache.druid.java.util.common.lifecycle.LifecycleStart;
import org.apache.druid.java.util.common.lifecycle.LifecycleStop;
import org.apache.druid.java.util.common.logger.Logger;
Expand Down Expand Up @@ -69,15 +69,15 @@ public WorkerCuratorCoordinator(
IndexerZkConfig indexerZkConfig,
RemoteTaskRunnerConfig config,
CuratorFramework curatorFramework,
@DirectExecutorAnnouncer Announcer announcer,
Worker worker
)
{
this.jsonMapper = jsonMapper;
this.config = config;
this.curatorFramework = curatorFramework;
this.worker = worker;

this.announcer = new Announcer(curatorFramework, Execs.directExecutor());
this.announcer = announcer;

this.baseAnnouncementsPath = getPath(Arrays.asList(indexerZkConfig.getAnnouncementsPath(), worker.getHost()));
this.baseTaskPath = getPath(Arrays.asList(indexerZkConfig.getTasksPath(), worker.getHost()));
Expand All @@ -87,7 +87,7 @@ public WorkerCuratorCoordinator(
@LifecycleStart
public void start() throws Exception
{
log.info("WorkerCuratorCoordinator good to go sir. Server[%s]", worker.getHost());
log.info("WorkerCuratorCoordinator good to go. Server[%s]", worker.getHost());
synchronized (lock) {
if (started) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.apache.curator.test.TestingCluster;
import org.apache.druid.client.coordinator.NoopCoordinatorClient;
import org.apache.druid.curator.PotentiallyGzippedCompressionProvider;
import org.apache.druid.curator.announcement.NodeAnnouncer;
import org.apache.druid.indexer.TaskState;
import org.apache.druid.indexing.common.IndexingServiceCondition;
import org.apache.druid.indexing.common.SegmentCacheManagerFactory;
Expand All @@ -47,6 +48,7 @@
import org.apache.druid.indexing.worker.config.WorkerConfig;
import org.apache.druid.java.util.common.FileUtils;
import org.apache.druid.java.util.common.StringUtils;
import org.apache.druid.java.util.common.concurrent.Execs;
import org.apache.druid.rpc.indexing.NoopOverlordClient;
import org.apache.druid.rpc.indexing.OverlordClient;
import org.apache.druid.segment.IndexIO;
Expand Down Expand Up @@ -141,6 +143,7 @@ public String getBase()
),
new TestRemoteTaskRunnerConfig(new Period("PT1S")),
cf,
new NodeAnnouncer(cf, Execs.directExecutor()),
worker
);
workerCuratorCoordinator.start();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@
import org.apache.curator.test.TestingCluster;
import org.apache.druid.curator.PotentiallyGzippedCompressionProvider;
import org.apache.druid.curator.ZkEnablementConfig;
import org.apache.druid.curator.announcement.NodeAnnouncer;
import org.apache.druid.indexing.overlord.config.RemoteTaskRunnerConfig;
import org.apache.druid.indexing.worker.Worker;
import org.apache.druid.indexing.worker.WorkerCuratorCoordinator;
import org.apache.druid.indexing.worker.WorkerTaskMonitor;
import org.apache.druid.indexing.worker.config.WorkerConfig;
import org.apache.druid.jackson.DefaultObjectMapper;
import org.apache.druid.java.util.common.StringUtils;
import org.apache.druid.java.util.common.concurrent.Execs;
import org.apache.druid.server.initialization.IndexerZkConfig;
import org.apache.druid.server.initialization.ZkPathsConfig;
import org.easymock.EasyMock;
Expand Down Expand Up @@ -95,6 +97,7 @@ public String getBase()
}, null, null, null, null),
new RemoteTaskRunnerConfig(),
cf,
new NodeAnnouncer(cf, Execs.directExecutor()),
worker
);
curatorCoordinator.start();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ public class CuratorConfig
@JsonProperty("maxZkRetries")
private int maxZkRetries = 29;

@JsonProperty("pathChildrenCacheStrategy")
private boolean pathChildrenCacheStrategy = true;

public static CuratorConfig create(String hosts)
{
CuratorConfig config = new CuratorConfig();
Expand Down Expand Up @@ -141,4 +144,9 @@ public int getMaxZkRetries()
{
return maxZkRetries;
}

public boolean getPathChildrenCacheStrategy()
{
return pathChildrenCacheStrategy;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* 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.curator.announcement;

/**
* The {@link Announceable} is a representation of an announcement to be made in ZooKeeper.
*/
class Announceable
{
/**
* Represents the path in ZooKeeper where the announcement will be made.
*/
final String path;

/**
* Holds the actual data to be announced.
*/
final byte[] bytes;

/**
* Indicates whether parent nodes should be removed if the announcement is created successfully.
* This can be useful for cleaning up unused paths in ZooKeeper.
*/
final boolean removeParentsIfCreated;

public Announceable(String path, byte[] bytes, boolean removeParentsIfCreated)
{
this.path = path;
this.bytes = bytes;
this.removeParentsIfCreated = removeParentsIfCreated;
}

// This should be used for updates only, where removeParentsIfCreated is not relevant.
public Announceable(String path, byte[] bytes)
{
// removeParentsIfCreated is irrelevant, so we can use dummy value "false".
this(path, bytes, false);
}
}
Loading
Loading