我正在将一些软件从较旧的Hadoop群集(使用用户名/密码身份验证)迁移到较新的 2.6.0-cdh5.12.0 ,其中 Kerberos身份验证已启用。
我已经能够使用Accumulo输入和/或输出的许多现有Map / Reduce作业使用AccumuloInput / OutputFormat类中的 DelegationToken 设置正常工作。
但是,我有1个作业,它使用AccumuloInput / OutputFormat作为输入和输出,但也在它的Mapper.setup()方法中,它通过Zookeeper连接到Accumulo,这样在Mapper.map()方法中,它可以比较正在处理的每个键/值我的Mapper.map()和另一个Accumulo表中的条目。
我在下面列出了相关代码,其中显示了连接到Zookeeper用户的一个Password()方法的Password()方法,然后创建了一个Accumulo表Scanner,然后在mapper方法中使用它。
所以问题是如何使用KerberosToken替换使用PasswordToken在Mapper.setup()方法中设置Accumulo扫描程序?我找不到"得到"我设置的AccumuloInput / OutputFormat类使用的DelegationToken。
我尝试了context.getCredentials()。getAllTokens()并查找类型为org.apache.accumulo.code.client.security.tokens.AuthenticationToken的标记 - 此处返回的所有标记都是org类型。 apache.hadoop.security.token.Token。
请注意我输入与剪切/粘贴的代码片段,因为代码在未连接到互联网的网络上运行 - 也就是说可能存在拼写错误。 :)
//****************************
// code in the M/R driver
//****************************
ClientConfiguration accumuloCfg = ClientConfiguration.loadDefault().withInstance("Accumulo1").withZkHosts("zookeeper1");
ZooKeeperInstance inst = new ZooKeeperInstance(accumuloCfg);
AuthenticationToken dt = conn.securityOperations().getDelegationToken(new DelagationTokenConfig());
AccumuloInputFormat.setConnectorInfo(job, username, dt);
AccumuloOutputFormat.setConnectorInfo(job, username, dt);
// other job setup and then
job.waitForCompletion(true)
//****************************
// this is inside the Mapper class of the M/R job
//****************************
private Scanner index_scanner;
public void setup(Context context) {
Configuration cfg = context.getConfiguration();
// properties set and passed from M/R Driver program
String username = cfg.get("UserName");
String password = cfg.get("Password");
String accumuloInstName = cfg.get("InstanceName");
String zookeepers = cfg.get("Zookeepers");
String tableName = cfg.get("TableName");
Instance inst = new ZooKeeperInstance(accumuloInstName, zookeepers);
try {
AuthenticationToken passwordToken = new PasswordToken(password);
Connector conn = inst.getConnector(username, passwordToken);
index_scanner = conn.createScanner(tableName, conn.securityOperations().getUserAuthorizations(username));
} catch(Exception e) {
e.printStackTrace();
}
}
public void map(Key key, Value value, Context context) throws IOException, InterruptedException {
String uuid = key.getRow().toString();
index_scanner.clearColumns();
index_scanner.setRange(Range.exact(uuid));
for(Entry<Key, Value> entry : index_scanner) {
// do some processing in here
}
}
答案 0 :(得分:6)
提供的AccumuloInputFormat和AccumuloOutputFormat有一种方法可以使用Accumulo*putFormat.setConnectorInfo(job, principle, token)
在作业配置中设置令牌。您还可以使用AuthenticationTokenSerializer在HDFS中的文件中序列化令牌,并使用接受文件名的setConnectorInfo
方法版本。
如果传入了KerberosToken,作业将创建一个要使用的DelegationToken,如果传入了DelegationToken,它将只使用它。
提供的AccumuloInputFormat
应该处理自己的扫描仪,因此通常情况下,如果您已正确设置配置,则不必在Mapper中执行此操作。但是,如果您在Mapper中进行二次扫描(对于某些类似的连接),您可以检查提供的AccumuloInputFormat
的RecordReader源代码,以获取有关如何检索配置和构建扫描仪。