Search in sources :

Example 1 with KeyExtent

use of org.apache.accumulo.core.data.impl.KeyExtent in project accumulo by apache.

the class SplitRecoveryIT method test.

@Test
public void test() throws Exception {
    String tableName = getUniqueNames(1)[0];
    for (int tn = 0; tn < 2; tn++) {
        Connector connector = getConnector();
        // create a table and put some data in it
        connector.tableOperations().create(tableName);
        BatchWriter bw = connector.createBatchWriter(tableName, new BatchWriterConfig());
        bw.addMutation(m("a"));
        bw.addMutation(m("b"));
        bw.addMutation(m("c"));
        bw.close();
        // take the table offline
        connector.tableOperations().offline(tableName);
        while (!isOffline(tableName, connector)) sleepUninterruptibly(200, TimeUnit.MILLISECONDS);
        // poke a partial split into the metadata table
        connector.securityOperations().grantTablePermission(getAdminPrincipal(), MetadataTable.NAME, TablePermission.WRITE);
        Table.ID tableId = Table.ID.of(connector.tableOperations().tableIdMap().get(tableName));
        KeyExtent extent = new KeyExtent(tableId, null, new Text("b"));
        Mutation m = extent.getPrevRowUpdateMutation();
        TabletsSection.TabletColumnFamily.SPLIT_RATIO_COLUMN.put(m, new Value(Double.toString(0.5).getBytes()));
        TabletsSection.TabletColumnFamily.OLD_PREV_ROW_COLUMN.put(m, KeyExtent.encodePrevEndRow(null));
        bw = connector.createBatchWriter(MetadataTable.NAME, new BatchWriterConfig());
        bw.addMutation(m);
        if (tn == 1) {
            bw.flush();
            try (Scanner scanner = connector.createScanner(MetadataTable.NAME, Authorizations.EMPTY)) {
                scanner.setRange(extent.toMetadataRange());
                scanner.fetchColumnFamily(DataFileColumnFamily.NAME);
                KeyExtent extent2 = new KeyExtent(tableId, new Text("b"), null);
                m = extent2.getPrevRowUpdateMutation();
                TabletsSection.ServerColumnFamily.DIRECTORY_COLUMN.put(m, new Value("/t2".getBytes()));
                TabletsSection.ServerColumnFamily.TIME_COLUMN.put(m, new Value("M0".getBytes()));
                for (Entry<Key, Value> entry : scanner) {
                    m.put(DataFileColumnFamily.NAME, entry.getKey().getColumnQualifier(), entry.getValue());
                }
                bw.addMutation(m);
            }
        }
        bw.close();
        // bring the table online
        connector.tableOperations().online(tableName);
        // verify the tablets went online
        try (Scanner scanner = connector.createScanner(tableName, Authorizations.EMPTY)) {
            int i = 0;
            String[] expected = { "a", "b", "c" };
            for (Entry<Key, Value> entry : scanner) {
                assertEquals(expected[i], entry.getKey().getRow().toString());
                i++;
            }
            assertEquals(3, i);
            connector.tableOperations().delete(tableName);
        }
    }
}
Also used : Connector(org.apache.accumulo.core.client.Connector) Scanner(org.apache.accumulo.core.client.Scanner) Table(org.apache.accumulo.core.client.impl.Table) MetadataTable(org.apache.accumulo.core.metadata.MetadataTable) Text(org.apache.hadoop.io.Text) KeyExtent(org.apache.accumulo.core.data.impl.KeyExtent) Value(org.apache.accumulo.core.data.Value) BatchWriterConfig(org.apache.accumulo.core.client.BatchWriterConfig) BatchWriter(org.apache.accumulo.core.client.BatchWriter) Mutation(org.apache.accumulo.core.data.Mutation) Key(org.apache.accumulo.core.data.Key) Test(org.junit.Test)

Example 2 with KeyExtent

use of org.apache.accumulo.core.data.impl.KeyExtent in project accumulo by apache.

the class VolumeIT method testRelativePaths.

@Test
public void testRelativePaths() throws Exception {
    List<String> expected = new ArrayList<>();
    Connector connector = getConnector();
    String tableName = getUniqueNames(1)[0];
    connector.tableOperations().create(tableName, new NewTableConfiguration().withoutDefaultIterators());
    Table.ID tableId = Table.ID.of(connector.tableOperations().tableIdMap().get(tableName));
    SortedSet<Text> partitions = new TreeSet<>();
    // with some splits
    for (String s : "c,g,k,p,s,v".split(",")) partitions.add(new Text(s));
    connector.tableOperations().addSplits(tableName, partitions);
    BatchWriter bw = connector.createBatchWriter(tableName, new BatchWriterConfig());
    // create two files in each tablet
    String[] rows = "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(",");
    for (String s : rows) {
        Mutation m = new Mutation(s);
        m.put("cf1", "cq1", "1");
        bw.addMutation(m);
        expected.add(s + ":cf1:cq1:1");
    }
    bw.flush();
    connector.tableOperations().flush(tableName, null, null, true);
    for (String s : rows) {
        Mutation m = new Mutation(s);
        m.put("cf1", "cq1", "2");
        bw.addMutation(m);
        expected.add(s + ":cf1:cq1:2");
    }
    bw.close();
    connector.tableOperations().flush(tableName, null, null, true);
    verifyData(expected, connector.createScanner(tableName, Authorizations.EMPTY));
    connector.tableOperations().offline(tableName, true);
    connector.securityOperations().grantTablePermission("root", MetadataTable.NAME, TablePermission.WRITE);
    try (Scanner metaScanner = connector.createScanner(MetadataTable.NAME, Authorizations.EMPTY)) {
        metaScanner.fetchColumnFamily(MetadataSchema.TabletsSection.DataFileColumnFamily.NAME);
        metaScanner.setRange(new KeyExtent(tableId, null, null).toMetadataRange());
        BatchWriter mbw = connector.createBatchWriter(MetadataTable.NAME, new BatchWriterConfig());
        for (Entry<Key, Value> entry : metaScanner) {
            String cq = entry.getKey().getColumnQualifier().toString();
            if (cq.startsWith(v1.toString())) {
                Path path = new Path(cq);
                String relPath = "/" + path.getParent().getName() + "/" + path.getName();
                Mutation fileMut = new Mutation(entry.getKey().getRow());
                fileMut.putDelete(entry.getKey().getColumnFamily(), entry.getKey().getColumnQualifier());
                fileMut.put(entry.getKey().getColumnFamily().toString(), relPath, entry.getValue().toString());
                mbw.addMutation(fileMut);
            }
        }
        mbw.close();
        connector.tableOperations().online(tableName, true);
        verifyData(expected, connector.createScanner(tableName, Authorizations.EMPTY));
        connector.tableOperations().compact(tableName, null, null, true, true);
        verifyData(expected, connector.createScanner(tableName, Authorizations.EMPTY));
        for (Entry<Key, Value> entry : metaScanner) {
            String cq = entry.getKey().getColumnQualifier().toString();
            Path path = new Path(cq);
            Assert.assertTrue("relative path not deleted " + path.toString(), path.depth() > 2);
        }
    }
}
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) ArrayList(java.util.ArrayList) Text(org.apache.hadoop.io.Text) KeyExtent(org.apache.accumulo.core.data.impl.KeyExtent) NewTableConfiguration(org.apache.accumulo.core.client.admin.NewTableConfiguration) TreeSet(java.util.TreeSet) Value(org.apache.accumulo.core.data.Value) BatchWriterConfig(org.apache.accumulo.core.client.BatchWriterConfig) BatchWriter(org.apache.accumulo.core.client.BatchWriter) Mutation(org.apache.accumulo.core.data.Mutation) Key(org.apache.accumulo.core.data.Key) Test(org.junit.Test)

Example 3 with KeyExtent

use of org.apache.accumulo.core.data.impl.KeyExtent 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 4 with KeyExtent

use of org.apache.accumulo.core.data.impl.KeyExtent in project accumulo by apache.

the class BulkImporter method assignMapFiles.

private Map<Path, List<KeyExtent>> assignMapFiles(String tableName, Map<Path, List<AssignmentInfo>> assignments, Map<KeyExtent, String> locations, int numThreads) {
    // group assignments by tablet
    Map<KeyExtent, List<PathSize>> assignmentsPerTablet = new TreeMap<>();
    for (Entry<Path, List<AssignmentInfo>> entry : assignments.entrySet()) {
        Path mapFile = entry.getKey();
        List<AssignmentInfo> tabletsToAssignMapFileTo = entry.getValue();
        for (AssignmentInfo ai : tabletsToAssignMapFileTo) {
            List<PathSize> mapFiles = assignmentsPerTablet.get(ai.ke);
            if (mapFiles == null) {
                mapFiles = new ArrayList<>();
                assignmentsPerTablet.put(ai.ke, mapFiles);
            }
            mapFiles.add(new PathSize(mapFile, ai.estSize));
        }
    }
    // group assignments by tabletserver
    Map<Path, List<KeyExtent>> assignmentFailures = Collections.synchronizedMap(new TreeMap<Path, List<KeyExtent>>());
    TreeMap<String, Map<KeyExtent, List<PathSize>>> assignmentsPerTabletServer = new TreeMap<>();
    for (Entry<KeyExtent, List<PathSize>> entry : assignmentsPerTablet.entrySet()) {
        KeyExtent ke = entry.getKey();
        String location = locations.get(ke);
        if (location == null) {
            for (PathSize pathSize : entry.getValue()) {
                synchronized (assignmentFailures) {
                    List<KeyExtent> failures = assignmentFailures.get(pathSize.path);
                    if (failures == null) {
                        failures = new ArrayList<>();
                        assignmentFailures.put(pathSize.path, failures);
                    }
                    failures.add(ke);
                }
            }
            log.warn("Could not assign {} map files to tablet {} because it had no location, will retry ...", entry.getValue().size(), ke);
            continue;
        }
        Map<KeyExtent, List<PathSize>> apt = assignmentsPerTabletServer.get(location);
        if (apt == null) {
            apt = new TreeMap<>();
            assignmentsPerTabletServer.put(location, apt);
        }
        apt.put(entry.getKey(), entry.getValue());
    }
    ExecutorService threadPool = Executors.newFixedThreadPool(numThreads, new NamingThreadFactory("submit"));
    for (Entry<String, Map<KeyExtent, List<PathSize>>> entry : assignmentsPerTabletServer.entrySet()) {
        String location = entry.getKey();
        threadPool.submit(new AssignmentTask(assignmentFailures, tableName, location, entry.getValue()));
    }
    threadPool.shutdown();
    while (!threadPool.isTerminated()) {
        try {
            threadPool.awaitTermination(60, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            log.error("Encountered InterruptedException while waiting for the thread pool to terminate.", e);
            throw new RuntimeException(e);
        }
    }
    return assignmentFailures;
}
Also used : NamingThreadFactory(org.apache.accumulo.core.util.NamingThreadFactory) TKeyExtent(org.apache.accumulo.core.data.thrift.TKeyExtent) KeyExtent(org.apache.accumulo.core.data.impl.KeyExtent) List(java.util.List) ArrayList(java.util.ArrayList) Path(org.apache.hadoop.fs.Path) TreeMap(java.util.TreeMap) ExecutorService(java.util.concurrent.ExecutorService) Map(java.util.Map) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap)

Example 5 with KeyExtent

use of org.apache.accumulo.core.data.impl.KeyExtent in project accumulo by apache.

the class BulkImporter method assignMapFiles.

private List<KeyExtent> assignMapFiles(ClientContext context, HostAndPort location, Map<KeyExtent, List<PathSize>> assignmentsPerTablet) throws AccumuloException, AccumuloSecurityException {
    try {
        long timeInMillis = context.getConfiguration().getTimeInMillis(Property.TSERV_BULK_TIMEOUT);
        TabletClientService.Iface client = ThriftUtil.getTServerClient(location, context, timeInMillis);
        try {
            HashMap<KeyExtent, Map<String, org.apache.accumulo.core.data.thrift.MapFileInfo>> files = new HashMap<>();
            for (Entry<KeyExtent, List<PathSize>> entry : assignmentsPerTablet.entrySet()) {
                HashMap<String, org.apache.accumulo.core.data.thrift.MapFileInfo> tabletFiles = new HashMap<>();
                files.put(entry.getKey(), tabletFiles);
                for (PathSize pathSize : entry.getValue()) {
                    org.apache.accumulo.core.data.thrift.MapFileInfo mfi = new org.apache.accumulo.core.data.thrift.MapFileInfo(pathSize.estSize);
                    tabletFiles.put(pathSize.path.toString(), mfi);
                }
            }
            log.debug("Asking {} to bulk load {}", location, files);
            List<TKeyExtent> failures = client.bulkImport(Tracer.traceInfo(), context.rpcCreds(), tid, Translator.translate(files, Translators.KET), setTime);
            return Translator.translate(failures, Translators.TKET);
        } finally {
            ThriftUtil.returnClient((TServiceClient) client);
        }
    } catch (ThriftSecurityException e) {
        throw new AccumuloSecurityException(e.user, e.code, e);
    } catch (Throwable t) {
        log.error("Encountered unknown exception in assignMapFiles.", t);
        throw new AccumuloException(t);
    }
}
Also used : HashMap(java.util.HashMap) TKeyExtent(org.apache.accumulo.core.data.thrift.TKeyExtent) KeyExtent(org.apache.accumulo.core.data.impl.KeyExtent) List(java.util.List) ArrayList(java.util.ArrayList) AccumuloSecurityException(org.apache.accumulo.core.client.AccumuloSecurityException) AccumuloException(org.apache.accumulo.core.client.AccumuloException) TKeyExtent(org.apache.accumulo.core.data.thrift.TKeyExtent) ThriftSecurityException(org.apache.accumulo.core.client.impl.thrift.ThriftSecurityException) TabletClientService(org.apache.accumulo.core.tabletserver.thrift.TabletClientService) Map(java.util.Map) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap)

Aggregations

KeyExtent (org.apache.accumulo.core.data.impl.KeyExtent)219 Test (org.junit.Test)84 Text (org.apache.hadoop.io.Text)82 Value (org.apache.accumulo.core.data.Value)67 ArrayList (java.util.ArrayList)63 Key (org.apache.accumulo.core.data.Key)59 HashMap (java.util.HashMap)50 Mutation (org.apache.accumulo.core.data.Mutation)40 Scanner (org.apache.accumulo.core.client.Scanner)39 Range (org.apache.accumulo.core.data.Range)39 TreeMap (java.util.TreeMap)37 TServerInstance (org.apache.accumulo.server.master.state.TServerInstance)36 Table (org.apache.accumulo.core.client.impl.Table)34 HashSet (java.util.HashSet)30 List (java.util.List)29 TKeyExtent (org.apache.accumulo.core.data.thrift.TKeyExtent)29 Connector (org.apache.accumulo.core.client.Connector)28 IOException (java.io.IOException)27 MetadataTable (org.apache.accumulo.core.metadata.MetadataTable)25 DataFileValue (org.apache.accumulo.core.metadata.schema.DataFileValue)25