You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by ct...@apache.org on 2020/01/11 06:56:56 UTC

[accumulo] branch master updated: Fix #1373 Support the init scope in some VolumeChoosers (#1450)

This is an automated email from the ASF dual-hosted git repository.

ctubbsii pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/accumulo.git


The following commit(s) were added to refs/heads/master by this push:
     new f36445a  Fix #1373 Support the init scope in some VolumeChoosers (#1450)
f36445a is described below

commit f36445a220a39b5e12e678d6d63541268942c4e9
Author: Karthick Narendran <ka...@gmail.com>
AuthorDate: Sat Jan 11 06:56:46 2020 +0000

    Fix #1373 Support the init scope in some VolumeChoosers (#1450)
    
    * Support the init scope in PerTableVolumeChooser and PreferredVolumeChooser
    * Update corresponding unit tests for updated choosers to test configuring the init scope
    * Update VolumeChooserIT to include config for the init scope
    * Implement tableId and endRow  methods in VolumeChooserEnvironmentImpl for init scope
    * Update Initialize to provide the tableIds and endRows in the VolumeChooserEnvironment when choosing volumes during initialization
---
 .../org/apache/accumulo/server/ServerContext.java  |  9 ++++++
 .../org/apache/accumulo/server/ServerInfo.java     | 16 +++++++++++
 .../accumulo/server/fs/PerTableVolumeChooser.java  | 13 ++-------
 .../accumulo/server/fs/PreferredVolumeChooser.java | 13 ++-------
 .../server/fs/VolumeChooserEnvironmentImpl.java    | 13 +++++++--
 .../apache/accumulo/server/init/Initialize.java    | 27 +++++++++++++-----
 .../server/fs/PerTableVolumeChooserTest.java       | 32 +++++++++++++++++-----
 .../server/fs/PreferredVolumeChooserTest.java      | 31 +++++++++++++++------
 .../org/apache/accumulo/test/VolumeChooserIT.java  |  2 ++
 9 files changed, 111 insertions(+), 45 deletions(-)

diff --git a/server/base/src/main/java/org/apache/accumulo/server/ServerContext.java b/server/base/src/main/java/org/apache/accumulo/server/ServerContext.java
index 0101252..5844b00 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/ServerContext.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/ServerContext.java
@@ -68,6 +68,10 @@ public class ServerContext extends ClientContext {
     this(new ServerInfo(siteConfig, instanceName, zooKeepers, zooKeepersSessionTimeOut));
   }
 
+  public ServerContext(SiteConfiguration siteConfig, String instanceName, String instanceID) {
+    this(new ServerInfo(siteConfig, instanceName, instanceID));
+  }
+
   public ServerContext(SiteConfiguration siteConfig, Properties clientProps) {
     this(siteConfig, ClientInfo.from(clientProps));
   }
@@ -83,6 +87,11 @@ public class ServerContext extends ClientContext {
     zooReaderWriter = new ZooReaderWriter(info.getSiteConfiguration());
   }
 
+  @Override
+  public String getInstanceID() {
+    return info.getInstanceID();
+  }
+
   /**
    * Should only be called by the Tablet server
    */
diff --git a/server/base/src/main/java/org/apache/accumulo/server/ServerInfo.java b/server/base/src/main/java/org/apache/accumulo/server/ServerInfo.java
index 09f595c..51ef02a 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/ServerInfo.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/ServerInfo.java
@@ -101,6 +101,22 @@ public class ServerInfo implements ClientInfo {
     instanceName = InstanceOperationsImpl.lookupInstanceName(zooCache, UUID.fromString(instanceID));
   }
 
+  ServerInfo(SiteConfiguration config, String instanceName, String instanceID) {
+    SingletonManager.setMode(Mode.SERVER);
+    siteConfig = config;
+    hadoopConf = new Configuration();
+    try {
+      volumeManager = VolumeManagerImpl.get(siteConfig, hadoopConf);
+    } catch (IOException e) {
+      throw new IllegalStateException(e);
+    }
+    this.instanceID = instanceID;
+    zooKeepers = config.get(Property.INSTANCE_ZK_HOST);
+    zooKeepersSessionTimeOut = (int) config.getTimeInMillis(Property.INSTANCE_ZK_TIMEOUT);
+    zooCache = new ZooCacheFactory().getZooCache(zooKeepers, zooKeepersSessionTimeOut);
+    this.instanceName = instanceName;
+  }
+
   public SiteConfiguration getSiteConfiguration() {
     return siteConfig;
   }
diff --git a/server/base/src/main/java/org/apache/accumulo/server/fs/PerTableVolumeChooser.java b/server/base/src/main/java/org/apache/accumulo/server/fs/PerTableVolumeChooser.java
index 5b95149..24d2ede 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/fs/PerTableVolumeChooser.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/fs/PerTableVolumeChooser.java
@@ -67,17 +67,10 @@ public class PerTableVolumeChooser implements VolumeChooser {
 
   // visible (not private) for testing
   VolumeChooser getDelegateChooser(VolumeChooserEnvironment env) {
-    switch (env.getScope()) {
-      case INIT:
-        // TODO should be possible to read from SiteConfiguration during init
-        log.warn("Not possible to determine delegate chooser at '{}' scope. Using {}.",
-            ChooserScope.INIT, RandomVolumeChooser.class.getName());
-        return randomChooser;
-      case TABLE:
-        return getVolumeChooserForTable(env);
-      default:
-        return getVolumeChooserForScope(env);
+    if (env.getScope() == ChooserScope.TABLE) {
+      return getVolumeChooserForTable(env);
     }
+    return getVolumeChooserForScope(env);
   }
 
   private VolumeChooser getVolumeChooserForTable(VolumeChooserEnvironment env) {
diff --git a/server/base/src/main/java/org/apache/accumulo/server/fs/PreferredVolumeChooser.java b/server/base/src/main/java/org/apache/accumulo/server/fs/PreferredVolumeChooser.java
index f46ed24..332207a 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/fs/PreferredVolumeChooser.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/fs/PreferredVolumeChooser.java
@@ -64,17 +64,10 @@ public class PreferredVolumeChooser extends RandomVolumeChooser {
 
   // visible (not private) for testing
   String[] getPreferredVolumes(VolumeChooserEnvironment env, String[] options) {
-    switch (env.getScope()) {
-      case INIT:
-        // TODO should be possible to read from SiteConfiguration during init
-        log.warn("Not possible to determine preferred volumes at '{}' scope. Using all volumes.",
-            ChooserScope.INIT);
-        return options;
-      case TABLE:
-        return getPreferredVolumesForTable(env, options);
-      default:
-        return getPreferredVolumesForScope(env, options);
+    if (env.getScope() == ChooserScope.TABLE) {
+      return getPreferredVolumesForTable(env, options);
     }
+    return getPreferredVolumesForScope(env, options);
   }
 
   private String[] getPreferredVolumesForTable(VolumeChooserEnvironment env, String[] options) {
diff --git a/server/base/src/main/java/org/apache/accumulo/server/fs/VolumeChooserEnvironmentImpl.java b/server/base/src/main/java/org/apache/accumulo/server/fs/VolumeChooserEnvironmentImpl.java
index 5b67bae..84b02a6 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/fs/VolumeChooserEnvironmentImpl.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/fs/VolumeChooserEnvironmentImpl.java
@@ -53,7 +53,14 @@ public class VolumeChooserEnvironmentImpl implements VolumeChooserEnvironment {
     this.scope = ChooserScope.TABLE;
     this.tableId = Objects.requireNonNull(tableId);
     this.endRow = endRow;
+  }
 
+  public VolumeChooserEnvironmentImpl(ChooserScope scope, TableId tableId, Text endRow,
+      ServerContext context) {
+    this.context = context;
+    this.scope = Objects.requireNonNull(scope);
+    this.tableId = Objects.requireNonNull(tableId);
+    this.endRow = endRow;
   }
 
   /**
@@ -64,19 +71,19 @@ public class VolumeChooserEnvironmentImpl implements VolumeChooserEnvironment {
    */
   @Override
   public Text getEndRow() {
-    if (scope != ChooserScope.TABLE)
+    if (scope != ChooserScope.TABLE && scope != ChooserScope.INIT)
       throw new IllegalStateException("Can only request end row for tables, not for " + scope);
     return endRow;
   }
 
   @Override
   public boolean hasTableId() {
-    return scope == ChooserScope.TABLE;
+    return scope == ChooserScope.TABLE || scope == ChooserScope.INIT;
   }
 
   @Override
   public TableId getTableId() {
-    if (scope != ChooserScope.TABLE)
+    if (scope != ChooserScope.TABLE && scope != ChooserScope.INIT)
       throw new IllegalStateException("Can only request table id for tables, not for " + scope);
     return tableId;
   }
diff --git a/server/base/src/main/java/org/apache/accumulo/server/init/Initialize.java b/server/base/src/main/java/org/apache/accumulo/server/init/Initialize.java
index 403bcb2..0b180f5 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/init/Initialize.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/init/Initialize.java
@@ -362,7 +362,10 @@ public class Initialize implements KeywordExecutable {
     UUID uuid = UUID.randomUUID();
     // the actual disk locations of the root table and tablets
     String[] configuredVolumes = VolumeConfiguration.getVolumeUris(siteConfig, hadoopConf);
-    VolumeChooserEnvironment chooserEnv = new VolumeChooserEnvironmentImpl(ChooserScope.INIT, null);
+    String instanceName = instanceNamePath.substring(getInstanceNamePrefix().length());
+    ServerContext serverContext = new ServerContext(siteConfig, instanceName, uuid.toString());
+    VolumeChooserEnvironment chooserEnv =
+        new VolumeChooserEnvironmentImpl(ChooserScope.INIT, RootTable.ID, null, serverContext);
     String rootTabletDirName = RootTable.ROOT_TABLET_DIR_NAME;
     String ext = FileOperations.getNewFileExtension(DefaultConfiguration.getInstance());
     String rootTabletFileUri = new Path(fs.choose(chooserEnv, configuredVolumes) + Path.SEPARATOR
@@ -381,7 +384,7 @@ public class Initialize implements KeywordExecutable {
           new Path(fs.choose(chooserEnv, configuredVolumes) + Path.SEPARATOR
               + ServerConstants.TABLE_DIR + Path.SEPARATOR + RootTable.ID + rootTabletDirName)
                   .toString(),
-          rootTabletFileUri);
+          rootTabletFileUri, serverContext);
     } catch (Exception e) {
       log.error("FATAL Failed to initialize filesystem", e);
 
@@ -497,24 +500,31 @@ public class Initialize implements KeywordExecutable {
   }
 
   private void initFileSystem(SiteConfiguration siteConfig, Configuration hadoopConf,
-      VolumeManager fs, UUID uuid, String rootTabletDirUri, String rootTabletFileUri)
-      throws IOException {
+      VolumeManager fs, UUID uuid, String rootTabletDirUri, String rootTabletFileUri,
+      ServerContext serverContext) throws IOException {
     initDirs(fs, uuid, VolumeConfiguration.getVolumeUris(siteConfig, hadoopConf), false);
 
     // initialize initial system tables config in zookeeper
     initSystemTablesConfig(zoo, Constants.ZROOT + "/" + uuid, hadoopConf);
 
-    VolumeChooserEnvironment chooserEnv = new VolumeChooserEnvironmentImpl(ChooserScope.INIT, null);
+    Text splitPoint = TabletsSection.getRange().getEndKey().getRow();
+
+    VolumeChooserEnvironment chooserEnv = new VolumeChooserEnvironmentImpl(ChooserScope.INIT,
+        MetadataTable.ID, splitPoint, serverContext);
     String tableMetadataTabletDirName = TABLE_TABLETS_TABLET_DIR;
     String tableMetadataTabletDirUri =
         fs.choose(chooserEnv, ServerConstants.getBaseUris(siteConfig, hadoopConf))
             + Constants.HDFS_TABLES_DIR + Path.SEPARATOR + MetadataTable.ID + Path.SEPARATOR
             + tableMetadataTabletDirName;
+    chooserEnv = new VolumeChooserEnvironmentImpl(ChooserScope.INIT, ReplicationTable.ID, null,
+        serverContext);
     String replicationTableDefaultTabletDirName = ServerColumnFamily.DEFAULT_TABLET_DIR_NAME;
     String replicationTableDefaultTabletDirUri =
         fs.choose(chooserEnv, ServerConstants.getBaseUris(siteConfig, hadoopConf))
             + Constants.HDFS_TABLES_DIR + Path.SEPARATOR + ReplicationTable.ID + Path.SEPARATOR
             + replicationTableDefaultTabletDirName;
+    chooserEnv =
+        new VolumeChooserEnvironmentImpl(ChooserScope.INIT, MetadataTable.ID, null, serverContext);
     String defaultMetadataTabletDirName = ServerColumnFamily.DEFAULT_TABLET_DIR_NAME;
     String defaultMetadataTabletDirUri =
         fs.choose(chooserEnv, ServerConstants.getBaseUris(siteConfig, hadoopConf))
@@ -535,7 +545,6 @@ public class Initialize implements KeywordExecutable {
     createMetadataFile(fs, metadataFileName, siteConfig, replicationTablet);
 
     // populate the root tablet with info about the metadata table's two initial tablets
-    Text splitPoint = TabletsSection.getRange().getEndKey().getRow();
     Tablet tablesTablet = new Tablet(MetadataTable.ID, tableMetadataTabletDirName, null, splitPoint,
         metadataFileName);
     Tablet defaultTablet =
@@ -688,6 +697,10 @@ public class Initialize implements KeywordExecutable {
         NodeExistsPolicy.FAIL);
   }
 
+  private String getInstanceNamePrefix() {
+    return Constants.ZROOT + Constants.ZINSTANCES + "/";
+  }
+
   private String getInstanceNamePath(Opts opts)
       throws IOException, KeeperException, InterruptedException {
     // setup the instance name
@@ -706,7 +719,7 @@ public class Initialize implements KeywordExecutable {
       if (instanceName.length() == 0) {
         continue;
       }
-      instanceNamePath = Constants.ZROOT + Constants.ZINSTANCES + "/" + instanceName;
+      instanceNamePath = getInstanceNamePrefix() + instanceName;
       if (opts.clearInstanceName) {
         exists = false;
       } else {
diff --git a/server/base/src/test/java/org/apache/accumulo/server/fs/PerTableVolumeChooserTest.java b/server/base/src/test/java/org/apache/accumulo/server/fs/PerTableVolumeChooserTest.java
index fda4584..eb1d9a6 100644
--- a/server/base/src/test/java/org/apache/accumulo/server/fs/PerTableVolumeChooserTest.java
+++ b/server/base/src/test/java/org/apache/accumulo/server/fs/PerTableVolumeChooserTest.java
@@ -96,13 +96,6 @@ public class PerTableVolumeChooserTest {
   }
 
   @Test
-  public void testInitScopeSelectsRandomChooser() {
-    replay(serviceEnv, tableConf, systemConf);
-    VolumeChooser delegate = getDelegate(ChooserScope.INIT);
-    assertSame(RandomVolumeChooser.class, delegate.getClass());
-  }
-
-  @Test
   public void testTableScopeUsingTableProperty() throws Exception {
     expect(tableConf.getTableCustom(TABLE_CUSTOM_SUFFIX)).andReturn(MockChooser1.class.getName());
     expect(serviceEnv.instantiate(TableId.of("testTable"), MockChooser1.class.getName(),
@@ -206,4 +199,29 @@ public class PerTableVolumeChooserTest {
     fail("should not reach");
   }
 
+  @Test
+  public void testInitScopeUsingInitProperty() throws Exception {
+    expect(systemConf.getCustom(getCustomPropertySuffix(ChooserScope.INIT)))
+        .andReturn(MockChooser1.class.getName()).once();
+    expect(serviceEnv.instantiate(MockChooser1.class.getName(), VolumeChooser.class))
+        .andReturn(new MockChooser1());
+    replay(serviceEnv, tableConf, systemConf);
+
+    VolumeChooser delegate = getDelegate(ChooserScope.INIT);
+    assertSame(MockChooser1.class, delegate.getClass());
+  }
+
+  @Test
+  public void testInitScopeUsingDefaultProperty() throws Exception {
+    expect(systemConf.getCustom(getCustomPropertySuffix(ChooserScope.INIT))).andReturn(null).once();
+    expect(systemConf.getCustom(getCustomPropertySuffix(ChooserScope.DEFAULT)))
+        .andReturn(MockChooser2.class.getName()).once();
+    expect(serviceEnv.instantiate(MockChooser2.class.getName(), VolumeChooser.class))
+        .andReturn(new MockChooser2());
+    replay(serviceEnv, tableConf, systemConf);
+
+    VolumeChooser delegate = getDelegate(ChooserScope.INIT);
+    assertSame(MockChooser2.class, delegate.getClass());
+  }
+
 }
diff --git a/server/base/src/test/java/org/apache/accumulo/server/fs/PreferredVolumeChooserTest.java b/server/base/src/test/java/org/apache/accumulo/server/fs/PreferredVolumeChooserTest.java
index 2561a7b..f1b1364 100644
--- a/server/base/src/test/java/org/apache/accumulo/server/fs/PreferredVolumeChooserTest.java
+++ b/server/base/src/test/java/org/apache/accumulo/server/fs/PreferredVolumeChooserTest.java
@@ -24,7 +24,6 @@ import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
 import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertSame;
 import static org.junit.Assert.fail;
 
 import java.util.Arrays;
@@ -97,13 +96,6 @@ public class PreferredVolumeChooserTest {
   }
 
   @Test
-  public void testInitScopeSelectsRandomlyFromAll() {
-    replay(serviceEnv, tableConf, systemConf);
-    String[] volumes = choose(ChooserScope.INIT);
-    assertSame(ALL_OPTIONS, volumes);
-  }
-
-  @Test
   public void testTableScopeUsingTableProperty() {
     expect(tableConf.getTableCustom(TABLE_CUSTOM_SUFFIX)).andReturn("2,1");
     replay(serviceEnv, tableConf, systemConf);
@@ -220,4 +212,27 @@ public class PreferredVolumeChooserTest {
     fail("should not reach");
   }
 
+  @Test
+  public void testInitScopeUsingInitProperty() {
+    expect(systemConf.getCustom(getCustomPropertySuffix(ChooserScope.INIT))).andReturn("2,1")
+        .once();
+    replay(serviceEnv, tableConf, systemConf);
+
+    String[] volumes = choose(ChooserScope.INIT);
+    Arrays.sort(volumes);
+    assertArrayEquals(new String[] {"1", "2"}, volumes);
+  }
+
+  @Test
+  public void testInitScopeUsingDefaultProperty() {
+    expect(systemConf.getCustom(getCustomPropertySuffix(ChooserScope.INIT))).andReturn(null).once();
+    expect(systemConf.getCustom(getCustomPropertySuffix(ChooserScope.DEFAULT))).andReturn("3,2")
+        .once();
+    replay(serviceEnv, tableConf, systemConf);
+
+    String[] volumes = choose(ChooserScope.INIT);
+    Arrays.sort(volumes);
+    assertArrayEquals(new String[] {"2", "3"}, volumes);
+  }
+
 }
diff --git a/test/src/main/java/org/apache/accumulo/test/VolumeChooserIT.java b/test/src/main/java/org/apache/accumulo/test/VolumeChooserIT.java
index 9367da6..d1b5761 100644
--- a/test/src/main/java/org/apache/accumulo/test/VolumeChooserIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/VolumeChooserIT.java
@@ -124,6 +124,8 @@ public class VolumeChooserIT extends ConfigurableMacBase {
 
     siteConfig.put(getPerTableProp(ChooserScope.LOGGER), PreferredVolumeChooser.class.getName());
     siteConfig.put(getPreferredProp(ChooserScope.LOGGER), v2.toString());
+    siteConfig.put(getPerTableProp(ChooserScope.INIT), PreferredVolumeChooser.class.getName());
+    siteConfig.put(getPreferredProp(ChooserScope.INIT), systemPreferredVolumes);
     cfg.setSiteConfig(siteConfig);
 
     // Only add volumes 1, 2, and 4 to the list of instance volumes to have one volume that isn't in