You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by ct...@apache.org on 2022/03/03 14:21:31 UTC

[accumulo] branch main updated: Improve ZooReader/ZooReaderWriter (#2543)

This is an automated email from the ASF dual-hosted git repository.

ctubbsii pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo.git


The following commit(s) were added to refs/heads/main by this push:
     new 4b66b96  Improve ZooReader/ZooReaderWriter (#2543)
4b66b96 is described below

commit 4b66b96b8f6c65c390fc26c11acf8c51cb78d858
Author: Christopher Tubbs <ct...@apache.org>
AuthorDate: Thu Mar 3 09:17:41 2022 -0500

    Improve ZooReader/ZooReaderWriter (#2543)
    
    * Inline a ClientContext method used only for the deprecated
      ConnectorImpl from ClientContext into ConnectorImpl
    * Move construction of most new ZooReader objects into ClientContext
    * Avoid constructing zoo-related objects when one is available from an
      existing ClientContext or ServerContext
    * Allow efficient conversion of ZooReader into ZooReaderWriter, with a
      provided secret to avoid some object construction for ZooReaderWriter
---
 .../accumulo/core/clientImpl/ClientContext.java    | 55 +++----------------
 .../accumulo/core/clientImpl/ConnectorImpl.java    | 41 +++++++++++++-
 .../core/clientImpl/ReplicationClient.java         |  3 +-
 .../core/metadata/schema/TabletsMetadata.java      |  2 +-
 .../org/apache/accumulo/core/util/MonitorUtil.java |  3 +-
 .../util/compaction/ExternalCompactionUtil.java    |  3 +-
 .../apache/accumulo/fate/zookeeper/ZooReader.java  |  4 ++
 .../accumulo/fate/zookeeper/ZooReaderWriter.java   | 16 +++++-
 .../miniclusterImpl/MiniAccumuloClusterImpl.java   |  4 +-
 .../org/apache/accumulo/server/ServerContext.java  |  8 ++-
 .../server/constraints/MetadataConstraints.java    |  2 +-
 .../accumulo/server/manager/LiveTServerSet.java    |  2 +-
 .../accumulo/server/metadata/ServerAmpleImpl.java  |  3 +-
 .../server/security/SecurityOperation.java         |  2 +-
 .../security/handler/KerberosAuthenticator.java    |  2 +-
 .../server/security/handler/ZKAuthenticator.java   |  2 +-
 .../server/security/handler/ZKAuthorizor.java      |  2 +-
 .../server/security/handler/ZKPermHandler.java     |  2 +-
 .../apache/accumulo/server/util/ChangeSecret.java  | 12 ++--
 .../server/zookeeper/DistributedWorkQueue.java     |  8 +--
 .../server/zookeeper/TransactionWatcher.java       |  2 +-
 .../security/handler/ZKAuthenticatorTest.java      | 32 +++++------
 .../accumulo/server/util/TServerUtilsTest.java     |  5 +-
 .../accumulo/manager/recovery/RecoveryManager.java |  2 +-
 .../DistributedWorkQueueWorkAssigner.java          |  2 +-
 .../replication/ManagerReplicationCoordinator.java |  3 +-
 .../ManagerReplicationCoordinatorTest.java         | 64 ++++++++++++----------
 .../org/apache/accumulo/tserver/TabletServer.java  |  2 +-
 .../accumulo/shell/commands/FateCommand.java       |  3 +-
 .../org/apache/accumulo/test/ExistingMacIT.java    |  8 +--
 .../apache/accumulo/test/TableOperationsIT.java    |  5 +-
 .../ThriftServerBindsBeforeZooKeeperLockIT.java    | 11 ++--
 .../java/org/apache/accumulo/test/UnusedWALIT.java |  4 --
 .../test/compaction/UserCompactionStrategyIT.java  |  7 +--
 .../accumulo/test/fate/zookeeper/FateIT.java       |  2 +-
 .../test/fate/zookeeper/ServiceLockIT.java         |  6 +-
 .../accumulo/test/fate/zookeeper/ZooMutatorIT.java |  2 +-
 .../accumulo/test/functional/BackupManagerIT.java  |  4 +-
 .../test/functional/ConcurrentDeleteTableIT.java   |  5 +-
 .../test/functional/FateConcurrencyIT.java         |  6 +-
 .../accumulo/test/functional/FateStarvationIT.java |  3 +-
 .../test/functional/FunctionalTestUtils.java       | 13 ++---
 .../test/functional/GarbageCollectorIT.java        |  4 +-
 .../accumulo/test/functional/ReadWriteIT.java      | 10 +---
 .../apache/accumulo/test/functional/RenameIT.java  |  3 +-
 .../apache/accumulo/test/functional/RestartIT.java | 10 +---
 .../replication/MultiTserverReplicationIT.java     |  6 +-
 .../test/upgrade/GCUpgrade9to10TestIT.java         |  2 +-
 .../test/zookeeper/ZooKeeperTestingServer.java     |  6 ++
 49 files changed, 191 insertions(+), 217 deletions(-)

diff --git a/core/src/main/java/org/apache/accumulo/core/clientImpl/ClientContext.java b/core/src/main/java/org/apache/accumulo/core/clientImpl/ClientContext.java
index 7c04571..88fab7b 100644
--- a/core/src/main/java/org/apache/accumulo/core/clientImpl/ClientContext.java
+++ b/core/src/main/java/org/apache/accumulo/core/clientImpl/ClientContext.java
@@ -81,6 +81,7 @@ import org.apache.accumulo.core.util.tables.TableZooHelper;
 import org.apache.accumulo.fate.zookeeper.ServiceLock;
 import org.apache.accumulo.fate.zookeeper.ZooCache;
 import org.apache.accumulo.fate.zookeeper.ZooCacheFactory;
+import org.apache.accumulo.fate.zookeeper.ZooReader;
 import org.apache.accumulo.fate.zookeeper.ZooUtil;
 import org.apache.hadoop.conf.Configuration;
 import org.slf4j.Logger;
@@ -103,6 +104,7 @@ public class ClientContext implements AccumuloClient {
 
   private final ClientInfo info;
   private InstanceId instanceId;
+  private final ZooReader zooReader;
   private final ZooCache zooCache;
 
   private Credentials creds;
@@ -150,6 +152,7 @@ public class ClientContext implements AccumuloClient {
       AccumuloConfiguration serverConf) {
     this.info = info;
     this.hadoopConf = info.getHadoopConf();
+    zooReader = new ZooReader(info.getZooKeepers(), info.getZooKeepersSessionTimeOut());
     zooCache =
         new ZooCacheFactory().getZooCache(info.getZooKeepers(), info.getZooKeepersSessionTimeOut());
     this.serverConf = serverConf;
@@ -163,53 +166,6 @@ public class ClientContext implements AccumuloClient {
     this.namespaceops = new NamespaceOperationsImpl(this, tableops);
   }
 
-  /**
-   * Retrieve the instance used to construct this context
-   *
-   * @deprecated since 2.0.0
-   */
-  @Deprecated(since = "2.0.0")
-  public org.apache.accumulo.core.client.Instance getDeprecatedInstance() {
-    final ClientContext context = this;
-    return new org.apache.accumulo.core.client.Instance() {
-      @Override
-      public String getRootTabletLocation() {
-        return context.getRootTabletLocation();
-      }
-
-      @Override
-      public List<String> getMasterLocations() {
-        return context.getManagerLocations();
-      }
-
-      @Override
-      public String getInstanceID() {
-        return context.getInstanceID().canonical();
-      }
-
-      @Override
-      public String getInstanceName() {
-        return context.getInstanceName();
-      }
-
-      @Override
-      public String getZooKeepers() {
-        return context.getZooKeepers();
-      }
-
-      @Override
-      public int getZooKeepersSessionTimeOut() {
-        return context.getZooKeepersSessionTimeOut();
-      }
-
-      @Override
-      public org.apache.accumulo.core.client.Connector getConnector(String principal,
-          AuthenticationToken token) throws AccumuloException, AccumuloSecurityException {
-        return org.apache.accumulo.core.client.Connector.from(context);
-      }
-    };
-  }
-
   public Ample getAmple() {
     ensureOpen();
     return new AmpleImpl(this);
@@ -985,6 +941,11 @@ public class ClientContext implements AccumuloClient {
     }
   }
 
+  public ZooReader getZooReader() {
+    ensureOpen();
+    return zooReader;
+  }
+
   public synchronized ThriftTransportPool getTransportPool() {
     ensureOpen();
     if (thriftTransportPool == null) {
diff --git a/core/src/main/java/org/apache/accumulo/core/clientImpl/ConnectorImpl.java b/core/src/main/java/org/apache/accumulo/core/clientImpl/ConnectorImpl.java
index 73c716c..ee14049 100644
--- a/core/src/main/java/org/apache/accumulo/core/clientImpl/ConnectorImpl.java
+++ b/core/src/main/java/org/apache/accumulo/core/clientImpl/ConnectorImpl.java
@@ -20,6 +20,8 @@ package org.apache.accumulo.core.clientImpl;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 
+import java.util.List;
+
 import org.apache.accumulo.core.client.AccumuloException;
 import org.apache.accumulo.core.client.AccumuloSecurityException;
 import org.apache.accumulo.core.client.BatchDeleter;
@@ -36,6 +38,7 @@ import org.apache.accumulo.core.client.admin.NamespaceOperations;
 import org.apache.accumulo.core.client.admin.ReplicationOperations;
 import org.apache.accumulo.core.client.admin.SecurityOperations;
 import org.apache.accumulo.core.client.admin.TableOperations;
+import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
 import org.apache.accumulo.core.clientImpl.thrift.SecurityErrorCode;
 import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.core.singletons.SingletonManager;
@@ -77,7 +80,43 @@ public class ConnectorImpl extends org.apache.accumulo.core.client.Connector {
 
   @Override
   public org.apache.accumulo.core.client.Instance getInstance() {
-    return context.getDeprecatedInstance();
+    return new org.apache.accumulo.core.client.Instance() {
+      @Override
+      public String getRootTabletLocation() {
+        return context.getRootTabletLocation();
+      }
+
+      @Override
+      public List<String> getMasterLocations() {
+        return context.getManagerLocations();
+      }
+
+      @Override
+      public String getInstanceID() {
+        return context.getInstanceID().canonical();
+      }
+
+      @Override
+      public String getInstanceName() {
+        return context.getInstanceName();
+      }
+
+      @Override
+      public String getZooKeepers() {
+        return context.getZooKeepers();
+      }
+
+      @Override
+      public int getZooKeepersSessionTimeOut() {
+        return context.getZooKeepersSessionTimeOut();
+      }
+
+      @Override
+      public org.apache.accumulo.core.client.Connector getConnector(String principal,
+          AuthenticationToken token) throws AccumuloException, AccumuloSecurityException {
+        return org.apache.accumulo.core.client.Connector.from(context);
+      }
+    };
   }
 
   @Override
diff --git a/core/src/main/java/org/apache/accumulo/core/clientImpl/ReplicationClient.java b/core/src/main/java/org/apache/accumulo/core/clientImpl/ReplicationClient.java
index f05f361..d5955e5 100644
--- a/core/src/main/java/org/apache/accumulo/core/clientImpl/ReplicationClient.java
+++ b/core/src/main/java/org/apache/accumulo/core/clientImpl/ReplicationClient.java
@@ -92,8 +92,7 @@ public class ReplicationClient {
 
     // Get the coordinator port for the manager we're trying to connect to
     try {
-      ZooReader reader =
-          new ZooReader(context.getZooKeepers(), context.getZooKeepersSessionTimeOut());
+      ZooReader reader = context.getZooReader();
       replCoordinatorAddr = new String(reader.getData(zkPath), UTF_8);
     } catch (KeeperException | InterruptedException e) {
       log.error("Could not fetch remote coordinator port", e);
diff --git a/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletsMetadata.java b/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletsMetadata.java
index d82bb0a..ee6c77b 100644
--- a/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletsMetadata.java
+++ b/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletsMetadata.java
@@ -510,7 +510,7 @@ public class TabletsMetadata implements Iterable<TabletMetadata>, AutoCloseable
       case EVENTUAL:
         return getRootMetadata(zkRoot, ctx.getZooCache());
       case IMMEDIATE:
-        ZooReader zooReader = new ZooReader(ctx.getZooKeepers(), ctx.getZooKeepersSessionTimeOut());
+        ZooReader zooReader = ctx.getZooReader();
         try {
           return RootTabletMetadata.fromJson(zooReader.getData(zkRoot + RootTable.ZROOT_TABLET))
               .convertToTabletMetadata();
diff --git a/core/src/main/java/org/apache/accumulo/core/util/MonitorUtil.java b/core/src/main/java/org/apache/accumulo/core/util/MonitorUtil.java
index 3b40c23..2f15287 100644
--- a/core/src/main/java/org/apache/accumulo/core/util/MonitorUtil.java
+++ b/core/src/main/java/org/apache/accumulo/core/util/MonitorUtil.java
@@ -32,8 +32,7 @@ public class MonitorUtil {
 
   public static String getLocation(ClientContext context)
       throws KeeperException, InterruptedException {
-    return getLocation(
-        new ZooReader(context.getZooKeepers(), context.getZooKeepersSessionTimeOut()), context);
+    return getLocation(context.getZooReader(), context);
   }
 
   @VisibleForTesting
diff --git a/core/src/main/java/org/apache/accumulo/core/util/compaction/ExternalCompactionUtil.java b/core/src/main/java/org/apache/accumulo/core/util/compaction/ExternalCompactionUtil.java
index d034d4e..a89932d 100644
--- a/core/src/main/java/org/apache/accumulo/core/util/compaction/ExternalCompactionUtil.java
+++ b/core/src/main/java/org/apache/accumulo/core/util/compaction/ExternalCompactionUtil.java
@@ -118,8 +118,7 @@ public class ExternalCompactionUtil {
     try {
       final Map<String,List<HostAndPort>> queuesAndAddresses = new HashMap<>();
       final String compactorQueuesPath = context.getZooKeeperRoot() + Constants.ZCOMPACTORS;
-      ZooReader zooReader =
-          new ZooReader(context.getZooKeepers(), context.getZooKeepersSessionTimeOut());
+      ZooReader zooReader = context.getZooReader();
       List<String> queues = zooReader.getChildren(compactorQueuesPath);
       for (String queue : queues) {
         queuesAndAddresses.putIfAbsent(queue, new ArrayList<HostAndPort>());
diff --git a/core/src/main/java/org/apache/accumulo/fate/zookeeper/ZooReader.java b/core/src/main/java/org/apache/accumulo/fate/zookeeper/ZooReader.java
index fb8ad96..4165d3f 100644
--- a/core/src/main/java/org/apache/accumulo/fate/zookeeper/ZooReader.java
+++ b/core/src/main/java/org/apache/accumulo/fate/zookeeper/ZooReader.java
@@ -54,6 +54,10 @@ public class ZooReader {
     this.timeout = timeout;
   }
 
+  public ZooReaderWriter asWriter(String secret) {
+    return new ZooReaderWriter(keepers, timeout, secret);
+  }
+
   protected ZooKeeper getZooKeeper() {
     return ZooSession.getAnonymousSession(keepers, timeout);
   }
diff --git a/core/src/main/java/org/apache/accumulo/fate/zookeeper/ZooReaderWriter.java b/core/src/main/java/org/apache/accumulo/fate/zookeeper/ZooReaderWriter.java
index 091dd0b..8e79007 100644
--- a/core/src/main/java/org/apache/accumulo/fate/zookeeper/ZooReaderWriter.java
+++ b/core/src/main/java/org/apache/accumulo/fate/zookeeper/ZooReaderWriter.java
@@ -24,8 +24,8 @@ import static java.util.Objects.requireNonNull;
 import java.util.List;
 
 import org.apache.accumulo.core.clientImpl.AcceptableThriftTableOperationException;
-import org.apache.accumulo.core.conf.AccumuloConfiguration;
 import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.conf.SiteConfiguration;
 import org.apache.accumulo.fate.zookeeper.ZooUtil.NodeExistsPolicy;
 import org.apache.accumulo.fate.zookeeper.ZooUtil.NodeMissingPolicy;
 import org.apache.zookeeper.CreateMode;
@@ -40,20 +40,30 @@ public class ZooReaderWriter extends ZooReader {
     byte[] mutate(byte[] currentValue) throws AcceptableThriftTableOperationException;
   }
 
-  public ZooReaderWriter(AccumuloConfiguration conf) {
+  public ZooReaderWriter(SiteConfiguration conf) {
     this(conf.get(Property.INSTANCE_ZK_HOST),
         (int) conf.getTimeInMillis(Property.INSTANCE_ZK_TIMEOUT),
         conf.get(Property.INSTANCE_SECRET));
   }
 
+  private final String secret;
   private final byte[] auth;
 
-  public ZooReaderWriter(String keepers, int timeoutInMillis, String secret) {
+  ZooReaderWriter(String keepers, int timeoutInMillis, String secret) {
     super(keepers, timeoutInMillis);
+    this.secret = requireNonNull(secret);
     this.auth = ("accumulo:" + secret).getBytes(UTF_8);
   }
 
   @Override
+  public ZooReaderWriter asWriter(String secret) {
+    if (this.secret.equals(secret)) {
+      return this;
+    }
+    return super.asWriter(secret);
+  }
+
+  @Override
   public ZooKeeper getZooKeeper() {
     return ZooSession.getAuthenticatedSession(keepers, timeout, "digest", auth);
   }
diff --git a/minicluster/src/main/java/org/apache/accumulo/miniclusterImpl/MiniAccumuloClusterImpl.java b/minicluster/src/main/java/org/apache/accumulo/miniclusterImpl/MiniAccumuloClusterImpl.java
index c5782d2..b6e6b1f 100644
--- a/minicluster/src/main/java/org/apache/accumulo/miniclusterImpl/MiniAccumuloClusterImpl.java
+++ b/minicluster/src/main/java/org/apache/accumulo/miniclusterImpl/MiniAccumuloClusterImpl.java
@@ -483,7 +483,6 @@ public class MiniAccumuloClusterImpl implements AccumuloCluster {
       Configuration hadoopConf = config.getHadoopConfiguration();
       ServerDirs serverDirs = new ServerDirs(acuConf, hadoopConf);
 
-      ConfigurationCopy cc = new ConfigurationCopy(acuConf);
       Path instanceIdPath;
       try (var fs = getServerContext().getVolumeManager()) {
         instanceIdPath = serverDirs.getInstanceIdLocation(fs.getFirst());
@@ -493,8 +492,7 @@ public class MiniAccumuloClusterImpl implements AccumuloCluster {
 
       InstanceId instanceIdFromFile =
           VolumeManager.getInstanceIDFromHdfs(instanceIdPath, hadoopConf);
-      ZooReaderWriter zrw = new ZooReaderWriter(cc.get(Property.INSTANCE_ZK_HOST),
-          (int) cc.getTimeInMillis(Property.INSTANCE_ZK_TIMEOUT), cc.get(Property.INSTANCE_SECRET));
+      ZooReaderWriter zrw = getServerContext().getZooReaderWriter();
 
       String rootPath = ZooUtil.getRoot(instanceIdFromFile);
 
diff --git a/server/base/src/main/java/org/apache/accumulo/server/ServerContext.java b/server/base/src/main/java/org/apache/accumulo/server/ServerContext.java
index 9ab212e..aa59057 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/ServerContext.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/ServerContext.java
@@ -158,8 +158,7 @@ public class ServerContext extends ClientContext {
     if (systemConfig == null) {
       // system configuration uses its own instance of ZooCache
       // this could be useful to keep its update counter independent
-      ZooCache propCache =
-          new ZooCache(new ZooReader(getZooKeepers(), getZooKeepersSessionTimeOut()), null);
+      ZooCache propCache = new ZooCache(getZooReader(), null);
       systemConfig = new ZooConfiguration(this, propCache, getSiteConfiguration());
     }
     return systemConfig;
@@ -212,6 +211,11 @@ public class ServerContext extends ClientContext {
     return info.getVolumeManager();
   }
 
+  @Override
+  public ZooReader getZooReader() {
+    return getZooReaderWriter();
+  }
+
   public ZooReaderWriter getZooReaderWriter() {
     return zooReaderWriter;
   }
diff --git a/server/base/src/main/java/org/apache/accumulo/server/constraints/MetadataConstraints.java b/server/base/src/main/java/org/apache/accumulo/server/constraints/MetadataConstraints.java
index 0c598d7..4c66cc3 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/constraints/MetadataConstraints.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/constraints/MetadataConstraints.java
@@ -277,7 +277,7 @@ public class MetadataConstraints implements Constraint {
           }
         } else if (new ColumnFQ(columnUpdate).equals(ServerColumnFamily.LOCK_COLUMN)) {
           if (zooCache == null) {
-            zooCache = new ZooCache(context.getZooReaderWriter(), null);
+            zooCache = new ZooCache(context.getZooReader(), null);
             CleanerUtil.zooCacheClearer(this, zooCache);
           }
 
diff --git a/server/base/src/main/java/org/apache/accumulo/server/manager/LiveTServerSet.java b/server/base/src/main/java/org/apache/accumulo/server/manager/LiveTServerSet.java
index d0ce0bf..a88af20 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/manager/LiveTServerSet.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/manager/LiveTServerSet.java
@@ -248,7 +248,7 @@ public class LiveTServerSet implements Watcher {
 
   public synchronized ZooCache getZooCache() {
     if (zooCache == null)
-      zooCache = new ZooCache(context.getZooReaderWriter(), this);
+      zooCache = new ZooCache(context.getZooReader(), this);
     return zooCache;
   }
 
diff --git a/server/base/src/main/java/org/apache/accumulo/server/metadata/ServerAmpleImpl.java b/server/base/src/main/java/org/apache/accumulo/server/metadata/ServerAmpleImpl.java
index 3f10aaf..66cecd6 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/metadata/ServerAmpleImpl.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/metadata/ServerAmpleImpl.java
@@ -48,7 +48,6 @@ import org.apache.accumulo.core.metadata.schema.MetadataSchema.DeletesSection;
 import org.apache.accumulo.core.metadata.schema.MetadataSchema.DeletesSection.SkewedKeyValue;
 import org.apache.accumulo.core.metadata.schema.MetadataSchema.ExternalCompactionSection;
 import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.fate.zookeeper.ZooReader;
 import org.apache.accumulo.server.ServerContext;
 import org.apache.hadoop.io.Text;
 import org.apache.zookeeper.KeeperException;
@@ -163,7 +162,7 @@ public class ServerAmpleImpl extends AmpleImpl implements Ample {
   @Override
   public Iterator<String> getGcCandidates(DataLevel level) {
     if (level == DataLevel.ROOT) {
-      var zooReader = new ZooReader(context.getZooKeepers(), context.getZooKeepersSessionTimeOut());
+      var zooReader = context.getZooReader();
       byte[] json;
       try {
         json = zooReader.getData(context.getZooKeeperRoot() + RootTable.ZROOT_TABLET_GC_CANDIDATES);
diff --git a/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java b/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java
index 343ab22..ea2d03f 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/security/SecurityOperation.java
@@ -113,7 +113,7 @@ public class SecurityOperation {
   protected SecurityOperation(ServerContext context) {
     this.context = context;
     ZKUserPath = Constants.ZROOT + "/" + context.getInstanceID() + "/users";
-    zooCache = new ZooCache(context.getZooReaderWriter(), null);
+    zooCache = new ZooCache(context.getZooReader(), null);
   }
 
   public SecurityOperation(ServerContext context, Authorizor author, Authenticator authent,
diff --git a/server/base/src/main/java/org/apache/accumulo/server/security/handler/KerberosAuthenticator.java b/server/base/src/main/java/org/apache/accumulo/server/security/handler/KerberosAuthenticator.java
index 06313933..712bbac 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/security/handler/KerberosAuthenticator.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/security/handler/KerberosAuthenticator.java
@@ -60,7 +60,7 @@ public class KerberosAuthenticator implements Authenticator {
   @Override
   public void initialize(ServerContext context) {
     this.context = context;
-    zooCache = new ZooCache(context.getZooReaderWriter(), null);
+    zooCache = new ZooCache(context.getZooReader(), null);
     impersonation = new UserImpersonation(context.getConfiguration());
     zkAuthenticator.initialize(context);
     zkUserPath = Constants.ZROOT + "/" + context.getInstanceID() + "/users";
diff --git a/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthenticator.java b/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthenticator.java
index f7e9f61..98bb9ee 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthenticator.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthenticator.java
@@ -52,7 +52,7 @@ public final class ZKAuthenticator implements Authenticator {
   @Override
   public void initialize(ServerContext context) {
     this.context = context;
-    zooCache = new ZooCache(context.getZooReaderWriter(), null);
+    zooCache = new ZooCache(context.getZooReader(), null);
     ZKUserPath = Constants.ZROOT + "/" + context.getInstanceID() + "/users";
   }
 
diff --git a/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java b/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java
index 384985d..023134d 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKAuthorizor.java
@@ -49,7 +49,7 @@ public class ZKAuthorizor implements Authorizor {
   @Override
   public void initialize(ServerContext context) {
     this.context = context;
-    zooCache = new ZooCache(context.getZooReaderWriter(), null);
+    zooCache = new ZooCache(context.getZooReader(), null);
     ZKUserPath = ZKSecurityTool.getInstancePath(context.getInstanceID()) + "/users";
   }
 
diff --git a/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKPermHandler.java b/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKPermHandler.java
index 2a3007b..a6d03bf 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKPermHandler.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/security/handler/ZKPermHandler.java
@@ -65,7 +65,7 @@ public class ZKPermHandler implements PermissionHandler {
 
   @Override
   public void initialize(ServerContext context) {
-    zooCache = new ZooCache(context.getZooReaderWriter(), null);
+    zooCache = new ZooCache(context.getZooReader(), null);
     zoo = context.getZooReaderWriter();
     InstanceId instanceId = context.getInstanceID();
     ZKUserPath = ZKSecurityTool.getInstancePath(instanceId) + "/users";
diff --git a/server/base/src/main/java/org/apache/accumulo/server/util/ChangeSecret.java b/server/base/src/main/java/org/apache/accumulo/server/util/ChangeSecret.java
index 1d9cf45..560fe06 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/util/ChangeSecret.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/util/ChangeSecret.java
@@ -116,8 +116,7 @@ public class ChangeSecret {
 
   private static void verifyAccumuloIsDown(ServerContext context, String oldPassword)
       throws Exception {
-    ZooReader zooReader = new ZooReaderWriter(context.getZooKeepers(),
-        context.getZooKeepersSessionTimeOut(), oldPassword);
+    ZooReader zooReader = context.getZooReader().asWriter(oldPassword);
     String root = context.getZooKeeperRoot();
     final List<String> ephemerals = new ArrayList<>();
     recurse(zooReader, root, (zoo, path) -> {
@@ -137,10 +136,8 @@ public class ChangeSecret {
 
   private static void rewriteZooKeeperInstance(final ServerContext context,
       final InstanceId newInstanceId, String oldPass, String newPass) throws Exception {
-    final ZooReaderWriter orig = new ZooReaderWriter(context.getZooKeepers(),
-        context.getZooKeepersSessionTimeOut(), oldPass);
-    final ZooReaderWriter new_ = new ZooReaderWriter(context.getZooKeepers(),
-        context.getZooKeepersSessionTimeOut(), newPass);
+    final ZooReaderWriter orig = context.getZooReader().asWriter(oldPass);
+    final ZooReaderWriter new_ = context.getZooReader().asWriter(newPass);
 
     String root = context.getZooKeeperRoot();
     recurse(orig, root, (zoo, path) -> {
@@ -220,8 +217,7 @@ public class ChangeSecret {
   }
 
   private static void deleteInstance(ServerContext context, String oldPass) throws Exception {
-    ZooReaderWriter orig = new ZooReaderWriter(context.getZooKeepers(),
-        context.getZooKeepersSessionTimeOut(), oldPass);
+    ZooReaderWriter orig = context.getZooReader().asWriter(oldPass);
     orig.recursiveDelete("/accumulo/" + context.getInstanceID(), NodeMissingPolicy.SKIP);
   }
 }
diff --git a/server/base/src/main/java/org/apache/accumulo/server/zookeeper/DistributedWorkQueue.java b/server/base/src/main/java/org/apache/accumulo/server/zookeeper/DistributedWorkQueue.java
index cfd8829..3a424dc 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/zookeeper/DistributedWorkQueue.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/zookeeper/DistributedWorkQueue.java
@@ -60,7 +60,6 @@ public class DistributedWorkQueue {
   private ThreadPoolExecutor threadPool;
   private ZooReaderWriter zoo;
   private String path;
-  private AccumuloConfiguration config;
   private ServerContext context;
   private long timerInitialDelay, timerPeriod;
 
@@ -174,21 +173,16 @@ public class DistributedWorkQueue {
   public DistributedWorkQueue(String path, AccumuloConfiguration config, ServerContext context,
       long timerInitialDelay, long timerPeriod) {
     this.path = path;
-    this.config = config;
     this.context = context;
     this.timerInitialDelay = timerInitialDelay;
     this.timerPeriod = timerPeriod;
-    zoo = new ZooReaderWriter(this.config);
+    zoo = context.getZooReaderWriter();
   }
 
   public ServerContext getContext() {
     return context;
   }
 
-  public ZooReaderWriter getZooReaderWriter() {
-    return zoo;
-  }
-
   public void startProcessing(final Processor processor, ThreadPoolExecutor executorService)
       throws KeeperException, InterruptedException {
 
diff --git a/server/base/src/main/java/org/apache/accumulo/server/zookeeper/TransactionWatcher.java b/server/base/src/main/java/org/apache/accumulo/server/zookeeper/TransactionWatcher.java
index b439459..18d5324 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/zookeeper/TransactionWatcher.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/zookeeper/TransactionWatcher.java
@@ -62,7 +62,7 @@ public class TransactionWatcher {
 
     public ZooArbitrator(ServerContext context) {
       this.context = context;
-      rdr = new ZooReader(context.getZooKeepers(), context.getZooKeepersSessionTimeOut());
+      rdr = context.getZooReader();
     }
 
     @Override
diff --git a/server/base/src/test/java/org/apache/accumulo/server/security/handler/ZKAuthenticatorTest.java b/server/base/src/test/java/org/apache/accumulo/server/security/handler/ZKAuthenticatorTest.java
index 89909f3..a5a29fe 100644
--- a/server/base/src/test/java/org/apache/accumulo/server/security/handler/ZKAuthenticatorTest.java
+++ b/server/base/src/test/java/org/apache/accumulo/server/security/handler/ZKAuthenticatorTest.java
@@ -19,8 +19,10 @@
 package org.apache.accumulo.server.security.handler;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.easymock.EasyMock.anyObject;
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.matches;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
 import static org.junit.Assert.assertEquals;
@@ -45,7 +47,6 @@ import org.apache.accumulo.server.ServerContext;
 import org.apache.zookeeper.Watcher;
 import org.apache.zookeeper.ZooKeeper;
 import org.apache.zookeeper.data.Stat;
-import org.easymock.EasyMock;
 import org.junit.Test;
 
 public class ZKAuthenticatorTest {
@@ -136,15 +137,14 @@ public class ZKAuthenticatorTest {
     // mocking zk interaction
     ServerContext context = MockServerContext.getWithZK(InstanceId.of("example"), "", 30_000);
     ZooReaderWriter zr = createMock(ZooReaderWriter.class);
-    expect(context.getZooReaderWriter()).andReturn(zr).anyTimes();
+    expect(context.getZooReader()).andReturn(zr).anyTimes();
     ZooKeeper zk = createMock(ZooKeeper.class);
-    expect(zk.getChildren(EasyMock.anyObject(), EasyMock.anyObject()))
-        .andReturn(Arrays.asList(principal)).anyTimes();
-    expect(zk.exists(EasyMock.matches("/accumulo/example/users/" + principal),
-        EasyMock.anyObject(Watcher.class))).andReturn(new Stat()).anyTimes();
+    expect(zk.getChildren(anyObject(), anyObject())).andReturn(Arrays.asList(principal)).anyTimes();
+    expect(zk.exists(matches("/accumulo/example/users/" + principal), anyObject(Watcher.class)))
+        .andReturn(new Stat()).anyTimes();
     expect(zr.getZooKeeper()).andReturn(zk).anyTimes();
-    expect(zk.getData(EasyMock.matches("/accumulo/example/users/" + principal),
-        EasyMock.anyObject(), EasyMock.anyObject())).andReturn(newHash).once();
+    expect(zk.getData(matches("/accumulo/example/users/" + principal), anyObject(), anyObject()))
+        .andReturn(newHash).once();
     replay(context, zr, zk);
 
     // creating authenticator
@@ -169,18 +169,18 @@ public class ZKAuthenticatorTest {
     // mocking zk interaction
     ServerContext context = MockServerContext.getWithZK(InstanceId.of("example"), "", 30_000);
     ZooReaderWriter zr = createMock(ZooReaderWriter.class);
+    expect(context.getZooReader()).andReturn(zr).anyTimes();
     expect(context.getZooReaderWriter()).andReturn(zr).anyTimes();
     ZooKeeper zk = createMock(ZooKeeper.class);
-    expect(zk.getChildren(EasyMock.anyObject(), EasyMock.anyObject()))
-        .andReturn(Arrays.asList(principal)).anyTimes();
-    expect(zk.exists(EasyMock.matches("/accumulo/example/users/" + principal),
-        EasyMock.anyObject(Watcher.class))).andReturn(new Stat()).anyTimes();
+    expect(zk.getChildren(anyObject(), anyObject())).andReturn(Arrays.asList(principal)).anyTimes();
+    expect(zk.exists(matches("/accumulo/example/users/" + principal), anyObject(Watcher.class)))
+        .andReturn(new Stat()).anyTimes();
     expect(zr.getZooKeeper()).andReturn(zk).anyTimes();
-    expect(zk.getData(EasyMock.matches("/accumulo/example/users/" + principal),
-        EasyMock.anyObject(), EasyMock.anyObject())).andReturn(outdatedHash).once();
+    expect(zk.getData(matches("/accumulo/example/users/" + principal), anyObject(), anyObject()))
+        .andReturn(outdatedHash).once();
     // expecting that the new hash is pushed to zk
-    expect(zr.putPrivatePersistentData(EasyMock.matches("/accumulo/example/users/" + principal),
-        EasyMock.anyObject(), EasyMock.anyObject())).andReturn(true).once();
+    expect(zr.putPrivatePersistentData(matches("/accumulo/example/users/" + principal), anyObject(),
+        anyObject())).andReturn(true).once();
     replay(context, zr, zk);
 
     // creating authenticator
diff --git a/server/base/src/test/java/org/apache/accumulo/server/util/TServerUtilsTest.java b/server/base/src/test/java/org/apache/accumulo/server/util/TServerUtilsTest.java
index 997370f..d329d6f 100644
--- a/server/base/src/test/java/org/apache/accumulo/server/util/TServerUtilsTest.java
+++ b/server/base/src/test/java/org/apache/accumulo/server/util/TServerUtilsTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.accumulo.server.util;
 
+import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
@@ -47,7 +48,6 @@ import org.apache.accumulo.server.rpc.ServerAddress;
 import org.apache.accumulo.server.rpc.TServerUtils;
 import org.apache.accumulo.server.rpc.ThriftServerType;
 import org.apache.thrift.server.TServer;
-import org.easymock.EasyMock;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -61,7 +61,8 @@ public class TServerUtilsTest {
 
   @Before
   public void createMockServerContext() {
-    context = EasyMock.createMock(ServerContext.class);
+    context = createMock(ServerContext.class);
+    expect(context.getZooReader()).andReturn(null).anyTimes();
     expect(context.getZooReaderWriter()).andReturn(null).anyTimes();
     expect(context.getProperties()).andReturn(new Properties()).anyTimes();
     expect(context.getZooKeepers()).andReturn("").anyTimes();
diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/recovery/RecoveryManager.java b/server/manager/src/main/java/org/apache/accumulo/manager/recovery/RecoveryManager.java
index a617e93..0503963 100644
--- a/server/manager/src/main/java/org/apache/accumulo/manager/recovery/RecoveryManager.java
+++ b/server/manager/src/main/java/org/apache/accumulo/manager/recovery/RecoveryManager.java
@@ -73,7 +73,7 @@ public class RecoveryManager {
             .maximumWeight(10_000_000).weigher((path, exist) -> path.toString().length()).build();
 
     executor = ThreadPools.createScheduledExecutorService(4, "Walog sort starter", false);
-    zooCache = new ZooCache(manager.getContext().getZooReaderWriter(), null);
+    zooCache = new ZooCache(manager.getContext().getZooReader(), null);
     try {
       List<String> workIDs =
           new DistributedWorkQueue(manager.getZooKeeperRoot() + Constants.ZRECOVERY,
diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/replication/DistributedWorkQueueWorkAssigner.java b/server/manager/src/main/java/org/apache/accumulo/manager/replication/DistributedWorkQueueWorkAssigner.java
index 9ccf59f..05b6bbd 100644
--- a/server/manager/src/main/java/org/apache/accumulo/manager/replication/DistributedWorkQueueWorkAssigner.java
+++ b/server/manager/src/main/java/org/apache/accumulo/manager/replication/DistributedWorkQueueWorkAssigner.java
@@ -110,7 +110,7 @@ public abstract class DistributedWorkQueueWorkAssigner implements WorkAssigner {
     initializeQueuedWork();
 
     if (zooCache == null) {
-      zooCache = new ZooCache(workQueue.getZooReaderWriter(), null);
+      zooCache = new ZooCache(workQueue.getContext().getZooReader(), null);
     }
 
     // Get the maximum number of entries we want to queue work for (or the default)
diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/replication/ManagerReplicationCoordinator.java b/server/manager/src/main/java/org/apache/accumulo/manager/replication/ManagerReplicationCoordinator.java
index 5d1f4e7..3f919e4 100644
--- a/server/manager/src/main/java/org/apache/accumulo/manager/replication/ManagerReplicationCoordinator.java
+++ b/server/manager/src/main/java/org/apache/accumulo/manager/replication/ManagerReplicationCoordinator.java
@@ -54,8 +54,7 @@ public class ManagerReplicationCoordinator implements ReplicationCoordinator.Ifa
   private final SecurityOperation security;
 
   public ManagerReplicationCoordinator(Manager manager) {
-    this(manager, new ZooReader(manager.getContext().getZooKeepers(),
-        manager.getContext().getZooKeepersSessionTimeOut()));
+    this(manager, manager.getContext().getZooReader());
   }
 
   protected ManagerReplicationCoordinator(Manager manager, ZooReader reader) {
diff --git a/server/manager/src/test/java/org/apache/accumulo/manager/replication/ManagerReplicationCoordinatorTest.java b/server/manager/src/test/java/org/apache/accumulo/manager/replication/ManagerReplicationCoordinatorTest.java
index 5c5531f..a4dccdf 100644
--- a/server/manager/src/test/java/org/apache/accumulo/manager/replication/ManagerReplicationCoordinatorTest.java
+++ b/server/manager/src/test/java/org/apache/accumulo/manager/replication/ManagerReplicationCoordinatorTest.java
@@ -18,6 +18,10 @@
  */
 package org.apache.accumulo.manager.replication;
 
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThrows;
 
@@ -32,7 +36,6 @@ import org.apache.accumulo.core.util.HostAndPort;
 import org.apache.accumulo.fate.zookeeper.ZooReader;
 import org.apache.accumulo.manager.Manager;
 import org.apache.accumulo.server.ServerContext;
-import org.easymock.EasyMock;
 import org.junit.Test;
 
 @Deprecated
@@ -42,15 +45,16 @@ public class ManagerReplicationCoordinatorTest {
 
   @Test
   public void randomServer() {
-    Manager manager = EasyMock.createMock(Manager.class);
-    ZooReader reader = EasyMock.createMock(ZooReader.class);
-    ServerContext context = EasyMock.createMock(ServerContext.class);
-    EasyMock.expect(context.getConfiguration()).andReturn(config).anyTimes();
-    EasyMock.expect(context.getInstanceID()).andReturn(InstanceId.of("1234")).anyTimes();
-    EasyMock.expect(context.getZooReaderWriter()).andReturn(null).anyTimes();
-    EasyMock.expect(manager.getContext()).andReturn(context);
-    EasyMock.expect(manager.getInstanceID()).andReturn(InstanceId.of("1234"));
-    EasyMock.replay(manager, context, reader);
+    Manager manager = createMock(Manager.class);
+    ZooReader reader = createMock(ZooReader.class);
+    ServerContext context = createMock(ServerContext.class);
+    expect(context.getConfiguration()).andReturn(config).anyTimes();
+    expect(context.getInstanceID()).andReturn(InstanceId.of("1234")).anyTimes();
+    expect(context.getZooReader()).andReturn(null).anyTimes();
+    expect(context.getZooReaderWriter()).andReturn(null).anyTimes();
+    expect(manager.getContext()).andReturn(context);
+    expect(manager.getInstanceID()).andReturn(InstanceId.of("1234"));
+    replay(manager, context, reader);
 
     ManagerReplicationCoordinator coordinator = new ManagerReplicationCoordinator(manager, reader);
     TServerInstance inst1 = new TServerInstance(HostAndPort.fromParts("host1", 1234), "session");
@@ -60,15 +64,16 @@ public class ManagerReplicationCoordinatorTest {
 
   @Test
   public void invalidOffset() {
-    Manager manager = EasyMock.createMock(Manager.class);
-    ServerContext context = EasyMock.createMock(ServerContext.class);
-    EasyMock.expect(context.getConfiguration()).andReturn(config).anyTimes();
-    EasyMock.expect(context.getInstanceID()).andReturn(InstanceId.of("1234")).anyTimes();
-    EasyMock.expect(context.getZooReaderWriter()).andReturn(null).anyTimes();
-    ZooReader reader = EasyMock.createMock(ZooReader.class);
-    EasyMock.expect(manager.getContext()).andReturn(context);
-    EasyMock.expect(manager.getInstanceID()).andReturn(InstanceId.of("1234"));
-    EasyMock.replay(manager, context, reader);
+    Manager manager = createMock(Manager.class);
+    ServerContext context = createMock(ServerContext.class);
+    expect(context.getConfiguration()).andReturn(config).anyTimes();
+    expect(context.getInstanceID()).andReturn(InstanceId.of("1234")).anyTimes();
+    expect(context.getZooReader()).andReturn(null).anyTimes();
+    expect(context.getZooReaderWriter()).andReturn(null).anyTimes();
+    ZooReader reader = createMock(ZooReader.class);
+    expect(manager.getContext()).andReturn(context);
+    expect(manager.getInstanceID()).andReturn(InstanceId.of("1234"));
+    replay(manager, context, reader);
     ManagerReplicationCoordinator coordinator = new ManagerReplicationCoordinator(manager, reader);
     TServerInstance inst1 = new TServerInstance(HostAndPort.fromParts("host1", 1234), "session");
     assertThrows(IllegalArgumentException.class,
@@ -77,19 +82,20 @@ public class ManagerReplicationCoordinatorTest {
 
   @Test
   public void randomServerFromMany() {
-    Manager manager = EasyMock.createMock(Manager.class);
-    ZooReader reader = EasyMock.createMock(ZooReader.class);
-    ServerContext context = EasyMock.createMock(ServerContext.class);
-    EasyMock.expect(context.getConfiguration()).andReturn(config).anyTimes();
-    EasyMock.expect(context.getInstanceID()).andReturn(InstanceId.of("1234")).anyTimes();
-    EasyMock.expect(context.getZooReaderWriter()).andReturn(null).anyTimes();
-    EasyMock.expect(manager.getInstanceID()).andReturn(InstanceId.of("1234")).anyTimes();
-    EasyMock.expect(manager.getContext()).andReturn(context).anyTimes();
-    EasyMock.replay(manager, context, reader);
+    Manager manager = createMock(Manager.class);
+    ZooReader reader = createMock(ZooReader.class);
+    ServerContext context = createMock(ServerContext.class);
+    expect(context.getConfiguration()).andReturn(config).anyTimes();
+    expect(context.getInstanceID()).andReturn(InstanceId.of("1234")).anyTimes();
+    expect(context.getZooReader()).andReturn(null).anyTimes();
+    expect(context.getZooReaderWriter()).andReturn(null).anyTimes();
+    expect(manager.getInstanceID()).andReturn(InstanceId.of("1234")).anyTimes();
+    expect(manager.getContext()).andReturn(context).anyTimes();
+    replay(manager, context, reader);
 
     ManagerReplicationCoordinator coordinator = new ManagerReplicationCoordinator(manager, reader);
 
-    EasyMock.verify(manager, reader);
+    verify(manager, reader);
 
     TreeSet<TServerInstance> instances = new TreeSet<>();
     TServerInstance inst1 = new TServerInstance(HostAndPort.fromParts("host1", 1234), "session");
diff --git a/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java b/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
index 928ba75..c4146c1 100644
--- a/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
+++ b/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
@@ -239,7 +239,7 @@ public class TabletServer extends AbstractServer {
     super("tserver", opts, args);
     context = super.getContext();
     context.setupCrypto();
-    this.managerLockCache = new ZooCache(context.getZooReaderWriter(), null);
+    this.managerLockCache = new ZooCache(context.getZooReader(), null);
     final AccumuloConfiguration aconf = getConfiguration();
     log.info("Version " + Constants.VERSION);
     log.info("Instance " + getInstanceID());
diff --git a/shell/src/main/java/org/apache/accumulo/shell/commands/FateCommand.java b/shell/src/main/java/org/apache/accumulo/shell/commands/FateCommand.java
index 62ad71d..5313145 100644
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/FateCommand.java
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/FateCommand.java
@@ -237,8 +237,7 @@ public class FateCommand extends Command {
       secret = siteConfig.get(Property.INSTANCE_SECRET);
     }
 
-    return new ZooReaderWriter(context.getZooKeepers(), context.getZooKeepersSessionTimeOut(),
-        secret);
+    return context.getZooReader().asWriter(secret);
   }
 
   @Override
diff --git a/test/src/main/java/org/apache/accumulo/test/ExistingMacIT.java b/test/src/main/java/org/apache/accumulo/test/ExistingMacIT.java
index be0e793..a0e0aa0 100644
--- a/test/src/main/java/org/apache/accumulo/test/ExistingMacIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/ExistingMacIT.java
@@ -37,8 +37,6 @@ import org.apache.accumulo.core.client.BatchWriter;
 import org.apache.accumulo.core.client.Scanner;
 import org.apache.accumulo.core.client.security.tokens.PasswordToken;
 import org.apache.accumulo.core.conf.ClientProperty;
-import org.apache.accumulo.core.conf.ConfigurationTypeHelper;
-import org.apache.accumulo.core.conf.DefaultConfiguration;
 import org.apache.accumulo.core.conf.Property;
 import org.apache.accumulo.core.data.Key;
 import org.apache.accumulo.core.data.Mutation;
@@ -114,11 +112,7 @@ public class ExistingMacIT extends ConfigurableMacBase {
         getCluster().killProcess(entry.getKey(), pr);
     }
 
-    final DefaultConfiguration defaultConfig = DefaultConfiguration.getInstance();
-    final long zkTimeout = ConfigurationTypeHelper.getTimeInMillis(
-        getCluster().getConfig().getSiteConfig().get(Property.INSTANCE_ZK_TIMEOUT.getKey()));
-    ZooReaderWriter zrw = new ZooReaderWriter(getCluster().getZooKeepers(), (int) zkTimeout,
-        defaultConfig.get(Property.INSTANCE_SECRET));
+    ZooReaderWriter zrw = getCluster().getServerContext().getZooReaderWriter();
     final String zInstanceRoot =
         Constants.ZROOT + "/" + client.instanceOperations().getInstanceId();
     while (!AccumuloStatus.isAccumuloOffline(zrw, zInstanceRoot)) {
diff --git a/test/src/main/java/org/apache/accumulo/test/TableOperationsIT.java b/test/src/main/java/org/apache/accumulo/test/TableOperationsIT.java
index 884f121..30d5087 100644
--- a/test/src/main/java/org/apache/accumulo/test/TableOperationsIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/TableOperationsIT.java
@@ -50,7 +50,6 @@ import org.apache.accumulo.core.client.TableExistsException;
 import org.apache.accumulo.core.client.TableNotFoundException;
 import org.apache.accumulo.core.client.admin.DiskUsage;
 import org.apache.accumulo.core.client.admin.TableOperations;
-import org.apache.accumulo.core.clientImpl.ClientContext;
 import org.apache.accumulo.core.conf.Property;
 import org.apache.accumulo.core.data.Key;
 import org.apache.accumulo.core.data.Mutation;
@@ -88,9 +87,9 @@ public class TableOperationsIT extends AccumuloClusterHarness {
   @After
   public void checkForDanglingFateLocks() {
     if (getClusterType() == ClusterType.MINI) {
-      FunctionalTestUtils.assertNoDanglingFateLocks((ClientContext) accumuloClient, getCluster());
-      accumuloClient.close();
+      FunctionalTestUtils.assertNoDanglingFateLocks(getCluster());
     }
+    accumuloClient.close();
   }
 
   @Test
diff --git a/test/src/main/java/org/apache/accumulo/test/ThriftServerBindsBeforeZooKeeperLockIT.java b/test/src/main/java/org/apache/accumulo/test/ThriftServerBindsBeforeZooKeeperLockIT.java
index 97ba8b1..a2d3e72 100644
--- a/test/src/main/java/org/apache/accumulo/test/ThriftServerBindsBeforeZooKeeperLockIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/ThriftServerBindsBeforeZooKeeperLockIT.java
@@ -32,7 +32,6 @@ import org.apache.accumulo.core.client.AccumuloClient;
 import org.apache.accumulo.core.conf.Property;
 import org.apache.accumulo.core.data.InstanceId;
 import org.apache.accumulo.core.util.MonitorUtil;
-import org.apache.accumulo.fate.zookeeper.ZooReader;
 import org.apache.accumulo.gc.SimpleGarbageCollector;
 import org.apache.accumulo.harness.AccumuloClusterHarness;
 import org.apache.accumulo.manager.Manager;
@@ -139,10 +138,9 @@ public class ThriftServerBindsBeforeZooKeeperLockIT extends AccumuloClusterHarne
 
       // Wait for the Manager to grab its lock
       while (true) {
-        final ZooReader reader = new ZooReader(cluster.getZooKeepers(), 30000);
         try {
-          List<String> locks =
-              reader.getChildren(Constants.ZROOT + "/" + instanceID + Constants.ZMANAGER_LOCK);
+          List<String> locks = cluster.getServerContext().getZooReader()
+              .getChildren(Constants.ZROOT + "/" + instanceID + Constants.ZMANAGER_LOCK);
           if (!locks.isEmpty()) {
             break;
           }
@@ -199,10 +197,9 @@ public class ThriftServerBindsBeforeZooKeeperLockIT extends AccumuloClusterHarne
 
       // Wait for the Manager to grab its lock
       while (true) {
-        final ZooReader reader = new ZooReader(cluster.getZooKeepers(), 30000);
         try {
-          List<String> locks =
-              reader.getChildren(Constants.ZROOT + "/" + instanceID + Constants.ZGC_LOCK);
+          List<String> locks = cluster.getServerContext().getZooReader()
+              .getChildren(Constants.ZROOT + "/" + instanceID + Constants.ZGC_LOCK);
           if (!locks.isEmpty()) {
             break;
           }
diff --git a/test/src/main/java/org/apache/accumulo/test/UnusedWALIT.java b/test/src/main/java/org/apache/accumulo/test/UnusedWALIT.java
index 8af6075..b319523 100644
--- a/test/src/main/java/org/apache/accumulo/test/UnusedWALIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/UnusedWALIT.java
@@ -29,7 +29,6 @@ import org.apache.accumulo.core.client.AccumuloClient;
 import org.apache.accumulo.core.client.BatchWriter;
 import org.apache.accumulo.core.client.BatchWriterConfig;
 import org.apache.accumulo.core.client.Scanner;
-import org.apache.accumulo.core.clientImpl.ClientInfo;
 import org.apache.accumulo.core.conf.Property;
 import org.apache.accumulo.core.data.Key;
 import org.apache.accumulo.core.data.Mutation;
@@ -38,7 +37,6 @@ import org.apache.accumulo.core.data.Value;
 import org.apache.accumulo.core.metadata.MetadataTable;
 import org.apache.accumulo.core.metadata.TServerInstance;
 import org.apache.accumulo.core.security.Authorizations;
-import org.apache.accumulo.fate.zookeeper.ZooReaderWriter;
 import org.apache.accumulo.minicluster.ServerType;
 import org.apache.accumulo.miniclusterImpl.MiniAccumuloConfigImpl;
 import org.apache.accumulo.server.ServerContext;
@@ -86,8 +84,6 @@ public class UnusedWALIT extends ConfigurableMacBase {
       c.tableOperations().create(lilTable);
 
       ServerContext context = getServerContext();
-      ClientInfo info = ClientInfo.from(getClientProperties());
-      new ZooReaderWriter(info.getZooKeepers(), info.getZooKeepersSessionTimeOut(), "");
 
       // put some data in a log that should be replayed for both tables
       writeSomeData(c, bigTable, 0, 10, 0, 10);
diff --git a/test/src/main/java/org/apache/accumulo/test/compaction/UserCompactionStrategyIT.java b/test/src/main/java/org/apache/accumulo/test/compaction/UserCompactionStrategyIT.java
index cccd752..cd85e4f 100644
--- a/test/src/main/java/org/apache/accumulo/test/compaction/UserCompactionStrategyIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/compaction/UserCompactionStrategyIT.java
@@ -19,7 +19,6 @@
 package org.apache.accumulo.test.compaction;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeTrue;
@@ -44,7 +43,6 @@ import org.apache.accumulo.core.client.TableNotFoundException;
 import org.apache.accumulo.core.client.admin.CompactionConfig;
 import org.apache.accumulo.core.client.admin.CompactionStrategyConfig;
 import org.apache.accumulo.core.client.admin.NewTableConfiguration;
-import org.apache.accumulo.core.clientImpl.ClientContext;
 import org.apache.accumulo.core.conf.Property;
 import org.apache.accumulo.core.data.Key;
 import org.apache.accumulo.core.data.Mutation;
@@ -69,10 +67,7 @@ public class UserCompactionStrategyIT extends AccumuloClusterHarness {
   @After
   public void checkForDanglingFateLocks() {
     if (getClusterType() == ClusterType.MINI) {
-      try (AccumuloClient c = Accumulo.newClient().from(getClientProps()).build()) {
-        assertNotNull(c);
-        FunctionalTestUtils.assertNoDanglingFateLocks((ClientContext) c, getCluster());
-      }
+      FunctionalTestUtils.assertNoDanglingFateLocks(getCluster());
     }
   }
 
diff --git a/test/src/main/java/org/apache/accumulo/test/fate/zookeeper/FateIT.java b/test/src/main/java/org/apache/accumulo/test/fate/zookeeper/FateIT.java
index 9323bfb..d56e1e5 100644
--- a/test/src/main/java/org/apache/accumulo/test/fate/zookeeper/FateIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/fate/zookeeper/FateIT.java
@@ -116,7 +116,7 @@ public class FateIT {
 
   @Test(timeout = 30000)
   public void testTransactionStatus() throws Exception {
-    ZooReaderWriter zk = new ZooReaderWriter(szk.getConn(), 30000, "secret");
+    ZooReaderWriter zk = szk.getZooReaderWriter();
 
     zk.mkdirs(ZK_ROOT + Constants.ZFATE);
     zk.mkdirs(ZK_ROOT + Constants.ZTABLE_LOCKS);
diff --git a/test/src/main/java/org/apache/accumulo/test/fate/zookeeper/ServiceLockIT.java b/test/src/main/java/org/apache/accumulo/test/fate/zookeeper/ServiceLockIT.java
index 866d270..b69b9ee 100644
--- a/test/src/main/java/org/apache/accumulo/test/fate/zookeeper/ServiceLockIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/fate/zookeeper/ServiceLockIT.java
@@ -217,7 +217,7 @@ public class ServiceLockIT {
 
     assertFalse(zl.isLocked());
 
-    ZooReaderWriter zk = new ZooReaderWriter(szk.getConn(), 30000, "secret");
+    ZooReaderWriter zk = szk.getZooReaderWriter();
 
     // intentionally created parent after lock
     zk.mkdirs(parent.toString());
@@ -266,7 +266,7 @@ public class ServiceLockIT {
     var parent =
         ServiceLock.path("/zltestDeleteLock-" + this.hashCode() + "-l" + pdCount.incrementAndGet());
 
-    ZooReaderWriter zk = new ZooReaderWriter(szk.getConn(), 30000, "secret");
+    ZooReaderWriter zk = szk.getZooReaderWriter();
     zk.mkdirs(parent.toString());
 
     ServiceLock zl = getZooLock(parent, UUID.randomUUID());
@@ -298,7 +298,7 @@ public class ServiceLockIT {
     var parent = ServiceLock
         .path("/zltestDeleteWaiting-" + this.hashCode() + "-l" + pdCount.incrementAndGet());
 
-    ZooReaderWriter zk = new ZooReaderWriter(szk.getConn(), 30000, "secret");
+    ZooReaderWriter zk = szk.getZooReaderWriter();
     zk.mkdirs(parent.toString());
 
     ServiceLock zl = getZooLock(parent, UUID.randomUUID());
diff --git a/test/src/main/java/org/apache/accumulo/test/fate/zookeeper/ZooMutatorIT.java b/test/src/main/java/org/apache/accumulo/test/fate/zookeeper/ZooMutatorIT.java
index 9505bd2..a70807c 100644
--- a/test/src/main/java/org/apache/accumulo/test/fate/zookeeper/ZooMutatorIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/fate/zookeeper/ZooMutatorIT.java
@@ -85,7 +85,7 @@ public class ZooMutatorIT {
 
     try (ZooKeeperTestingServer szk = new ZooKeeperTestingServer(tempFolder.newFolder())) {
       szk.initPaths("/accumulo/" + InstanceId.of(UUID.randomUUID()));
-      ZooReaderWriter zk = new ZooReaderWriter(szk.getConn(), 10_0000, "aPasswd");
+      ZooReaderWriter zk = szk.getZooReaderWriter();
 
       var executor = Executors.newFixedThreadPool(16);
 
diff --git a/test/src/main/java/org/apache/accumulo/test/functional/BackupManagerIT.java b/test/src/main/java/org/apache/accumulo/test/functional/BackupManagerIT.java
index bad2777..d510ca0 100644
--- a/test/src/main/java/org/apache/accumulo/test/functional/BackupManagerIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/functional/BackupManagerIT.java
@@ -23,7 +23,6 @@ import java.util.List;
 import org.apache.accumulo.core.Constants;
 import org.apache.accumulo.core.client.Accumulo;
 import org.apache.accumulo.core.client.AccumuloClient;
-import org.apache.accumulo.core.conf.Property;
 import org.apache.accumulo.fate.util.UtilWaitThread;
 import org.apache.accumulo.fate.zookeeper.ServiceLock;
 import org.apache.accumulo.fate.zookeeper.ZooReaderWriter;
@@ -45,8 +44,7 @@ public class BackupManagerIT extends ConfigurableMacBase {
     // create a backup
     Process backup = exec(Manager.class);
     try (AccumuloClient client = Accumulo.newClient().from(getClientProperties()).build()) {
-      String secret = getCluster().getSiteConfiguration().get(Property.INSTANCE_SECRET);
-      ZooReaderWriter writer = new ZooReaderWriter(cluster.getZooKeepers(), 30_000, secret);
+      ZooReaderWriter writer = getCluster().getServerContext().getZooReaderWriter();
       String root = "/accumulo/" + client.instanceOperations().getInstanceId();
       List<String> children;
       // wait for 2 lock entries
diff --git a/test/src/main/java/org/apache/accumulo/test/functional/ConcurrentDeleteTableIT.java b/test/src/main/java/org/apache/accumulo/test/functional/ConcurrentDeleteTableIT.java
index 6ad139a..41e6f41 100644
--- a/test/src/main/java/org/apache/accumulo/test/functional/ConcurrentDeleteTableIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/functional/ConcurrentDeleteTableIT.java
@@ -42,7 +42,6 @@ import org.apache.accumulo.core.client.TableNotFoundException;
 import org.apache.accumulo.core.client.TableOfflineException;
 import org.apache.accumulo.core.client.admin.CompactionConfig;
 import org.apache.accumulo.core.client.admin.NewTableConfiguration;
-import org.apache.accumulo.core.clientImpl.ClientContext;
 import org.apache.accumulo.core.clientImpl.TableOperationsImpl;
 import org.apache.accumulo.core.clientImpl.thrift.ThriftTableOperationException;
 import org.apache.accumulo.core.data.Mutation;
@@ -108,7 +107,7 @@ public class ConcurrentDeleteTableIT extends AccumuloClusterHarness {
         assertThrows("Expected table " + table + " to be gone.", TableNotFoundException.class,
             () -> c.createScanner(table, Authorizations.EMPTY));
 
-        FunctionalTestUtils.assertNoDanglingFateLocks((ClientContext) c, getCluster());
+        FunctionalTestUtils.assertNoDanglingFateLocks(getCluster());
       }
 
       es.shutdown();
@@ -212,7 +211,7 @@ public class ConcurrentDeleteTableIT extends AccumuloClusterHarness {
         assertThrows("Expected table " + table + " to be gone.", TableNotFoundException.class,
             () -> c.createScanner(table, Authorizations.EMPTY));
 
-        FunctionalTestUtils.assertNoDanglingFateLocks((ClientContext) c, getCluster());
+        FunctionalTestUtils.assertNoDanglingFateLocks(getCluster());
       }
 
       es.shutdown();
diff --git a/test/src/main/java/org/apache/accumulo/test/functional/FateConcurrencyIT.java b/test/src/main/java/org/apache/accumulo/test/functional/FateConcurrencyIT.java
index 6853a62..8cdf1e1 100644
--- a/test/src/main/java/org/apache/accumulo/test/functional/FateConcurrencyIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/functional/FateConcurrencyIT.java
@@ -250,8 +250,7 @@ public class FateConcurrencyIT extends AccumuloClusterHarness {
       try {
 
         InstanceId instanceId = context.getInstanceID();
-        ZooReaderWriter zk = new ZooReaderWriter(context.getZooKeepers(),
-            context.getZooKeepersSessionTimeOut(), secret);
+        ZooReaderWriter zk = context.getZooReader().asWriter(secret);
         ZooStore<String> zs = new ZooStore<>(ZooUtil.getRoot(instanceId) + Constants.ZFATE, zk);
 
         withLocks = admin.getStatus(zs, zk,
@@ -342,8 +341,7 @@ public class FateConcurrencyIT extends AccumuloClusterHarness {
       log.trace("tid: {}", tableId);
 
       InstanceId instanceId = context.getInstanceID();
-      ZooReaderWriter zk = new ZooReaderWriter(context.getZooKeepers(),
-          context.getZooKeepersSessionTimeOut(), secret);
+      ZooReaderWriter zk = context.getZooReader().asWriter(secret);
       ZooStore<String> zs = new ZooStore<>(ZooUtil.getRoot(instanceId) + Constants.ZFATE, zk);
       AdminUtil.FateStatus fateStatus = admin.getStatus(zs, zk,
           ZooUtil.getRoot(instanceId) + Constants.ZTABLE_LOCKS + "/" + tableId, null, null);
diff --git a/test/src/main/java/org/apache/accumulo/test/functional/FateStarvationIT.java b/test/src/main/java/org/apache/accumulo/test/functional/FateStarvationIT.java
index 83675d8..350af80 100644
--- a/test/src/main/java/org/apache/accumulo/test/functional/FateStarvationIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/functional/FateStarvationIT.java
@@ -24,7 +24,6 @@ import java.util.List;
 import org.apache.accumulo.core.client.Accumulo;
 import org.apache.accumulo.core.client.AccumuloClient;
 import org.apache.accumulo.core.client.admin.NewTableConfiguration;
-import org.apache.accumulo.core.clientImpl.ClientContext;
 import org.apache.accumulo.harness.AccumuloClusterHarness;
 import org.apache.accumulo.test.TestIngest;
 import org.apache.accumulo.test.TestIngest.IngestParams;
@@ -68,7 +67,7 @@ public class FateStarvationIT extends AccumuloClusterHarness {
 
       c.tableOperations().offline(tableName);
 
-      FunctionalTestUtils.assertNoDanglingFateLocks((ClientContext) c, getCluster());
+      FunctionalTestUtils.assertNoDanglingFateLocks(getCluster());
     }
   }
 }
diff --git a/test/src/main/java/org/apache/accumulo/test/functional/FunctionalTestUtils.java b/test/src/main/java/org/apache/accumulo/test/functional/FunctionalTestUtils.java
index e73ee1e..95e9926 100644
--- a/test/src/main/java/org/apache/accumulo/test/functional/FunctionalTestUtils.java
+++ b/test/src/main/java/org/apache/accumulo/test/functional/FunctionalTestUtils.java
@@ -50,7 +50,6 @@ import org.apache.accumulo.core.Constants;
 import org.apache.accumulo.core.client.AccumuloClient;
 import org.apache.accumulo.core.client.Scanner;
 import org.apache.accumulo.core.clientImpl.ClientContext;
-import org.apache.accumulo.core.conf.Property;
 import org.apache.accumulo.core.data.Key;
 import org.apache.accumulo.core.data.Mutation;
 import org.apache.accumulo.core.data.Range;
@@ -67,6 +66,7 @@ import org.apache.accumulo.fate.AdminUtil;
 import org.apache.accumulo.fate.AdminUtil.FateStatus;
 import org.apache.accumulo.fate.ZooStore;
 import org.apache.accumulo.fate.zookeeper.ZooReaderWriter;
+import org.apache.accumulo.server.ServerContext;
 import org.apache.accumulo.test.TestIngest;
 import org.apache.commons.io.IOUtils;
 import org.apache.hadoop.fs.FileSystem;
@@ -201,20 +201,19 @@ public class FunctionalTestUtils {
     return result;
   }
 
-  public static void assertNoDanglingFateLocks(ClientContext context, AccumuloCluster cluster) {
-    FateStatus fateStatus = getFateStatus(context, cluster);
+  public static void assertNoDanglingFateLocks(AccumuloCluster cluster) {
+    FateStatus fateStatus = getFateStatus(cluster);
     assertEquals("Dangling FATE locks : " + fateStatus.getDanglingHeldLocks(), 0,
         fateStatus.getDanglingHeldLocks().size());
     assertEquals("Dangling FATE locks : " + fateStatus.getDanglingWaitingLocks(), 0,
         fateStatus.getDanglingWaitingLocks().size());
   }
 
-  private static FateStatus getFateStatus(ClientContext context, AccumuloCluster cluster) {
+  private static FateStatus getFateStatus(AccumuloCluster cluster) {
     try {
       AdminUtil<String> admin = new AdminUtil<>(false);
-      String secret = cluster.getSiteConfiguration().get(Property.INSTANCE_SECRET);
-      ZooReaderWriter zk = new ZooReaderWriter(context.getZooKeepers(),
-          context.getZooKeepersSessionTimeOut(), secret);
+      ServerContext context = cluster.getServerContext();
+      ZooReaderWriter zk = context.getZooReaderWriter();
       ZooStore<String> zs = new ZooStore<>(context.getZooKeeperRoot() + Constants.ZFATE, zk);
       return admin.getStatus(zs, zk, context.getZooKeeperRoot() + Constants.ZTABLE_LOCKS, null,
           null);
diff --git a/test/src/main/java/org/apache/accumulo/test/functional/GarbageCollectorIT.java b/test/src/main/java/org/apache/accumulo/test/functional/GarbageCollectorIT.java
index 60b514a..a2ea64a 100644
--- a/test/src/main/java/org/apache/accumulo/test/functional/GarbageCollectorIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/functional/GarbageCollectorIT.java
@@ -104,7 +104,7 @@ public class GarbageCollectorIT extends ConfigurableMacBase {
         getCluster().getProcesses().get(ServerType.GARBAGE_COLLECTOR).iterator().next());
     // delete lock in zookeeper if there, this will allow next GC to start quickly
     var path = ServiceLock.path(getServerContext().getZooKeeperRoot() + Constants.ZGC_LOCK);
-    ZooReaderWriter zk = new ZooReaderWriter(cluster.getZooKeepers(), 30000, OUR_SECRET);
+    ZooReaderWriter zk = getServerContext().getZooReaderWriter();
     try {
       ServiceLock.deleteLock(zk, path);
     } catch (IllegalStateException e) {
@@ -258,7 +258,7 @@ public class GarbageCollectorIT extends ConfigurableMacBase {
 
     try (AccumuloClient client = Accumulo.newClient().from(getClientProperties()).build()) {
 
-      ZooReaderWriter zk = new ZooReaderWriter(cluster.getZooKeepers(), 30000, OUR_SECRET);
+      ZooReaderWriter zk = cluster.getServerContext().getZooReaderWriter();
       var path = ServiceLock
           .path(ZooUtil.getRoot(client.instanceOperations().getInstanceId()) + Constants.ZGC_LOCK);
       for (int i = 0; i < 5; i++) {
diff --git a/test/src/main/java/org/apache/accumulo/test/functional/ReadWriteIT.java b/test/src/main/java/org/apache/accumulo/test/functional/ReadWriteIT.java
index 9a5bad1..bfe555b 100644
--- a/test/src/main/java/org/apache/accumulo/test/functional/ReadWriteIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/functional/ReadWriteIT.java
@@ -75,7 +75,6 @@ import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.core.util.MonitorUtil;
 import org.apache.accumulo.fate.zookeeper.ServiceLock;
 import org.apache.accumulo.fate.zookeeper.ZooCache;
-import org.apache.accumulo.fate.zookeeper.ZooReader;
 import org.apache.accumulo.fate.zookeeper.ZooUtil;
 import org.apache.accumulo.harness.AccumuloClusterHarness;
 import org.apache.accumulo.minicluster.ServerType;
@@ -119,9 +118,8 @@ public class ReadWriteIT extends AccumuloClusterHarness {
 
   @Test
   public void invalidInstanceName() {
-    try (AccumuloClient client =
-        Accumulo.newClient().to("fake_instance_name", cluster.getZooKeepers())
-            .as(getAdminPrincipal(), getAdminToken()).build()) {
+    try (var client = Accumulo.newClient().to("fake_instance_name", cluster.getZooKeepers())
+        .as(getAdminPrincipal(), getAdminToken()).build()) {
       assertThrows(RuntimeException.class, () -> client.instanceOperations().getTabletServers());
     }
   }
@@ -167,9 +165,7 @@ public class ReadWriteIT extends AccumuloClusterHarness {
       log.debug("Stopping accumulo cluster");
       ClusterControl control = cluster.getClusterControl();
       control.adminStopAll();
-      ClientInfo info = ClientInfo.from(accumuloClient.properties());
-      ZooReader zreader = new ZooReader(info.getZooKeepers(), info.getZooKeepersSessionTimeOut());
-      ZooCache zcache = new ZooCache(zreader, null);
+      ZooCache zcache = cluster.getServerContext().getZooCache();
       var zLockPath =
           ServiceLock.path(ZooUtil.getRoot(accumuloClient.instanceOperations().getInstanceId())
               + Constants.ZMANAGER_LOCK);
diff --git a/test/src/main/java/org/apache/accumulo/test/functional/RenameIT.java b/test/src/main/java/org/apache/accumulo/test/functional/RenameIT.java
index e8bd622..0d8fba6 100644
--- a/test/src/main/java/org/apache/accumulo/test/functional/RenameIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/functional/RenameIT.java
@@ -20,7 +20,6 @@ package org.apache.accumulo.test.functional;
 
 import org.apache.accumulo.core.client.Accumulo;
 import org.apache.accumulo.core.client.AccumuloClient;
-import org.apache.accumulo.core.clientImpl.ClientContext;
 import org.apache.accumulo.harness.AccumuloClusterHarness;
 import org.apache.accumulo.test.TestIngest;
 import org.apache.accumulo.test.VerifyIngest;
@@ -52,7 +51,7 @@ public class RenameIT extends AccumuloClusterHarness {
       c.tableOperations().rename(name2, name1);
       params.tableName = name1;
       VerifyIngest.verifyIngest(c, params);
-      FunctionalTestUtils.assertNoDanglingFateLocks((ClientContext) c, getCluster());
+      FunctionalTestUtils.assertNoDanglingFateLocks(getCluster());
     }
   }
 }
diff --git a/test/src/main/java/org/apache/accumulo/test/functional/RestartIT.java b/test/src/main/java/org/apache/accumulo/test/functional/RestartIT.java
index 30ac634..9474b0c 100644
--- a/test/src/main/java/org/apache/accumulo/test/functional/RestartIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/functional/RestartIT.java
@@ -33,13 +33,11 @@ import org.apache.accumulo.cluster.ClusterControl;
 import org.apache.accumulo.core.Constants;
 import org.apache.accumulo.core.client.Accumulo;
 import org.apache.accumulo.core.client.AccumuloClient;
-import org.apache.accumulo.core.clientImpl.ClientInfo;
 import org.apache.accumulo.core.conf.ClientProperty;
 import org.apache.accumulo.core.conf.Property;
 import org.apache.accumulo.core.metadata.MetadataTable;
 import org.apache.accumulo.fate.zookeeper.ServiceLock;
 import org.apache.accumulo.fate.zookeeper.ZooCache;
-import org.apache.accumulo.fate.zookeeper.ZooReader;
 import org.apache.accumulo.fate.zookeeper.ZooUtil;
 import org.apache.accumulo.harness.AccumuloClusterHarness;
 import org.apache.accumulo.minicluster.ServerType;
@@ -137,9 +135,7 @@ public class RestartIT extends AccumuloClusterHarness {
       control.stopAllServers(ServerType.GARBAGE_COLLECTOR);
       control.stopAllServers(ServerType.MONITOR);
 
-      ClientInfo info = ClientInfo.from(c.properties());
-      ZooReader zreader = new ZooReader(info.getZooKeepers(), info.getZooKeepersSessionTimeOut());
-      ZooCache zcache = new ZooCache(zreader, null);
+      ZooCache zcache = cluster.getServerContext().getZooCache();
       var zLockPath = ServiceLock
           .path(ZooUtil.getRoot(c.instanceOperations().getInstanceId()) + Constants.ZMANAGER_LOCK);
       byte[] managerLockData;
@@ -190,9 +186,7 @@ public class RestartIT extends AccumuloClusterHarness {
 
       control.stopAllServers(ServerType.MANAGER);
 
-      ClientInfo info = ClientInfo.from(c.properties());
-      ZooReader zreader = new ZooReader(info.getZooKeepers(), info.getZooKeepersSessionTimeOut());
-      ZooCache zcache = new ZooCache(zreader, null);
+      ZooCache zcache = cluster.getServerContext().getZooCache();
       var zLockPath = ServiceLock
           .path(ZooUtil.getRoot(c.instanceOperations().getInstanceId()) + Constants.ZMANAGER_LOCK);
       byte[] managerLockData;
diff --git a/test/src/main/java/org/apache/accumulo/test/replication/MultiTserverReplicationIT.java b/test/src/main/java/org/apache/accumulo/test/replication/MultiTserverReplicationIT.java
index f616e66..3baea9b 100644
--- a/test/src/main/java/org/apache/accumulo/test/replication/MultiTserverReplicationIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/replication/MultiTserverReplicationIT.java
@@ -70,8 +70,7 @@ public class MultiTserverReplicationIT extends ConfigurableMacBase {
     try (Scanner s = client.createScanner("foo", Authorizations.EMPTY)) {
       assertEquals(0, Iterables.size(s));
 
-      ZooReader zreader =
-          new ZooReader(context.getZooKeepers(), context.getZooKeepersSessionTimeOut());
+      ZooReader zreader = context.getZooReader();
       Set<String> tserverHost = new HashSet<>();
       tserverHost.addAll(zreader.getChildren(
           ZooUtil.getRoot(client.instanceOperations().getInstanceId()) + Constants.ZTSERVERS));
@@ -108,8 +107,7 @@ public class MultiTserverReplicationIT extends ConfigurableMacBase {
     try (Scanner s = client.createScanner("foo", Authorizations.EMPTY)) {
       assertEquals(0, Iterables.size(s));
 
-      ZooReader zreader =
-          new ZooReader(context.getZooKeepers(), context.getZooKeepersSessionTimeOut());
+      ZooReader zreader = context.getZooReader();
 
       // Should have one manager instance
       assertEquals(1, context.getManagerLocations().size());
diff --git a/test/src/main/java/org/apache/accumulo/test/upgrade/GCUpgrade9to10TestIT.java b/test/src/main/java/org/apache/accumulo/test/upgrade/GCUpgrade9to10TestIT.java
index 66e5718..46584e4 100644
--- a/test/src/main/java/org/apache/accumulo/test/upgrade/GCUpgrade9to10TestIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/upgrade/GCUpgrade9to10TestIT.java
@@ -84,7 +84,7 @@ public class GCUpgrade9to10TestIT extends ConfigurableMacBase {
         getCluster().getProcesses().get(ServerType.GARBAGE_COLLECTOR).iterator().next());
     // delete lock in zookeeper if there, this will allow next GC to start quickly
     var path = ServiceLock.path(getServerContext().getZooKeeperRoot() + Constants.ZGC_LOCK);
-    ZooReaderWriter zk = new ZooReaderWriter(cluster.getZooKeepers(), 30000, OUR_SECRET);
+    ZooReaderWriter zk = getServerContext().getZooReaderWriter();
     try {
       ServiceLock.deleteLock(zk, path);
     } catch (IllegalStateException e) {
diff --git a/test/src/main/java/org/apache/accumulo/test/zookeeper/ZooKeeperTestingServer.java b/test/src/main/java/org/apache/accumulo/test/zookeeper/ZooKeeperTestingServer.java
index f7c923d..5a7cf57 100644
--- a/test/src/main/java/org/apache/accumulo/test/zookeeper/ZooKeeperTestingServer.java
+++ b/test/src/main/java/org/apache/accumulo/test/zookeeper/ZooKeeperTestingServer.java
@@ -22,6 +22,8 @@ import java.io.File;
 import java.io.IOException;
 import java.util.concurrent.CountDownLatch;
 
+import org.apache.accumulo.fate.zookeeper.ZooReader;
+import org.apache.accumulo.fate.zookeeper.ZooReaderWriter;
 import org.apache.accumulo.server.util.PortUtils;
 import org.apache.curator.test.TestingServer;
 import org.apache.zookeeper.CreateMode;
@@ -98,6 +100,10 @@ public class ZooKeeperTestingServer implements AutoCloseable {
     return zoo;
   }
 
+  public ZooReaderWriter getZooReaderWriter() {
+    return new ZooReader(getConn(), 30000).asWriter("secret");
+  }
+
   public String getConn() {
     return zkServer.getConnectString();
   }