Search in sources :

Example 11 with ServiceLock

use of org.apache.accumulo.fate.zookeeper.ServiceLock in project accumulo by apache.

the class TabletServer method announceExistence.

private void announceExistence() {
    ZooReaderWriter zoo = getContext().getZooReaderWriter();
    try {
        var zLockPath = ServiceLock.path(getContext().getZooKeeperRoot() + Constants.ZTSERVERS + "/" + getClientAddressString());
        try {
            zoo.putPersistentData(zLockPath.toString(), new byte[] {}, NodeExistsPolicy.SKIP);
        } catch (KeeperException e) {
            if (e.code() == KeeperException.Code.NOAUTH) {
                log.error("Failed to write to ZooKeeper. Ensure that" + " accumulo.properties, specifically instance.secret, is consistent.");
            }
            throw e;
        }
        tabletServerLock = new ServiceLock(zoo.getZooKeeper(), zLockPath, UUID.randomUUID());
        LockWatcher lw = new LockWatcher() {

            @Override
            public void lostLock(final LockLossReason reason) {
                Halt.halt(serverStopRequested ? 0 : 1, () -> {
                    if (!serverStopRequested) {
                        log.error("Lost tablet server lock (reason = {}), exiting.", reason);
                    }
                    gcLogger.logGCInfo(getConfiguration());
                });
            }

            @Override
            public void unableToMonitorLockNode(final Exception e) {
                Halt.halt(1, () -> log.error("Lost ability to monitor tablet server lock, exiting.", e));
            }
        };
        byte[] lockContent = new ServerServices(getClientAddressString(), Service.TSERV_CLIENT).toString().getBytes(UTF_8);
        for (int i = 0; i < 120 / 5; i++) {
            zoo.putPersistentData(zLockPath.toString(), new byte[0], NodeExistsPolicy.SKIP);
            if (tabletServerLock.tryLock(lw, lockContent)) {
                log.debug("Obtained tablet server lock {}", tabletServerLock.getLockPath());
                lockID = tabletServerLock.getLockID().serialize(getContext().getZooKeeperRoot() + Constants.ZTSERVERS + "/");
                return;
            }
            log.info("Waiting for tablet server lock");
            sleepUninterruptibly(5, TimeUnit.SECONDS);
        }
        String msg = "Too many retries, exiting.";
        log.info(msg);
        throw new RuntimeException(msg);
    } catch (Exception e) {
        log.info("Could not obtain tablet server lock, exiting.", e);
        throw new RuntimeException(e);
    }
}
Also used : ServerServices(org.apache.accumulo.core.util.ServerServices) ServiceLock(org.apache.accumulo.fate.zookeeper.ServiceLock) LockWatcher(org.apache.accumulo.fate.zookeeper.ServiceLock.LockWatcher) ZooReaderWriter(org.apache.accumulo.fate.zookeeper.ZooReaderWriter) LockLossReason(org.apache.accumulo.fate.zookeeper.ServiceLock.LockLossReason) KeeperException(org.apache.zookeeper.KeeperException) WalMarkerException(org.apache.accumulo.server.log.WalStateManager.WalMarkerException) TException(org.apache.thrift.TException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) KeeperException(org.apache.zookeeper.KeeperException)

Example 12 with ServiceLock

use of org.apache.accumulo.fate.zookeeper.ServiceLock in project accumulo by apache.

the class Monitor method getMonitorLock.

/**
 * Get the monitor lock in ZooKeeper
 */
private void getMonitorLock() throws KeeperException, InterruptedException {
    ServerContext context = getContext();
    final String zRoot = context.getZooKeeperRoot();
    final String monitorPath = zRoot + Constants.ZMONITOR;
    final var monitorLockPath = ServiceLock.path(zRoot + Constants.ZMONITOR_LOCK);
    // Ensure that everything is kosher with ZK as this has changed.
    ZooReaderWriter zoo = context.getZooReaderWriter();
    if (zoo.exists(monitorPath)) {
        byte[] data = zoo.getData(monitorPath);
        // If the node isn't empty, it's from a previous install (has hostname:port for HTTP server)
        if (data.length != 0) {
            // Recursively delete from that parent node
            zoo.recursiveDelete(monitorPath, NodeMissingPolicy.SKIP);
            // And then make the nodes that we expect for the incoming ephemeral nodes
            zoo.putPersistentData(monitorPath, new byte[0], NodeExistsPolicy.FAIL);
            zoo.putPersistentData(monitorLockPath.toString(), new byte[0], NodeExistsPolicy.FAIL);
        } else if (!zoo.exists(monitorLockPath.toString())) {
            // monitor node in ZK exists and is empty as we expect
            // but the monitor/lock node does not
            zoo.putPersistentData(monitorLockPath.toString(), new byte[0], NodeExistsPolicy.FAIL);
        }
    } else {
        // 1.5.0 and earlier
        zoo.putPersistentData(zRoot + Constants.ZMONITOR, new byte[0], NodeExistsPolicy.FAIL);
        if (!zoo.exists(monitorLockPath.toString())) {
            // Somehow the monitor node exists but not monitor/lock
            zoo.putPersistentData(monitorLockPath.toString(), new byte[0], NodeExistsPolicy.FAIL);
        }
    }
    // Get a ZooLock for the monitor
    UUID zooLockUUID = UUID.randomUUID();
    while (true) {
        MoniterLockWatcher monitorLockWatcher = new MoniterLockWatcher();
        monitorLock = new ServiceLock(zoo.getZooKeeper(), monitorLockPath, zooLockUUID);
        monitorLock.lock(monitorLockWatcher, new byte[0]);
        monitorLockWatcher.waitForChange();
        if (monitorLockWatcher.acquiredLock) {
            break;
        }
        if (!monitorLockWatcher.failedToAcquireLock) {
            throw new IllegalStateException("monitor lock in unknown state");
        }
        monitorLock.tryToCancelAsyncLockOrUnlock();
        sleepUninterruptibly(context.getConfiguration().getTimeInMillis(Property.MONITOR_LOCK_CHECK_INTERVAL), TimeUnit.MILLISECONDS);
    }
    log.info("Got Monitor lock.");
}
Also used : ServerContext(org.apache.accumulo.server.ServerContext) ServiceLock(org.apache.accumulo.fate.zookeeper.ServiceLock) ZooReaderWriter(org.apache.accumulo.fate.zookeeper.ZooReaderWriter) UUID(java.util.UUID)

Example 13 with ServiceLock

use of org.apache.accumulo.fate.zookeeper.ServiceLock in project accumulo by apache.

the class ServiceLockIT method testTryLock.

@Test(timeout = 10000)
public void testTryLock() throws Exception {
    var parent = ServiceLock.path("/zltestTryLock-" + this.hashCode() + "-l" + pdCount.incrementAndGet());
    ServiceLock zl = getZooLock(parent, UUID.randomUUID());
    ConnectedWatcher watcher = new ConnectedWatcher();
    try (ZooKeeper zk = new ZooKeeper(szk.getConn(), 30000, watcher)) {
        ZooUtil.digestAuth(zk, "secret");
        while (!watcher.isConnected()) {
            Thread.sleep(200);
        }
        for (int i = 0; i < 10; i++) {
            zk.create(parent.toString(), new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            zk.delete(parent.toString(), -1);
        }
        zk.create(parent.toString(), new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        TestALW lw = new TestALW();
        boolean ret = zl.tryLock(lw, "test1".getBytes(UTF_8));
        assertTrue(ret);
        // make sure still watching parent even though a lot of events occurred for the parent
        synchronized (zl) {
            Field field = zl.getClass().getDeclaredField("watchingParent");
            field.setAccessible(true);
            assertTrue((Boolean) field.get(zl));
        }
        zl.unlock();
    }
}
Also used : Field(java.lang.reflect.Field) ZooKeeper(org.apache.zookeeper.ZooKeeper) ServiceLock(org.apache.accumulo.fate.zookeeper.ServiceLock) Test(org.junit.Test)

Example 14 with ServiceLock

use of org.apache.accumulo.fate.zookeeper.ServiceLock in project accumulo by apache.

the class ServiceLockIT method testLockSerial.

@Test(timeout = 60000)
public void testLockSerial() throws Exception {
    var parent = ServiceLock.path("/zlretryLockSerial");
    ConnectedWatcher watcher1 = new ConnectedWatcher();
    ConnectedWatcher watcher2 = new ConnectedWatcher();
    try (ZooKeeperWrapper zk1 = new ZooKeeperWrapper(szk.getConn(), 30000, watcher1);
        ZooKeeperWrapper zk2 = new ZooKeeperWrapper(szk.getConn(), 30000, watcher2)) {
        ZooUtil.digestAuth(zk1, "secret");
        ZooUtil.digestAuth(zk2, "secret");
        while (!watcher1.isConnected()) {
            Thread.sleep(200);
        }
        while (!watcher2.isConnected()) {
            Thread.sleep(200);
        }
        // Create the parent node
        zk1.createOnce(parent.toString(), new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        final RetryLockWatcher zlw1 = new RetryLockWatcher();
        ServiceLock zl1 = getZooLock(zk1, parent, UUID.fromString("00000000-0000-0000-0000-aaaaaaaaaaaa"));
        zl1.lock(zlw1, "test1".getBytes(UTF_8));
        // The call above creates two nodes in ZK because of the overridden create method in
        // ZooKeeperWrapper.
        // The nodes created are:
        // zlock#00000000-0000-0000-0000-aaaaaaaaaaaa#0000000000
        // zlock#00000000-0000-0000-0000-aaaaaaaaaaaa#0000000001
        // 
        // ZooLock should realize this and remove the latter one and place a watcher on the first one
        // in case the ZooKeeper ephemeral node is deleted by some external process.
        // Lastly, because zlock#00000000-0000-0000-0000-aaaaaaaaaaaa#0000000000 is the first child,
        // zl1 assumes that it has the lock.
        final RetryLockWatcher zlw2 = new RetryLockWatcher();
        ServiceLock zl2 = getZooLock(zk2, parent, UUID.fromString("00000000-0000-0000-0000-bbbbbbbbbbbb"));
        zl2.lock(zlw2, "test1".getBytes(UTF_8));
        // The call above creates two nodes in ZK because of the overridden create method in
        // ZooKeeperWrapper.
        // The nodes created are:
        // zlock#00000000-0000-0000-0000-bbbbbbbbbbbb#0000000002
        // zlock#00000000-0000-0000-0000-bbbbbbbbbbbb#0000000003
        // 
        // ZooLock should realize this and remove the latter one and place a watcher on the first one
        // in case
        // the ZooKeeper ephemeral node is deleted by some external process.
        // Because zlock#00000000-0000-0000-0000-bbbbbbbbbbbb#0000000002 is not the first child in the
        // list, it places a watcher on zlock#00000000-0000-0000-0000-aaaaaaaaaaaa#0000000000
        // so that it may try to acquire the lock when
        // zlock#00000000-0000-0000-0000-aaaaaaaaaaaa#0000000000 is removed.
        assertTrue(zlw1.isLockHeld());
        assertFalse(zlw2.isLockHeld());
        List<String> children = zk1.getChildren(parent.toString(), false);
        assertTrue(children.contains("zlock#00000000-0000-0000-0000-aaaaaaaaaaaa#0000000000"));
        assertFalse("this node should have been deleted", children.contains("zlock#00000000-0000-0000-0000-aaaaaaaaaaaa#0000000001"));
        assertTrue(children.contains("zlock#00000000-0000-0000-0000-bbbbbbbbbbbb#0000000002"));
        assertFalse("this node should have been deleted", children.contains("zlock#00000000-0000-0000-0000-bbbbbbbbbbbb#0000000003"));
        assertNull(zl1.getWatching());
        assertEquals("/zlretryLockSerial/zlock#00000000-0000-0000-0000-aaaaaaaaaaaa#0000000000", zl2.getWatching());
        zl1.unlock();
        assertFalse(zlw1.isLockHeld());
        zk1.close();
        while (!zlw2.isLockHeld()) {
            LockSupport.parkNanos(50);
        }
        assertTrue(zlw2.isLockHeld());
        zl2.unlock();
        zk2.close();
    }
}
Also used : ServiceLock(org.apache.accumulo.fate.zookeeper.ServiceLock) Test(org.junit.Test)

Example 15 with ServiceLock

use of org.apache.accumulo.fate.zookeeper.ServiceLock in project accumulo by apache.

the class ServiceLockIT method testDeleteLock.

@Test(timeout = 10000)
public void testDeleteLock() throws Exception {
    var parent = ServiceLock.path("/zltestDeleteLock-" + this.hashCode() + "-l" + pdCount.incrementAndGet());
    ZooReaderWriter zk = new ZooReaderWriter(szk.getConn(), 30000, "secret");
    zk.mkdirs(parent.toString());
    ServiceLock zl = getZooLock(parent, UUID.randomUUID());
    assertFalse(zl.isLocked());
    TestALW lw = new TestALW();
    zl.lock(lw, "test1".getBytes(UTF_8));
    lw.waitForChanges(1);
    assertTrue(lw.locked);
    assertTrue(zl.isLocked());
    assertNull(lw.exception);
    assertNull(lw.reason);
    zk.delete(zl.getLockPath());
    lw.waitForChanges(2);
    assertEquals(LockLossReason.LOCK_DELETED, lw.reason);
    assertNull(lw.exception);
}
Also used : ServiceLock(org.apache.accumulo.fate.zookeeper.ServiceLock) ZooReaderWriter(org.apache.accumulo.fate.zookeeper.ZooReaderWriter) Test(org.junit.Test)

Aggregations

ServiceLock (org.apache.accumulo.fate.zookeeper.ServiceLock)16 ZooReaderWriter (org.apache.accumulo.fate.zookeeper.ZooReaderWriter)8 Test (org.junit.Test)8 LockLossReason (org.apache.accumulo.fate.zookeeper.ServiceLock.LockLossReason)5 LockWatcher (org.apache.accumulo.fate.zookeeper.ServiceLock.LockWatcher)5 UUID (java.util.UUID)4 ServerServices (org.apache.accumulo.core.util.ServerServices)4 IOException (java.io.IOException)3 KeeperException (org.apache.zookeeper.KeeperException)3 ZooKeeper (org.apache.zookeeper.ZooKeeper)3 UnknownHostException (java.net.UnknownHostException)2 TableNotFoundException (org.apache.accumulo.core.client.TableNotFoundException)2 ServerContext (org.apache.accumulo.server.ServerContext)2 TException (org.apache.thrift.TException)2 InvalidProtocolBufferException (com.google.protobuf.InvalidProtocolBufferException)1 SuppressFBWarnings (edu.umd.cs.findbugs.annotations.SuppressFBWarnings)1 FileNotFoundException (java.io.FileNotFoundException)1 Field (java.lang.reflect.Field)1 AccumuloSecurityException (org.apache.accumulo.core.client.AccumuloSecurityException)1 ThriftSecurityException (org.apache.accumulo.core.clientImpl.thrift.ThriftSecurityException)1