我希望有人能告诉我这两个API调用之间的区别是什么。我在他们两个之间得到了奇怪的结果。这发生在hbase-client / hbase-server版本1.0.1和1.2.0-cdh5.7.2。
首先,我的rowkeys的格式为hash_name_timestamp 例如100_servername_1234567890。 hbase表的TTL为30天,因此30天以后的事情应该在压缩后消失。
以下是使用ResultScanner的代码。它不使用MapReduce,因此需要很长时间才能完成。我不能这样做我的工作,因为它需要太长时间。但是,出于调试目的,我对此方法没有任何问题。它列出了指定时间范围内的所有密钥,这些密钥看起来对我有效,因为返回密钥的所有时间戳都在过去30天内且在指定的时间范围内:
Scan scan = new Scan();
scan.addColumn(Bytes.toBytes("raw_data"), Bytes.toBytes(fileType));
scan.setCaching(500);
scan.setCacheBlocks(false);
scan.setTimeRange(start, end);
Connection fConnection = ConnectionFactory.createConnection(conf);
Table table = fConnection.getTable(TableName.valueOf(tableName));
ResultScanner scanner = table.getScanner(scan);
for (Result result = scanner.next(); result != null; result = scanner.next()) {
System.out.println("Found row: " + Bytes.toString(result.getRow()));
}
以下代码不起作用,但它使用MapReduce,它比使用ResultScanner方式运行得更快,因为它将事物划分为1200个地图。问题是我得到了因TTL过期而应该消失的rowkeys:
Scan scan = new Scan();
scan.addColumn(Bytes.toBytes("raw_data"), Bytes.toBytes(fileType));
scan.setCaching(500);
scan.setCacheBlocks(false);
scan.setTimeRange(start, end);
TableMapReduceUtil.initTableMapperJob(tableName, scan, MTTRMapper.class, Text.class, IntWritable.class, job);
这是我得到的错误,最终会导致整个MR作业失败,因为超过25%的地图制作者失败了。
错误:org.apache.hadoop.hbase.client.RetriesExhaustedException: 尝试= 36后失败,例外:2017年6月28日星期三13:46:57, null,java.net.SocketTimeoutException:callTimeout = 120000, callDuration = 120301:row'65_app129041.iad1.mydomain.com_1476641940' 在表'server_based_data'在region = server_based_data
我将尝试研究hbase-client和hbase-server jar的代码,但希望有人会知道方法之间的区别是什么以及导致initTableMapperJob调用失败的原因。
编辑:这是我正在使用的表格的描述:
describe 'server_based_data'
Table server_based_data is ENABLED
server_based_data
COLUMN FAMILIES DESCRIPTION
{NAME => 'raw_data', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLIC
ATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'SNAPPY', MIN_VERSIONS => '0
', TTL => '2592000 SECONDS (30 DAYS)', KEEP_DELETED_CELLS => 'FALSE', BLOCKSIZE
=> '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}
1 row(s) in 0.5180 seconds
这是我的映射器代码:
public void map(ImmutableBytesWritable rowkey, Result columns, Context context) throws IOException, InterruptedException {
Configuration conf = context.getConfiguration();
startMS = conf.getLong("startTime", 0);
endMS = conf.getLong("endTime", 1);
System.out.println(startMS);
System.out.println(endMS);
// extract the ci as the key from the rowkey
String pattern = "\\d*_(\\S*)_(\\d{10})";
String ciname = null;
Pattern r = Pattern.compile(pattern);
String strRowKey = Bytes.toString(rowkey.get());
// check the time here to see if we count it or not in the counts
Matcher m = r.matcher(strRowKey);
long ts = 0;
if (m.find()) {
ts = Long.valueOf(m.group(2)).longValue();
ciname = m.group(1);
if ((ts >= startMS) && (ts <= endMS)) {
context.write(new Text(ciname), ONE);
}
}
}
我仍然认为initTableMapperJob方法有一些东西,因为上面发布的错误显示了一个应该从表的TTL过期的行的时间戳但是由于某种原因,initTableMapperJob仍然找到它并尝试寻找它但是超时,而ResultScanner由于某种原因没有看到它。
答案 0 :(得分:1)
我想提出几点建议。
我不确定导致initTableMapperJob
奇怪行为的原因。但我希望上述建议有用。