Search in sources :

Example 6 with SimpleThreadPool

use of org.apache.accumulo.core.util.SimpleThreadPool in project accumulo by apache.

the class BatchWriterFlushIT method runMultiThreadedBinningTest.

@Test
public void runMultiThreadedBinningTest() throws Exception {
    Connector c = getConnector();
    String[] tableNames = getUniqueNames(1);
    String tableName = tableNames[0];
    c.tableOperations().create(tableName);
    for (int x = 0; x < NUM_THREADS; x++) {
        c.tableOperations().addSplits(tableName, new TreeSet<>(Collections.singleton(new Text(Integer.toString(x * NUM_TO_FLUSH)))));
    }
    c.instanceOperations().waitForBalance();
    // Logger.getLogger(TabletServerBatchWriter.class).setLevel(Level.TRACE);
    final List<Set<Mutation>> allMuts = new LinkedList<>();
    List<Mutation> data = new ArrayList<>();
    for (int i = 0; i < NUM_THREADS; i++) {
        final int thread = i;
        for (int j = 0; j < NUM_TO_FLUSH; j++) {
            int row = thread * NUM_TO_FLUSH + j;
            Mutation m = new Mutation(new Text(String.format("%10d", row)));
            m.put(new Text("cf" + thread), new Text("cq"), new Value(("" + row).getBytes()));
            data.add(m);
        }
    }
    Assert.assertEquals(NUM_THREADS * NUM_TO_FLUSH, data.size());
    Collections.shuffle(data);
    for (int n = 0; n < (NUM_THREADS * NUM_TO_FLUSH); n += NUM_TO_FLUSH) {
        Set<Mutation> muts = new HashSet<>(data.subList(n, n + NUM_TO_FLUSH));
        allMuts.add(muts);
    }
    SimpleThreadPool threads = new SimpleThreadPool(NUM_THREADS, "ClientThreads");
    threads.allowCoreThreadTimeOut(false);
    threads.prestartAllCoreThreads();
    BatchWriterConfig cfg = new BatchWriterConfig();
    cfg.setMaxLatency(10, TimeUnit.SECONDS);
    cfg.setMaxMemory(1 * 1024 * 1024);
    cfg.setMaxWriteThreads(NUM_THREADS);
    final BatchWriter bw = getConnector().createBatchWriter(tableName, cfg);
    for (int k = 0; k < NUM_THREADS; k++) {
        final int idx = k;
        threads.execute(new Runnable() {

            @Override
            public void run() {
                try {
                    bw.addMutations(allMuts.get(idx));
                    bw.flush();
                } catch (MutationsRejectedException e) {
                    Assert.fail("Error adding mutations to batch writer");
                }
            }
        });
    }
    threads.shutdown();
    threads.awaitTermination(3, TimeUnit.MINUTES);
    bw.close();
    try (Scanner scanner = getConnector().createScanner(tableName, Authorizations.EMPTY)) {
        for (Entry<Key, Value> e : scanner) {
            Mutation m = new Mutation(e.getKey().getRow());
            m.put(e.getKey().getColumnFamily(), e.getKey().getColumnQualifier(), e.getValue());
            boolean found = false;
            for (int l = 0; l < NUM_THREADS; l++) {
                if (allMuts.get(l).contains(m)) {
                    found = true;
                    allMuts.get(l).remove(m);
                    break;
                }
            }
            Assert.assertTrue("Mutation not found: " + m.toString(), found);
        }
        for (int m = 0; m < NUM_THREADS; m++) {
            Assert.assertEquals(0, allMuts.get(m).size());
        }
    }
}
Also used : Connector(org.apache.accumulo.core.client.Connector) Scanner(org.apache.accumulo.core.client.Scanner) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) Set(java.util.Set) ArrayList(java.util.ArrayList) BatchWriterConfig(org.apache.accumulo.core.client.BatchWriterConfig) SimpleThreadPool(org.apache.accumulo.core.util.SimpleThreadPool) HashSet(java.util.HashSet) MutationsRejectedException(org.apache.accumulo.core.client.MutationsRejectedException) Text(org.apache.hadoop.io.Text) LinkedList(java.util.LinkedList) Value(org.apache.accumulo.core.data.Value) Mutation(org.apache.accumulo.core.data.Mutation) BatchWriter(org.apache.accumulo.core.client.BatchWriter) Key(org.apache.accumulo.core.data.Key) Test(org.junit.Test)

Example 7 with SimpleThreadPool

use of org.apache.accumulo.core.util.SimpleThreadPool in project accumulo by apache.

the class RandomizeVolumes method randomize.

public static int randomize(Connector c, String tableName) throws IOException, AccumuloSecurityException, AccumuloException, TableNotFoundException {
    final VolumeManager vm = VolumeManagerImpl.get();
    if (vm.getVolumes().size() < 2) {
        log.error("There are not enough volumes configured");
        return 1;
    }
    String tblStr = c.tableOperations().tableIdMap().get(tableName);
    if (null == tblStr) {
        log.error("Could not determine the table ID for table {}", tableName);
        return 2;
    }
    Table.ID tableId = Table.ID.of(tblStr);
    TableState tableState = TableManager.getInstance().getTableState(tableId);
    if (TableState.OFFLINE != tableState) {
        log.info("Taking {} offline", tableName);
        c.tableOperations().offline(tableName, true);
        log.info("{} offline", tableName);
    }
    SimpleThreadPool pool = new SimpleThreadPool(50, "directory maker");
    log.info("Rewriting entries for {}", tableName);
    Scanner scanner = c.createScanner(MetadataTable.NAME, Authorizations.EMPTY);
    DIRECTORY_COLUMN.fetch(scanner);
    scanner.setRange(TabletsSection.getRange(tableId));
    BatchWriter writer = c.createBatchWriter(MetadataTable.NAME, null);
    int count = 0;
    for (Entry<Key, Value> entry : scanner) {
        String oldLocation = entry.getValue().toString();
        String directory;
        if (oldLocation.contains(":")) {
            String[] parts = oldLocation.split(Path.SEPARATOR);
            Table.ID tableIdEntry = Table.ID.of(parts[parts.length - 2]);
            if (!tableIdEntry.equals(tableId)) {
                log.error("Unexpected table id found: {}, expected {}; skipping", tableIdEntry, tableId);
                continue;
            }
            directory = parts[parts.length - 1];
        } else {
            directory = oldLocation.substring(Path.SEPARATOR.length());
        }
        Key key = entry.getKey();
        Mutation m = new Mutation(key.getRow());
        VolumeChooserEnvironment chooserEnv = new VolumeChooserEnvironment(tableId);
        final String newLocation = vm.choose(chooserEnv, ServerConstants.getBaseUris()) + Path.SEPARATOR + ServerConstants.TABLE_DIR + Path.SEPARATOR + tableId + Path.SEPARATOR + directory;
        m.put(key.getColumnFamily(), key.getColumnQualifier(), new Value(newLocation.getBytes(UTF_8)));
        if (log.isTraceEnabled()) {
            log.trace("Replacing {} with {}", oldLocation, newLocation);
        }
        writer.addMutation(m);
        pool.submit(new Runnable() {

            @Override
            public void run() {
                try {
                    vm.mkdirs(new Path(newLocation));
                } catch (IOException ex) {
                // nevermind
                }
            }
        });
        count++;
    }
    writer.close();
    pool.shutdown();
    while (!pool.isTerminated()) {
        log.trace("Waiting for mkdir() calls to finish");
        try {
            pool.awaitTermination(5, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            break;
        }
    }
    log.info("Updated {} entries for table {}", count, tableName);
    if (TableState.OFFLINE != tableState) {
        c.tableOperations().online(tableName, true);
        log.info("table {} back online", tableName);
    }
    return 0;
}
Also used : Path(org.apache.hadoop.fs.Path) VolumeManager(org.apache.accumulo.server.fs.VolumeManager) Scanner(org.apache.accumulo.core.client.Scanner) MetadataTable(org.apache.accumulo.core.metadata.MetadataTable) Table(org.apache.accumulo.core.client.impl.Table) ClientOnRequiredTable(org.apache.accumulo.core.cli.ClientOnRequiredTable) IOException(java.io.IOException) VolumeChooserEnvironment(org.apache.accumulo.server.fs.VolumeChooserEnvironment) Value(org.apache.accumulo.core.data.Value) BatchWriter(org.apache.accumulo.core.client.BatchWriter) Mutation(org.apache.accumulo.core.data.Mutation) SimpleThreadPool(org.apache.accumulo.core.util.SimpleThreadPool) Key(org.apache.accumulo.core.data.Key) TableState(org.apache.accumulo.core.master.state.tables.TableState)

Example 8 with SimpleThreadPool

use of org.apache.accumulo.core.util.SimpleThreadPool in project accumulo by apache.

the class TabletServer method run.

// main loop listens for client requests
@Override
public void run() {
    SecurityUtil.serverLogin(SiteConfiguration.getInstance());
    // We can just make the zookeeper paths before we try to use.
    try {
        ZooKeeperInitialization.ensureZooKeeperInitialized(ZooReaderWriter.getInstance(), ZooUtil.getRoot(getInstance()));
    } catch (KeeperException | InterruptedException e) {
        log.error("Could not ensure that ZooKeeper is properly initialized", e);
        throw new RuntimeException(e);
    }
    Metrics tserverMetrics = metricsFactory.createTabletServerMetrics(this);
    // Register MBeans
    try {
        tserverMetrics.register();
        mincMetrics.register();
        scanMetrics.register();
        updateMetrics.register();
    } catch (Exception e) {
        log.error("Error registering with JMX", e);
    }
    if (null != authKeyWatcher) {
        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 {
        walMarker.initWalMarker(getTabletSession());
    } catch (Exception e) {
        log.error("Unable to create WAL marker node in zookeeper", e);
        throw new RuntimeException(e);
    }
    ThreadPoolExecutor distWorkQThreadPool = new SimpleThreadPool(getConfiguration().getCount(Property.TSERV_WORKQ_THREADS), "distributed work queue");
    bulkFailedCopyQ = new DistributedWorkQueue(ZooUtil.getRoot(getInstance()) + Constants.ZBULK_FAILED_COPYQ, getConfiguration());
    try {
        bulkFailedCopyQ.startProcessing(new BulkFailedCopyProcessor(), 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);
    }
    // Start the thrift service listening for incoming replication requests
    try {
        replicationAddress = startReplicationService();
    } catch (UnknownHostException e) {
        throw new RuntimeException("Failed to start replication service", e);
    }
    // Start the pool to handle outgoing replications
    final ThreadPoolExecutor replicationThreadPool = new SimpleThreadPool(getConfiguration().getCount(Property.REPLICATION_WORKER_THREADS), "replication task");
    replWorker.setExecutor(replicationThreadPool);
    replWorker.run();
    // Check the configuration value for the size of the pool and, if changed, resize the pool, every 5 seconds);
    final AccumuloConfiguration aconf = getConfiguration();
    Runnable replicationWorkThreadPoolResizer = new Runnable() {

        @Override
        public void run() {
            int maxPoolSize = aconf.getCount(Property.REPLICATION_WORKER_THREADS);
            if (replicationThreadPool.getMaximumPoolSize() != maxPoolSize) {
                log.info("Resizing thread pool for sending replication work from {} to {}", replicationThreadPool.getMaximumPoolSize(), maxPoolSize);
                replicationThreadPool.setMaximumPoolSize(maxPoolSize);
            }
        }
    };
    SimpleTimer.getInstance(aconf).schedule(replicationWorkThreadPoolResizer, 10000, 30000);
    final long CLEANUP_BULK_LOADED_CACHE_MILLIS = 15 * 60 * 1000;
    SimpleTimer.getInstance(aconf).schedule(new BulkImportCacheCleaner(this), CLEANUP_BULK_LOADED_CACHE_MILLIS, CLEANUP_BULK_LOADED_CACHE_MILLIS);
    HostAndPort masterHost;
    while (!serverStopRequested) {
        // send all of the pending messages
        try {
            MasterMessage mm = null;
            MasterClientService.Client iface = null;
            try {
                // was requested
                while (mm == null && !serverStopRequested) {
                    mm = masterMessages.poll(1000, TimeUnit.MILLISECONDS);
                }
                // have a message to send to the master, so grab a
                // connection
                masterHost = getMasterAddress();
                iface = masterConnection(masterHost);
                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(rpcCreds(), getClientAddressString(), iface);
                        mm = null;
                    } catch (TException ex) {
                        log.warn("Error sending message: queuing message again");
                        masterMessages.putFirst(mm);
                        mm = null;
                        throw ex;
                    }
                    // if any messages are immediately available grab em and
                    // send them
                    mm = masterMessages.poll();
                }
            } finally {
                if (mm != null) {
                    masterMessages.putFirst(mm);
                }
                returnMasterConnection(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 master
            // loop back to the beginning and wait for a new one
            // this way we survive master failures
            log.error(getClientAddressString() + ": TServerInfo: Exception. Master 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");
    TServerUtils.stopTServer(this.replServer);
    log.debug("Stopping Thrift Servers");
    TServerUtils.stopTServer(server);
    try {
        log.debug("Closing filesystem");
        fs.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 : MasterMessage(org.apache.accumulo.tserver.mastermessage.MasterMessage) TException(org.apache.thrift.TException) UnknownHostException(java.net.UnknownHostException) IOException(java.io.IOException) IterationInterruptedException(org.apache.accumulo.core.iterators.IterationInterruptedException) TableNotFoundException(org.apache.accumulo.core.client.TableNotFoundException) ThriftSecurityException(org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException) IterationInterruptedException(org.apache.accumulo.core.iterators.IterationInterruptedException) TSampleNotPresentException(org.apache.accumulo.core.tabletserver.thrift.TSampleNotPresentException) WalMarkerException(org.apache.accumulo.server.log.WalStateManager.WalMarkerException) ConstraintViolationException(org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) ExecutionException(java.util.concurrent.ExecutionException) NotServingTabletException(org.apache.accumulo.core.tabletserver.thrift.NotServingTabletException) AccumuloSecurityException(org.apache.accumulo.core.client.AccumuloSecurityException) KeeperException(org.apache.zookeeper.KeeperException) NoSuchScanIDException(org.apache.accumulo.core.tabletserver.thrift.NoSuchScanIDException) CancellationException(java.util.concurrent.CancellationException) DistributedStoreException(org.apache.accumulo.server.master.state.DistributedStoreException) TException(org.apache.thrift.TException) NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) ThriftTableOperationException(org.apache.accumulo.core.client.impl.thrift.ThriftTableOperationException) BadLocationStateException(org.apache.accumulo.server.master.state.TabletLocationState.BadLocationStateException) TimeoutException(java.util.concurrent.TimeoutException) TabletClosedException(org.apache.accumulo.tserver.tablet.TabletClosedException) SampleNotPresentException(org.apache.accumulo.core.client.SampleNotPresentException) AccumuloException(org.apache.accumulo.core.client.AccumuloException) DistributedWorkQueue(org.apache.accumulo.server.zookeeper.DistributedWorkQueue) TServiceClient(org.apache.thrift.TServiceClient) HostAndPort(org.apache.accumulo.core.util.HostAndPort) TabletServerScanMetrics(org.apache.accumulo.tserver.metrics.TabletServerScanMetrics) Metrics(org.apache.accumulo.server.metrics.Metrics) TabletServerUpdateMetrics(org.apache.accumulo.tserver.metrics.TabletServerUpdateMetrics) BulkImportCacheCleaner(org.apache.accumulo.tserver.tablet.BulkImportCacheCleaner) LoggingRunnable(org.apache.accumulo.fate.util.LoggingRunnable) MasterClientService(org.apache.accumulo.core.master.thrift.MasterClientService) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) KeeperException(org.apache.zookeeper.KeeperException) SimpleThreadPool(org.apache.accumulo.core.util.SimpleThreadPool) AccumuloConfiguration(org.apache.accumulo.core.conf.AccumuloConfiguration)

Example 9 with SimpleThreadPool

use of org.apache.accumulo.core.util.SimpleThreadPool in project accumulo by apache.

the class BalanceWithOfflineTableIT method test.

@Test
public void test() throws Exception {
    final String[] tableNames = getUniqueNames(2);
    final String tableName = tableNames[0];
    // create a table with a bunch of splits
    final Connector c = getConnector();
    log.info("Creating table {}", tableName);
    c.tableOperations().create(tableName);
    final SortedSet<Text> splits = new TreeSet<>();
    for (String split : "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z".split(",")) {
        splits.add(new Text(split));
    }
    log.info("Splitting table {}", tableName);
    c.tableOperations().addSplits(tableName, splits);
    log.info("Balancing");
    c.instanceOperations().waitForBalance();
    log.info("Balanced");
    // create a new table which will unbalance the cluster
    final String table2 = tableNames[1];
    log.info("Creating table {}", table2);
    c.tableOperations().create(table2);
    log.info("Creating splits {}", table2);
    c.tableOperations().addSplits(table2, splits);
    // offline the table, hopefully while there are some migrations going on
    log.info("Offlining {}", table2);
    c.tableOperations().offline(table2, true);
    log.info("Offlined {}", table2);
    log.info("Waiting for balance");
    SimpleThreadPool pool = new SimpleThreadPool(1, "waitForBalance");
    Future<Boolean> wait = pool.submit(new Callable<Boolean>() {

        @Override
        public Boolean call() throws Exception {
            c.instanceOperations().waitForBalance();
            return true;
        }
    });
    wait.get(20, TimeUnit.SECONDS);
    log.info("Balance succeeded with an offline table");
}
Also used : Connector(org.apache.accumulo.core.client.Connector) TreeSet(java.util.TreeSet) Text(org.apache.hadoop.io.Text) SimpleThreadPool(org.apache.accumulo.core.util.SimpleThreadPool) Test(org.junit.Test)

Aggregations

SimpleThreadPool (org.apache.accumulo.core.util.SimpleThreadPool)9 IOException (java.io.IOException)4 ArrayList (java.util.ArrayList)3 TreeSet (java.util.TreeSet)3 ThreadPoolExecutor (java.util.concurrent.ThreadPoolExecutor)3 LoggingRunnable (org.apache.accumulo.fate.util.LoggingRunnable)3 Path (org.apache.hadoop.fs.Path)3 Text (org.apache.hadoop.io.Text)3 Test (org.junit.Test)3 Future (java.util.concurrent.Future)2 BatchWriter (org.apache.accumulo.core.client.BatchWriter)2 Connector (org.apache.accumulo.core.client.Connector)2 Scanner (org.apache.accumulo.core.client.Scanner)2 TableNotFoundException (org.apache.accumulo.core.client.TableNotFoundException)2 Key (org.apache.accumulo.core.data.Key)2 Mutation (org.apache.accumulo.core.data.Mutation)2 Value (org.apache.accumulo.core.data.Value)2 VolumeManager (org.apache.accumulo.server.fs.VolumeManager)2 FileNotFoundException (java.io.FileNotFoundException)1 UnknownHostException (java.net.UnknownHostException)1