Search in sources :

Example 11 with TabletsMetadata

use of org.apache.accumulo.core.metadata.schema.TabletsMetadata in project accumulo by apache.

the class TableOperationsImpl method waitForTableStateTransition.

private void waitForTableStateTransition(TableId tableId, TableState expectedState) throws AccumuloException, TableNotFoundException {
    Text startRow = null;
    Text lastRow = null;
    while (true) {
        if (context.getTableState(tableId) != expectedState) {
            context.clearTableListCache();
            TableState currentState = context.getTableState(tableId);
            if (currentState != expectedState) {
                context.requireNotDeleted(tableId);
                if (currentState == TableState.DELETING)
                    throw new TableNotFoundException(tableId.canonical(), "", TABLE_DELETED_MSG);
                throw new AccumuloException("Unexpected table state " + tableId + " " + currentState + " != " + expectedState);
            }
        }
        Range range;
        if (startRow == null || lastRow == null)
            range = new KeyExtent(tableId, null, null).toMetaRange();
        else
            range = new Range(startRow, lastRow);
        TabletsMetadata tablets = TabletsMetadata.builder(context).scanMetadataTable().overRange(range).fetch(LOCATION, PREV_ROW).build();
        KeyExtent lastExtent = null;
        int total = 0;
        int waitFor = 0;
        int holes = 0;
        Text continueRow = null;
        MapCounter<String> serverCounts = new MapCounter<>();
        for (TabletMetadata tablet : tablets) {
            total++;
            Location loc = tablet.getLocation();
            if ((expectedState == TableState.ONLINE && (loc == null || loc.getType() == LocationType.FUTURE)) || (expectedState == TableState.OFFLINE && loc != null)) {
                if (continueRow == null)
                    continueRow = tablet.getExtent().toMetaRow();
                waitFor++;
                lastRow = tablet.getExtent().toMetaRow();
                if (loc != null) {
                    serverCounts.increment(loc.getHostPortSession(), 1);
                }
            }
            if (!tablet.getExtent().tableId().equals(tableId)) {
                throw new AccumuloException("Saw unexpected table Id " + tableId + " " + tablet.getExtent());
            }
            if (lastExtent != null && !tablet.getExtent().isPreviousExtent(lastExtent)) {
                holes++;
            }
            lastExtent = tablet.getExtent();
        }
        if (continueRow != null) {
            startRow = continueRow;
        }
        if (holes > 0 || total == 0) {
            startRow = null;
            lastRow = null;
        }
        if (waitFor > 0 || holes > 0 || total == 0) {
            long waitTime;
            long maxPerServer = 0;
            if (serverCounts.size() > 0) {
                maxPerServer = serverCounts.max();
                waitTime = maxPerServer * 10;
            } else
                waitTime = waitFor * 10L;
            waitTime = Math.max(100, waitTime);
            waitTime = Math.min(5000, waitTime);
            log.trace("Waiting for {}({}) tablets, startRow = {} lastRow = {}, holes={} sleeping:{}ms", waitFor, maxPerServer, startRow, lastRow, holes, waitTime);
            sleepUninterruptibly(waitTime, MILLISECONDS);
        } else {
            break;
        }
    }
}
Also used : AccumuloException(org.apache.accumulo.core.client.AccumuloException) Text(org.apache.hadoop.io.Text) Range(org.apache.accumulo.core.data.Range) TRowRange(org.apache.accumulo.core.dataImpl.thrift.TRowRange) KeyExtent(org.apache.accumulo.core.dataImpl.KeyExtent) Constraint(org.apache.accumulo.core.data.constraints.Constraint) TableNotFoundException(org.apache.accumulo.core.client.TableNotFoundException) TabletsMetadata(org.apache.accumulo.core.metadata.schema.TabletsMetadata) MapCounter(org.apache.accumulo.core.util.MapCounter) TabletMetadata(org.apache.accumulo.core.metadata.schema.TabletMetadata) TableState(org.apache.accumulo.core.manager.state.tables.TableState) Location(org.apache.accumulo.core.metadata.schema.TabletMetadata.Location) TabletLocation(org.apache.accumulo.core.clientImpl.TabletLocator.TabletLocation)

Example 12 with TabletsMetadata

use of org.apache.accumulo.core.metadata.schema.TabletsMetadata in project accumulo by apache.

the class TabletServer method run.

// main loop listens for client requests
@Override
public void run() {
    SecurityUtil.serverLogin(getConfiguration());
    // To make things easier on users/devs, and to avoid creating an upgrade path to 1.7
    // We can just make the zookeeper paths before we try to use.
    initializeZkForReplication();
    if (authKeyWatcher != null) {
        log.info("Seeding ZooKeeper watcher for authentication keys");
        try {
            authKeyWatcher.updateAuthKeys();
        } catch (KeeperException | InterruptedException e) {
            // TODO Does there need to be a better check? What are the error conditions that we'd fall
            // out here? AUTH_FAILURE?
            // If we get the error, do we just put it on a timer and retry the exists(String, Watcher)
            // call?
            log.error("Failed to perform initial check for authentication tokens in" + " ZooKeeper. Delegation token authentication will be unavailable.", e);
        }
    }
    try {
        clientAddress = startTabletClientService();
    } catch (UnknownHostException e1) {
        throw new RuntimeException("Failed to start the tablet client service", e1);
    }
    announceExistence();
    try {
        MetricsUtil.initializeMetrics(context.getConfiguration(), this.applicationName, clientAddress);
    } catch (Exception e1) {
        log.error("Error initializing metrics, metrics will not be emitted.", e1);
    }
    metrics = new TabletServerMetrics(this);
    updateMetrics = new TabletServerUpdateMetrics();
    scanMetrics = new TabletServerScanMetrics();
    mincMetrics = new TabletServerMinCMetrics();
    ceMetrics = new CompactionExecutorsMetrics();
    MetricsUtil.initializeProducers(metrics, updateMetrics, scanMetrics, mincMetrics, ceMetrics);
    this.compactionManager = new CompactionManager(new Iterable<Compactable>() {

        @Override
        public Iterator<Compactable> iterator() {
            return Iterators.transform(onlineTablets.snapshot().values().iterator(), Tablet::asCompactable);
        }
    }, getContext(), ceMetrics);
    compactionManager.start();
    try {
        walMarker.initWalMarker(getTabletSession());
    } catch (Exception e) {
        log.error("Unable to create WAL marker node in zookeeper", e);
        throw new RuntimeException(e);
    }
    ThreadPoolExecutor distWorkQThreadPool = ThreadPools.createExecutorService(getConfiguration(), Property.TSERV_WORKQ_THREADS, true);
    bulkFailedCopyQ = new DistributedWorkQueue(getContext().getZooKeeperRoot() + Constants.ZBULK_FAILED_COPYQ, getConfiguration(), getContext());
    try {
        bulkFailedCopyQ.startProcessing(new BulkFailedCopyProcessor(getContext()), distWorkQThreadPool);
    } catch (Exception e1) {
        throw new RuntimeException("Failed to start distributed work queue for copying ", e1);
    }
    try {
        logSorter.startWatchingForRecoveryLogs(distWorkQThreadPool);
    } catch (Exception ex) {
        log.error("Error setting watches for recoveries");
        throw new RuntimeException(ex);
    }
    final AccumuloConfiguration aconf = getConfiguration();
    // if the replication name is ever set, then start replication services
    @SuppressWarnings("deprecation") Property p = Property.REPLICATION_NAME;
    context.getScheduledExecutor().scheduleWithFixedDelay(() -> {
        if (this.replServer == null) {
            if (!getConfiguration().get(p).isEmpty()) {
                log.info(p.getKey() + " was set, starting repl services.");
                setupReplication(aconf);
            }
        }
    }, 0, 5, TimeUnit.SECONDS);
    // random 30-60 minute delay
    int tabletCheckFrequency = 30 + random.nextInt(31);
    // Periodically check that metadata of tablets matches what is held in memory
    ThreadPools.createGeneralScheduledExecutorService(aconf).scheduleWithFixedDelay(() -> {
        final SortedMap<KeyExtent, Tablet> onlineTabletsSnapshot = onlineTablets.snapshot();
        Map<KeyExtent, Long> updateCounts = new HashMap<>();
        // gather updateCounts for each tablet
        onlineTabletsSnapshot.forEach((ke, tablet) -> {
            updateCounts.put(ke, tablet.getUpdateCount());
        });
        // gather metadata for all tablets readTablets()
        try (TabletsMetadata tabletsMetadata = getContext().getAmple().readTablets().forTablets(onlineTabletsSnapshot.keySet()).fetch(FILES, LOGS, ECOMP, PREV_ROW).build()) {
            // for each tablet, compare its metadata to what is held in memory
            tabletsMetadata.forEach(tabletMetadata -> {
                KeyExtent extent = tabletMetadata.getExtent();
                Tablet tablet = onlineTabletsSnapshot.get(extent);
                Long counter = updateCounts.get(extent);
                tablet.compareTabletInfo(counter, tabletMetadata);
            });
        }
    }, tabletCheckFrequency, tabletCheckFrequency, TimeUnit.MINUTES);
    final long CLEANUP_BULK_LOADED_CACHE_MILLIS = TimeUnit.MINUTES.toMillis(15);
    context.getScheduledExecutor().scheduleWithFixedDelay(new BulkImportCacheCleaner(this), CLEANUP_BULK_LOADED_CACHE_MILLIS, CLEANUP_BULK_LOADED_CACHE_MILLIS, TimeUnit.MILLISECONDS);
    HostAndPort managerHost;
    while (!serverStopRequested) {
        // send all of the pending messages
        try {
            ManagerMessage mm = null;
            ManagerClientService.Client iface = null;
            try {
                // was requested
                while (mm == null && !serverStopRequested) {
                    mm = managerMessages.poll(1, TimeUnit.SECONDS);
                }
                // have a message to send to the manager, so grab a
                // connection
                managerHost = getManagerAddress();
                iface = managerConnection(managerHost);
                TServiceClient client = iface;
                // then finally block should place mm back on queue
                while (!serverStopRequested && mm != null && client != null && client.getOutputProtocol() != null && client.getOutputProtocol().getTransport() != null && client.getOutputProtocol().getTransport().isOpen()) {
                    try {
                        mm.send(getContext().rpcCreds(), getClientAddressString(), iface);
                        mm = null;
                    } catch (TException ex) {
                        log.warn("Error sending message: queuing message again");
                        managerMessages.putFirst(mm);
                        mm = null;
                        throw ex;
                    }
                    // if any messages are immediately available grab em and
                    // send them
                    mm = managerMessages.poll();
                }
            } finally {
                if (mm != null) {
                    managerMessages.putFirst(mm);
                }
                returnManagerConnection(iface);
                sleepUninterruptibly(1, TimeUnit.SECONDS);
            }
        } catch (InterruptedException e) {
            log.info("Interrupt Exception received, shutting down");
            serverStopRequested = true;
        } catch (Exception e) {
            // may have lost connection with manager
            // loop back to the beginning and wait for a new one
            // this way we survive manager failures
            log.error(getClientAddressString() + ": TServerInfo: Exception. Manager down?", e);
        }
    }
    // get prematurely finalized
    synchronized (this) {
        while (!shutdownComplete) {
            try {
                this.wait(1000);
            } catch (InterruptedException e) {
                log.error(e.toString());
            }
        }
    }
    log.debug("Stopping Replication Server");
    if (this.replServer != null) {
        this.replServer.stop();
    }
    log.debug("Stopping Thrift Servers");
    if (server != null) {
        server.stop();
    }
    try {
        log.debug("Closing filesystems");
        getVolumeManager().close();
    } catch (IOException e) {
        log.warn("Failed to close filesystem : {}", e.getMessage(), e);
    }
    gcLogger.logGCInfo(getConfiguration());
    log.info("TServerInfo: stop requested. exiting ... ");
    try {
        tabletServerLock.unlock();
    } catch (Exception e) {
        log.warn("Failed to release tablet server lock", e);
    }
}
Also used : TException(org.apache.thrift.TException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) Compactable(org.apache.accumulo.tserver.compactions.Compactable) KeyExtent(org.apache.accumulo.core.dataImpl.KeyExtent) TabletServerMinCMetrics(org.apache.accumulo.tserver.metrics.TabletServerMinCMetrics) DistributedWorkQueue(org.apache.accumulo.server.zookeeper.DistributedWorkQueue) TServiceClient(org.apache.thrift.TServiceClient) HostAndPort(org.apache.accumulo.core.util.HostAndPort) TabletServerMetrics(org.apache.accumulo.tserver.metrics.TabletServerMetrics) TabletsMetadata(org.apache.accumulo.core.metadata.schema.TabletsMetadata) Tablet(org.apache.accumulo.tserver.tablet.Tablet) Property(org.apache.accumulo.core.conf.Property) AccumuloConfiguration(org.apache.accumulo.core.conf.AccumuloConfiguration) ManagerClientService(org.apache.accumulo.core.manager.thrift.ManagerClientService) CompactionExecutorsMetrics(org.apache.accumulo.tserver.metrics.CompactionExecutorsMetrics) UnknownHostException(java.net.UnknownHostException) TabletServerUpdateMetrics(org.apache.accumulo.tserver.metrics.TabletServerUpdateMetrics) IOException(java.io.IOException) 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) BulkImportCacheCleaner(org.apache.accumulo.tserver.tablet.BulkImportCacheCleaner) ManagerMessage(org.apache.accumulo.tserver.managermessage.ManagerMessage) CompactionManager(org.apache.accumulo.tserver.compactions.CompactionManager) AtomicLong(java.util.concurrent.atomic.AtomicLong) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) KeeperException(org.apache.zookeeper.KeeperException) TabletServerScanMetrics(org.apache.accumulo.tserver.metrics.TabletServerScanMetrics)

Example 13 with TabletsMetadata

use of org.apache.accumulo.core.metadata.schema.TabletsMetadata in project accumulo by apache.

the class ExternalCompaction_1_IT method testExternalCompactionDeadTServer.

@Test
public void testExternalCompactionDeadTServer() throws Exception {
    // Shut down the normal TServers
    getCluster().getProcesses().get(TABLET_SERVER).forEach(p -> {
        try {
            getCluster().killProcess(TABLET_SERVER, p);
        } catch (Exception e) {
            fail("Failed to shutdown tablet server");
        }
    });
    // Start our TServer that will not commit the compaction
    ProcessInfo tserverProcess = getCluster().exec(ExternalCompactionTServer.class);
    final String table3 = this.getUniqueNames(1)[0];
    try (final AccumuloClient client = Accumulo.newClient().from(getCluster().getClientProperties()).build()) {
        createTable(client, table3, "cs7");
        writeData(client, table3);
        getCluster().getClusterControl().startCompactors(Compactor.class, 1, QUEUE7);
        getCluster().getClusterControl().startCoordinator(CompactionCoordinator.class);
        compact(client, table3, 2, QUEUE7, false);
        // ExternalCompactionTServer will not commit the compaction. Wait for the
        // metadata table entries to show up.
        LOG.info("Waiting for external compaction to complete.");
        TableId tid = getCluster().getServerContext().getTableId(table3);
        Stream<ExternalCompactionFinalState> fs = getFinalStatesForTable(getCluster(), tid);
        while (fs.count() == 0) {
            LOG.info("Waiting for compaction completed marker to appear");
            UtilWaitThread.sleep(250);
            fs = getFinalStatesForTable(getCluster(), tid);
        }
        LOG.info("Validating metadata table contents.");
        TabletsMetadata tm = getCluster().getServerContext().getAmple().readTablets().forTable(tid).fetch(ColumnType.ECOMP).build();
        List<TabletMetadata> md = new ArrayList<>();
        tm.forEach(t -> md.add(t));
        assertEquals(1, md.size());
        TabletMetadata m = md.get(0);
        Map<ExternalCompactionId, ExternalCompactionMetadata> em = m.getExternalCompactions();
        assertEquals(1, em.size());
        List<ExternalCompactionFinalState> finished = new ArrayList<>();
        getFinalStatesForTable(getCluster(), tid).forEach(f -> finished.add(f));
        assertEquals(1, finished.size());
        assertEquals(em.entrySet().iterator().next().getKey(), finished.get(0).getExternalCompactionId());
        tm.close();
        // Force a flush on the metadata table before killing our tserver
        client.tableOperations().flush("accumulo.metadata");
        // Stop our TabletServer. Need to perform a normal shutdown so that the WAL is closed
        // normally.
        LOG.info("Stopping our tablet server");
        getCluster().stopProcessWithTimeout(tserverProcess.getProcess(), 30, TimeUnit.SECONDS);
        getCluster().getClusterControl().stop(ServerType.TABLET_SERVER);
        // Start a TabletServer to commit the compaction.
        LOG.info("Starting normal tablet server");
        getCluster().getClusterControl().start(ServerType.TABLET_SERVER);
        // Wait for the compaction to be committed.
        LOG.info("Waiting for compaction completed marker to disappear");
        Stream<ExternalCompactionFinalState> fs2 = getFinalStatesForTable(getCluster(), tid);
        while (fs2.count() != 0) {
            LOG.info("Waiting for compaction completed marker to disappear");
            UtilWaitThread.sleep(500);
            fs2 = getFinalStatesForTable(getCluster(), tid);
        }
        verify(client, table3, 2);
        // We need to cancel the compaction or delete the table here because we initiate a user
        // compaction above in the test. Even though the external compaction was cancelled
        // because we split the table, FaTE will continue to queue up a compaction
        client.tableOperations().cancelCompaction(table3);
    }
}
Also used : AccumuloClient(org.apache.accumulo.core.client.AccumuloClient) TableId(org.apache.accumulo.core.data.TableId) ExternalCompactionId(org.apache.accumulo.core.metadata.schema.ExternalCompactionId) ArrayList(java.util.ArrayList) ProcessInfo(org.apache.accumulo.miniclusterImpl.MiniAccumuloClusterImpl.ProcessInfo) IOException(java.io.IOException) ExternalCompactionMetadata(org.apache.accumulo.core.metadata.schema.ExternalCompactionMetadata) TabletsMetadata(org.apache.accumulo.core.metadata.schema.TabletsMetadata) ExternalCompactionFinalState(org.apache.accumulo.core.metadata.schema.ExternalCompactionFinalState) TabletMetadata(org.apache.accumulo.core.metadata.schema.TabletMetadata) Test(org.junit.Test)

Example 14 with TabletsMetadata

use of org.apache.accumulo.core.metadata.schema.TabletsMetadata in project accumulo by apache.

the class ExternalCompactionMetricsIT method testMetrics.

@Test
public void testMetrics() throws Exception {
    Collection<ProcessReference> tservers = ((MiniAccumuloClusterImpl) getCluster()).getProcesses().get(ServerType.TABLET_SERVER);
    assertEquals(2, tservers.size());
    // kill one tserver so that queue metrics are not spread across tservers
    ((MiniAccumuloClusterImpl) getCluster()).killProcess(TABLET_SERVER, tservers.iterator().next());
    String[] names = getUniqueNames(2);
    try (final AccumuloClient client = Accumulo.newClient().from(getCluster().getClientProperties()).build()) {
        String table1 = names[0];
        createTable(client, table1, "cs1", 5);
        String table2 = names[1];
        createTable(client, table2, "cs2", 10);
        writeData(client, table1);
        writeData(client, table2);
        final LinkedBlockingQueue<Metric> queueMetrics = new LinkedBlockingQueue<>();
        final AtomicBoolean shutdownTailer = new AtomicBoolean(false);
        Thread thread = Threads.createThread("metric-tailer", () -> {
            while (!shutdownTailer.get()) {
                List<String> statsDMetrics = sink.getLines();
                for (String s : statsDMetrics) {
                    if (shutdownTailer.get()) {
                        break;
                    }
                    if (s.startsWith(MetricsProducer.METRICS_MAJC_QUEUED)) {
                        queueMetrics.add(TestStatsDSink.parseStatsDMetric(s));
                    }
                }
            }
        });
        thread.start();
        compact(client, table1, 7, "DCQ1", false);
        compact(client, table2, 13, "DCQ2", false);
        boolean sawDCQ1_5 = false;
        boolean sawDCQ2_10 = false;
        // wait until expected number of queued are seen in metrics
        while (!sawDCQ1_5 || !sawDCQ2_10) {
            Metric qm = queueMetrics.take();
            sawDCQ1_5 |= match(qm, "DCQ1", "5");
            sawDCQ2_10 |= match(qm, "DCQ2", "10");
        }
        cluster.getClusterControl().startCompactors(Compactor.class, 1, QUEUE1);
        cluster.getClusterControl().startCompactors(Compactor.class, 1, QUEUE2);
        cluster.getClusterControl().startCoordinator(CompactionCoordinator.class);
        boolean sawDCQ1_0 = false;
        boolean sawDCQ2_0 = false;
        // wait until queued goes to zero in metrics
        while (!sawDCQ1_0 || !sawDCQ2_0) {
            Metric qm = queueMetrics.take();
            sawDCQ1_0 |= match(qm, "DCQ1", "0");
            sawDCQ2_0 |= match(qm, "DCQ2", "0");
        }
        shutdownTailer.set(true);
        thread.join();
        // Wait for all external compactions to complete
        long count;
        do {
            UtilWaitThread.sleep(100);
            try (TabletsMetadata tm = getCluster().getServerContext().getAmple().readTablets().forLevel(DataLevel.USER).fetch(ColumnType.ECOMP).build()) {
                count = tm.stream().flatMap(t -> t.getExternalCompactions().keySet().stream()).count();
            }
        } while (count > 0);
        verify(client, table1, 7);
        verify(client, table2, 13);
    } finally {
    // We stopped the TServer and started our own, restart the original TabletServers
    // Uncomment this if other tests are added.
    // 
    // cluster.getClusterControl().start(ServerType.TABLET_SERVER);
    }
}
Also used : AccumuloClient(org.apache.accumulo.core.client.AccumuloClient) ProcessReference(org.apache.accumulo.miniclusterImpl.ProcessReference) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) UtilWaitThread(org.apache.accumulo.fate.util.UtilWaitThread) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) TabletsMetadata(org.apache.accumulo.core.metadata.schema.TabletsMetadata) Metric(org.apache.accumulo.test.metrics.TestStatsDSink.Metric) MiniAccumuloClusterImpl(org.apache.accumulo.miniclusterImpl.MiniAccumuloClusterImpl) Test(org.junit.Test)

Aggregations

TabletsMetadata (org.apache.accumulo.core.metadata.schema.TabletsMetadata)14 TabletMetadata (org.apache.accumulo.core.metadata.schema.TabletMetadata)9 AccumuloClient (org.apache.accumulo.core.client.AccumuloClient)7 TableId (org.apache.accumulo.core.data.TableId)7 Text (org.apache.hadoop.io.Text)7 Test (org.junit.Test)7 Property (org.apache.accumulo.core.conf.Property)5 ArrayList (java.util.ArrayList)4 TreeSet (java.util.TreeSet)4 Accumulo (org.apache.accumulo.core.client.Accumulo)4 ExternalCompactionId (org.apache.accumulo.core.metadata.schema.ExternalCompactionId)4 Set (java.util.Set)3 Collectors (java.util.stream.Collectors)3 KeyExtent (org.apache.accumulo.core.dataImpl.KeyExtent)3 MiniClusterConfigurationCallback (org.apache.accumulo.harness.MiniClusterConfigurationCallback)3 SharedMiniClusterBase (org.apache.accumulo.harness.SharedMiniClusterBase)3 ServerType (org.apache.accumulo.minicluster.ServerType)3 MiniAccumuloConfigImpl (org.apache.accumulo.miniclusterImpl.MiniAccumuloConfigImpl)3 Configuration (org.apache.hadoop.conf.Configuration)3 Assert.assertEquals (org.junit.Assert.assertEquals)3