Search in sources :

Example 1 with ZooReaderWriter

use of org.apache.accumulo.server.zookeeper.ZooReaderWriter in project accumulo by apache.

the class VolumeIT method verifyVolumesUsed.

private void verifyVolumesUsed(String tableName, boolean shouldExist, Path... paths) throws Exception {
    Connector conn = getConnector();
    List<String> expected = new ArrayList<>();
    for (int i = 0; i < 100; i++) {
        String row = String.format("%06d", i * 100 + 3);
        expected.add(row + ":cf1:cq1:1");
    }
    if (!conn.tableOperations().exists(tableName)) {
        Assert.assertFalse(shouldExist);
        writeData(tableName, conn);
        verifyData(expected, conn.createScanner(tableName, Authorizations.EMPTY));
        conn.tableOperations().flush(tableName, null, null, true);
    }
    verifyData(expected, conn.createScanner(tableName, Authorizations.EMPTY));
    Table.ID tableId = Table.ID.of(conn.tableOperations().tableIdMap().get(tableName));
    try (Scanner metaScanner = conn.createScanner(MetadataTable.NAME, Authorizations.EMPTY)) {
        MetadataSchema.TabletsSection.ServerColumnFamily.DIRECTORY_COLUMN.fetch(metaScanner);
        metaScanner.fetchColumnFamily(MetadataSchema.TabletsSection.DataFileColumnFamily.NAME);
        metaScanner.setRange(new KeyExtent(tableId, null, null).toMetadataRange());
        int[] counts = new int[paths.length];
        outer: for (Entry<Key, Value> entry : metaScanner) {
            String cf = entry.getKey().getColumnFamily().toString();
            String cq = entry.getKey().getColumnQualifier().toString();
            String path;
            if (cf.equals(MetadataSchema.TabletsSection.DataFileColumnFamily.NAME.toString()))
                path = cq;
            else
                path = entry.getValue().toString();
            for (int i = 0; i < paths.length; i++) {
                if (path.startsWith(paths[i].toString())) {
                    counts[i]++;
                    continue outer;
                }
            }
            Assert.fail("Unexpected volume " + path);
        }
        // keep retrying until WAL state information in ZooKeeper stabilizes or until test times out
        retry: while (true) {
            Instance i = conn.getInstance();
            ZooReaderWriter zk = new ZooReaderWriter(i.getZooKeepers(), i.getZooKeepersSessionTimeOut(), "");
            WalStateManager wals = new WalStateManager(i, zk);
            try {
                outer: for (Entry<Path, WalState> entry : wals.getAllState().entrySet()) {
                    for (Path path : paths) {
                        if (entry.getKey().toString().startsWith(path.toString())) {
                            continue outer;
                        }
                    }
                    log.warn("Unexpected volume " + entry.getKey() + " (" + entry.getValue() + ")");
                    continue retry;
                }
            } catch (WalMarkerException e) {
                Throwable cause = e.getCause();
                if (cause instanceof NoNodeException) {
                    // ignore WALs being cleaned up
                    continue retry;
                }
                throw e;
            }
            break;
        }
        // if a volume is chosen randomly for each tablet, then the probability that a volume will not be chosen for any tablet is ((num_volumes -
        // 1)/num_volumes)^num_tablets. For 100 tablets and 3 volumes the probability that only 2 volumes would be chosen is 2.46e-18
        int sum = 0;
        for (int count : counts) {
            Assert.assertTrue(count > 0);
            sum += count;
        }
        Assert.assertEquals(200, sum);
    }
}
Also used : Path(org.apache.hadoop.fs.Path) Connector(org.apache.accumulo.core.client.Connector) Scanner(org.apache.accumulo.core.client.Scanner) MetadataTable(org.apache.accumulo.core.metadata.MetadataTable) RootTable(org.apache.accumulo.core.metadata.RootTable) Table(org.apache.accumulo.core.client.impl.Table) NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) Instance(org.apache.accumulo.core.client.Instance) ZooKeeperInstance(org.apache.accumulo.core.client.ZooKeeperInstance) ArrayList(java.util.ArrayList) ZooReaderWriter(org.apache.accumulo.server.zookeeper.ZooReaderWriter) KeyExtent(org.apache.accumulo.core.data.impl.KeyExtent) Entry(java.util.Map.Entry) WalStateManager(org.apache.accumulo.server.log.WalStateManager) WalState(org.apache.accumulo.server.log.WalStateManager.WalState) WalMarkerException(org.apache.accumulo.server.log.WalStateManager.WalMarkerException)

Example 2 with ZooReaderWriter

use of org.apache.accumulo.server.zookeeper.ZooReaderWriter in project accumulo by apache.

the class ReplicationIT method getLogs.

private Multimap<String, Table.ID> getLogs(Connector conn) throws Exception {
    // Map of server to tableId
    Multimap<TServerInstance, String> serverToTableID = HashMultimap.create();
    try (Scanner scanner = conn.createScanner(MetadataTable.NAME, Authorizations.EMPTY)) {
        scanner.setRange(MetadataSchema.TabletsSection.getRange());
        scanner.fetchColumnFamily(MetadataSchema.TabletsSection.CurrentLocationColumnFamily.NAME);
        for (Entry<Key, Value> entry : scanner) {
            TServerInstance key = new TServerInstance(entry.getValue(), entry.getKey().getColumnQualifier());
            byte[] tableId = KeyExtent.tableOfMetadataRow(entry.getKey().getRow());
            serverToTableID.put(key, new String(tableId, UTF_8));
        }
        // Map of logs to tableId
        Multimap<String, Table.ID> logs = HashMultimap.create();
        Instance i = conn.getInstance();
        ZooReaderWriter zk = new ZooReaderWriter(i.getZooKeepers(), i.getZooKeepersSessionTimeOut(), "");
        WalStateManager wals = new WalStateManager(conn.getInstance(), zk);
        for (Entry<TServerInstance, List<UUID>> entry : wals.getAllMarkers().entrySet()) {
            for (UUID id : entry.getValue()) {
                Pair<WalState, Path> state = wals.state(entry.getKey(), id);
                for (String tableId : serverToTableID.get(entry.getKey())) {
                    logs.put(state.getSecond().toString(), Table.ID.of(tableId));
                }
            }
        }
        return logs;
    }
}
Also used : Path(org.apache.hadoop.fs.Path) Scanner(org.apache.accumulo.core.client.Scanner) Instance(org.apache.accumulo.core.client.Instance) TServerInstance(org.apache.accumulo.server.master.state.TServerInstance) ZooKeeperInstance(org.apache.accumulo.core.client.ZooKeeperInstance) ZooReaderWriter(org.apache.accumulo.server.zookeeper.ZooReaderWriter) TServerInstance(org.apache.accumulo.server.master.state.TServerInstance) WalStateManager(org.apache.accumulo.server.log.WalStateManager) Value(org.apache.accumulo.core.data.Value) List(java.util.List) ArrayList(java.util.ArrayList) WalState(org.apache.accumulo.server.log.WalStateManager.WalState) UUID(java.util.UUID) UUID(java.util.UUID) Key(org.apache.accumulo.core.data.Key)

Example 3 with ZooReaderWriter

use of org.apache.accumulo.server.zookeeper.ZooReaderWriter in project accumulo by apache.

the class ReplicationIT method correctRecordsCompleteFile.

@Test
public void correctRecordsCompleteFile() throws Exception {
    Connector conn = getConnector();
    String table = "table1";
    conn.tableOperations().create(table);
    // If we have more than one tserver, this is subject to a race condition.
    conn.tableOperations().setProperty(table, Property.TABLE_REPLICATION.getKey(), "true");
    BatchWriter bw = conn.createBatchWriter(table, new BatchWriterConfig());
    for (int i = 0; i < 10; i++) {
        Mutation m = new Mutation(Integer.toString(i));
        m.put(new byte[0], new byte[0], new byte[0]);
        bw.addMutation(m);
    }
    bw.close();
    // After writing data, we'll get a replication table online
    while (!ReplicationTable.isOnline(conn)) {
        sleepUninterruptibly(MILLIS_BETWEEN_REPLICATION_TABLE_ONLINE_CHECKS, TimeUnit.MILLISECONDS);
    }
    Assert.assertTrue("Replication table did not exist", ReplicationTable.isOnline(conn));
    for (int i = 0; i < 5; i++) {
        if (conn.securityOperations().hasTablePermission("root", ReplicationTable.NAME, TablePermission.READ)) {
            break;
        }
        log.info("Could not read replication table, waiting and will retry");
        Thread.sleep(2000);
    }
    Assert.assertTrue("'root' user could not read the replication table", conn.securityOperations().hasTablePermission("root", ReplicationTable.NAME, TablePermission.READ));
    Set<String> replRows = new HashSet<>();
    int attempts = 5;
    while (replRows.isEmpty() && attempts > 0) {
        try (Scanner scanner = ReplicationTable.getScanner(conn)) {
            StatusSection.limit(scanner);
            for (Entry<Key, Value> entry : scanner) {
                Key k = entry.getKey();
                String fileUri = k.getRow().toString();
                try {
                    new URI(fileUri);
                } catch (URISyntaxException e) {
                    Assert.fail("Expected a valid URI: " + fileUri);
                }
                replRows.add(fileUri);
            }
        }
    }
    Set<String> wals = new HashSet<>();
    attempts = 5;
    Instance i = conn.getInstance();
    ZooReaderWriter zk = new ZooReaderWriter(i.getZooKeepers(), i.getZooKeepersSessionTimeOut(), "");
    while (wals.isEmpty() && attempts > 0) {
        WalStateManager markers = new WalStateManager(i, zk);
        for (Entry<Path, WalState> entry : markers.getAllState().entrySet()) {
            wals.add(entry.getKey().toString());
        }
        attempts--;
    }
    // We only have one file that should need replication (no trace table)
    // We should find an entry in tablet and in the repl row
    Assert.assertEquals("Rows found: " + replRows, 1, replRows.size());
    // There should only be one extra WALog that replication doesn't know about
    replRows.removeAll(wals);
    Assert.assertEquals(2, wals.size());
    Assert.assertEquals(0, replRows.size());
}
Also used : Path(org.apache.hadoop.fs.Path) Connector(org.apache.accumulo.core.client.Connector) Scanner(org.apache.accumulo.core.client.Scanner) Instance(org.apache.accumulo.core.client.Instance) TServerInstance(org.apache.accumulo.server.master.state.TServerInstance) ZooKeeperInstance(org.apache.accumulo.core.client.ZooKeeperInstance) ZooReaderWriter(org.apache.accumulo.server.zookeeper.ZooReaderWriter) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) WalStateManager(org.apache.accumulo.server.log.WalStateManager) Value(org.apache.accumulo.core.data.Value) BatchWriterConfig(org.apache.accumulo.core.client.BatchWriterConfig) WalState(org.apache.accumulo.server.log.WalStateManager.WalState) BatchWriter(org.apache.accumulo.core.client.BatchWriter) Mutation(org.apache.accumulo.core.data.Mutation) Key(org.apache.accumulo.core.data.Key) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 4 with ZooReaderWriter

use of org.apache.accumulo.server.zookeeper.ZooReaderWriter in project accumulo by apache.

the class Master method run.

public void run() throws IOException, InterruptedException, KeeperException {
    final String zroot = ZooUtil.getRoot(getInstance());
    // ACCUMULO-4424 Put up the Thrift servers before getting the lock as a sign of process health when a hot-standby
    // 
    // Start the Master's Client service
    clientHandler = new MasterClientServiceHandler(this);
    // Ensure that calls before the master gets the lock fail
    Iface haProxy = HighlyAvailableServiceWrapper.service(clientHandler, this);
    Iface rpcProxy = RpcWrapper.service(haProxy);
    final Processor<Iface> processor;
    if (ThriftServerType.SASL == getThriftServerType()) {
        Iface tcredsProxy = TCredentialsUpdatingWrapper.service(rpcProxy, clientHandler.getClass(), getConfiguration());
        processor = new Processor<>(tcredsProxy);
    } else {
        processor = new Processor<>(rpcProxy);
    }
    ServerAddress sa = TServerUtils.startServer(this, hostname, Property.MASTER_CLIENTPORT, processor, "Master", "Master Client Service Handler", null, Property.MASTER_MINTHREADS, Property.MASTER_THREADCHECK, Property.GENERAL_MAX_MESSAGE_SIZE);
    clientService = sa.server;
    log.info("Started Master client service at {}", sa.address);
    // Start the replication coordinator which assigns tservers to service replication requests
    MasterReplicationCoordinator impl = new MasterReplicationCoordinator(this);
    ReplicationCoordinator.Iface haReplicationProxy = HighlyAvailableServiceWrapper.service(impl, this);
    ReplicationCoordinator.Processor<ReplicationCoordinator.Iface> replicationCoordinatorProcessor = new ReplicationCoordinator.Processor<>(RpcWrapper.service(haReplicationProxy));
    ServerAddress replAddress = TServerUtils.startServer(this, hostname, Property.MASTER_REPLICATION_COORDINATOR_PORT, replicationCoordinatorProcessor, "Master Replication Coordinator", "Replication Coordinator", null, Property.MASTER_REPLICATION_COORDINATOR_MINTHREADS, Property.MASTER_REPLICATION_COORDINATOR_THREADCHECK, Property.GENERAL_MAX_MESSAGE_SIZE);
    log.info("Started replication coordinator service at " + replAddress.address);
    // block until we can obtain the ZK lock for the master
    getMasterLock(zroot + Constants.ZMASTER_LOCK);
    recoveryManager = new RecoveryManager(this);
    TableManager.getInstance().addObserver(this);
    StatusThread statusThread = new StatusThread();
    statusThread.start();
    MigrationCleanupThread migrationCleanupThread = new MigrationCleanupThread();
    migrationCleanupThread.start();
    tserverSet.startListeningForTabletServerChanges();
    ZooReaderWriter zReaderWriter = ZooReaderWriter.getInstance();
    zReaderWriter.getChildren(zroot + Constants.ZRECOVERY, new Watcher() {

        @Override
        public void process(WatchedEvent event) {
            nextEvent.event("Noticed recovery changes", event.getType());
            try {
                // watcher only fires once, add it back
                ZooReaderWriter.getInstance().getChildren(zroot + Constants.ZRECOVERY, this);
            } catch (Exception e) {
                log.error("Failed to add log recovery watcher back", e);
            }
        }
    });
    watchers.add(new TabletGroupWatcher(this, new MetaDataStateStore(this, this), null) {

        @Override
        boolean canSuspendTablets() {
            // Always allow user data tablets to enter suspended state.
            return true;
        }
    });
    watchers.add(new TabletGroupWatcher(this, new RootTabletStateStore(this, this), watchers.get(0)) {

        @Override
        boolean canSuspendTablets() {
            // be immediately reassigned, even if there's a global table.suspension.duration setting.
            return getConfiguration().getBoolean(Property.MASTER_METADATA_SUSPENDABLE);
        }
    });
    watchers.add(new TabletGroupWatcher(this, new ZooTabletStateStore(new ZooStore(zroot)), watchers.get(1)) {

        @Override
        boolean canSuspendTablets() {
            // Never allow root tablet to enter suspended state.
            return false;
        }
    });
    for (TabletGroupWatcher watcher : watchers) {
        watcher.start();
    }
    // Once we are sure the upgrade is complete, we can safely allow fate use.
    waitForMetadataUpgrade.await();
    try {
        final AgeOffStore<Master> store = new AgeOffStore<>(new org.apache.accumulo.fate.ZooStore<Master>(ZooUtil.getRoot(getInstance()) + Constants.ZFATE, ZooReaderWriter.getInstance()), 1000 * 60 * 60 * 8);
        int threads = getConfiguration().getCount(Property.MASTER_FATE_THREADPOOL_SIZE);
        fate = new Fate<>(this, store);
        fate.startTransactionRunners(threads);
        SimpleTimer.getInstance(getConfiguration()).schedule(new Runnable() {

            @Override
            public void run() {
                store.ageOff();
            }
        }, 63000, 63000);
    } catch (KeeperException | InterruptedException e) {
        throw new IOException(e);
    }
    ZooKeeperInitialization.ensureZooKeeperInitialized(zReaderWriter, zroot);
    // the master client service.
    if (null != authenticationTokenKeyManager && null != keyDistributor) {
        log.info("Starting delegation-token key manager");
        keyDistributor.initialize();
        authenticationTokenKeyManager.start();
        boolean logged = false;
        while (!authenticationTokenKeyManager.isInitialized()) {
            // Print out a status message when we start waiting for the key manager to get initialized
            if (!logged) {
                log.info("Waiting for AuthenticationTokenKeyManager to be initialized");
                logged = true;
            }
            sleepUninterruptibly(200, TimeUnit.MILLISECONDS);
        }
        // And log when we are initialized
        log.info("AuthenticationTokenSecretManager is initialized");
    }
    String address = sa.address.toString();
    log.info("Setting master lock data to {}", address);
    masterLock.replaceLockData(address.getBytes());
    while (!clientService.isServing()) {
        sleepUninterruptibly(100, TimeUnit.MILLISECONDS);
    }
    // Start the daemon to scan the replication table and make units of work
    replicationWorkDriver = new ReplicationDriver(this);
    replicationWorkDriver.start();
    // Start the daemon to assign work to tservers to replicate to our peers
    try {
        replicationWorkAssigner = new WorkDriver(this);
    } catch (AccumuloException | AccumuloSecurityException e) {
        log.error("Caught exception trying to initialize replication WorkDriver", e);
        throw new RuntimeException(e);
    }
    replicationWorkAssigner.start();
    // Advertise that port we used so peers don't have to be told what it is
    ZooReaderWriter.getInstance().putPersistentData(ZooUtil.getRoot(getInstance()) + Constants.ZMASTER_REPLICATION_COORDINATOR_ADDR, replAddress.address.toString().getBytes(UTF_8), NodeExistsPolicy.OVERWRITE);
    // Register replication metrics
    MasterMetricsFactory factory = new MasterMetricsFactory(getConfiguration(), this);
    Metrics replicationMetrics = factory.createReplicationMetrics();
    try {
        replicationMetrics.register();
    } catch (Exception e) {
        log.error("Failed to register replication metrics", e);
    }
    // The master is fully initialized. Clients are allowed to connect now.
    masterInitialized.set(true);
    while (clientService.isServing()) {
        sleepUninterruptibly(500, TimeUnit.MILLISECONDS);
    }
    log.info("Shutting down fate.");
    fate.shutdown();
    log.info("Shutting down timekeeping.");
    timeKeeper.shutdown();
    final long deadline = System.currentTimeMillis() + MAX_CLEANUP_WAIT_TIME;
    statusThread.join(remaining(deadline));
    replicationWorkAssigner.join(remaining(deadline));
    replicationWorkDriver.join(remaining(deadline));
    replAddress.server.stop();
    // Signal that we want it to stop, and wait for it to do so.
    if (authenticationTokenKeyManager != null) {
        authenticationTokenKeyManager.gracefulStop();
        authenticationTokenKeyManager.join(remaining(deadline));
    }
    // don't stop
    for (TabletGroupWatcher watcher : watchers) {
        watcher.join(remaining(deadline));
    }
    log.info("exiting");
}
Also used : Processor(org.apache.accumulo.core.master.thrift.MasterClientService.Processor) ServerAddress(org.apache.accumulo.server.rpc.ServerAddress) Watcher(org.apache.zookeeper.Watcher) MasterReplicationCoordinator(org.apache.accumulo.master.replication.MasterReplicationCoordinator) ReplicationCoordinator(org.apache.accumulo.core.replication.thrift.ReplicationCoordinator) WatchedEvent(org.apache.zookeeper.WatchedEvent) Iface(org.apache.accumulo.core.master.thrift.MasterClientService.Iface) Metrics(org.apache.accumulo.server.metrics.Metrics) RootTabletStateStore(org.apache.accumulo.server.master.state.RootTabletStateStore) MasterReplicationCoordinator(org.apache.accumulo.master.replication.MasterReplicationCoordinator) WorkDriver(org.apache.accumulo.master.replication.WorkDriver) AccumuloSecurityException(org.apache.accumulo.core.client.AccumuloSecurityException) AgeOffStore(org.apache.accumulo.fate.AgeOffStore) AccumuloException(org.apache.accumulo.core.client.AccumuloException) ZooReaderWriter(org.apache.accumulo.server.zookeeper.ZooReaderWriter) IZooReaderWriter(org.apache.accumulo.fate.zookeeper.IZooReaderWriter) ZooStore(org.apache.accumulo.server.master.state.ZooStore) IOException(java.io.IOException) TableNotFoundException(org.apache.accumulo.core.client.TableNotFoundException) NoAuthException(org.apache.zookeeper.KeeperException.NoAuthException) WalMarkerException(org.apache.accumulo.server.log.WalStateManager.WalMarkerException) TException(org.apache.thrift.TException) IOException(java.io.IOException) ThriftTableOperationException(org.apache.accumulo.core.client.impl.thrift.ThriftTableOperationException) TTransportException(org.apache.thrift.transport.TTransportException) AccumuloSecurityException(org.apache.accumulo.core.client.AccumuloSecurityException) KeeperException(org.apache.zookeeper.KeeperException) AccumuloException(org.apache.accumulo.core.client.AccumuloException) RecoveryManager(org.apache.accumulo.master.recovery.RecoveryManager) MetaDataStateStore(org.apache.accumulo.server.master.state.MetaDataStateStore) ReplicationDriver(org.apache.accumulo.master.replication.ReplicationDriver) MasterMetricsFactory(org.apache.accumulo.master.metrics.MasterMetricsFactory) ZooTabletStateStore(org.apache.accumulo.server.master.state.ZooTabletStateStore) KeeperException(org.apache.zookeeper.KeeperException)

Example 5 with ZooReaderWriter

use of org.apache.accumulo.server.zookeeper.ZooReaderWriter in project accumulo by apache.

the class ZooKeeperInitializationTest method parentNodesAreNotRecreatedWhenAlreadyExist.

@Test
public void parentNodesAreNotRecreatedWhenAlreadyExist() throws Exception {
    ZooReaderWriter zReaderWriter = createMock(ZooReaderWriter.class);
    String zRoot = "/accumulo";
    expect(zReaderWriter.exists(zRoot + ReplicationConstants.ZOO_TSERVERS, null)).andReturn(true).once();
    expect(zReaderWriter.exists(zRoot + ReplicationConstants.ZOO_WORK_QUEUE, null)).andReturn(true).once();
    replay(zReaderWriter);
    ZooKeeperInitialization.ensureZooKeeperInitialized(zReaderWriter, zRoot);
    verify(zReaderWriter);
}
Also used : ZooReaderWriter(org.apache.accumulo.server.zookeeper.ZooReaderWriter) Test(org.junit.Test)

Aggregations

ZooReaderWriter (org.apache.accumulo.server.zookeeper.ZooReaderWriter)20 Instance (org.apache.accumulo.core.client.Instance)8 IZooReaderWriter (org.apache.accumulo.fate.zookeeper.IZooReaderWriter)6 Connector (org.apache.accumulo.core.client.Connector)5 ZooKeeperInstance (org.apache.accumulo.core.client.ZooKeeperInstance)5 WalStateManager (org.apache.accumulo.server.log.WalStateManager)5 WalState (org.apache.accumulo.server.log.WalStateManager.WalState)5 Path (org.apache.hadoop.fs.Path)5 KeeperException (org.apache.zookeeper.KeeperException)5 Test (org.junit.Test)5 ArrayList (java.util.ArrayList)4 IOException (java.io.IOException)3 Scanner (org.apache.accumulo.core.client.Scanner)3 TServerInstance (org.apache.accumulo.server.master.state.TServerInstance)3 HashSet (java.util.HashSet)2 List (java.util.List)2 TableNotFoundException (org.apache.accumulo.core.client.TableNotFoundException)2 Key (org.apache.accumulo.core.data.Key)2 Value (org.apache.accumulo.core.data.Value)2 ServerServices (org.apache.accumulo.core.util.ServerServices)2