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);
}
}
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;
}
}
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());
}
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");
}
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);
}
Aggregations