我正在HBase上执行MR。
化简器中的业务逻辑大量访问两个表,例如 T1(40k 行)和 T2(90k 行)。目前,我正在执行以下步骤:
1.In 化简器类的构造函数,执行以下操作:
HBaseCRUD hbaseCRUD = new HBaseCRUD();
HTableInterface t1= hbaseCRUD.getTable("T1",
"CF1", null, "C1", "C2");
HTableInterface t2= hbaseCRUD.getTable("T2",
"CF1", null, "C1", "C2");
在减少(...
String lowercase = ....;
/* Start : HBase code */
/*
* TRY using get(...) on the table rather than a
* Scan!
*/
Scan scan = new Scan();
scan.setStartRow(lowercase.getBytes());
scan.setStopRow(lowercase.getBytes());
/*scan will return a single row*/
ResultScanner resultScanner = t1.getScanner(scan);
for (Result result : resultScanner) {
/*business logic*/
}
虽然不确定上面的代码首先是否合理,但我有一个问题 - get(...) 会比扫描提供任何性能优势吗?
Get get = new Get(lowercase.getBytes());
Result getResult = t1.get(get);
由于 T1 和 T2 将是只读的(大部分),我认为如果保存在内存中,性能会提高。根据 HBase 文档,我将不得不重新创建表 T1 和 T2。请验证我的理解是否正确:
public void createTables(String tableName, boolean readOnly,
boolean blockCacheEnabled, boolean inMemory,
String... columnFamilyNames) throws IOException {
// TODO Auto-generated method stub
HTableDescriptor tableDesc = new HTableDescriptor(tableName);
/* not sure !!! */
tableDesc.setReadOnly(readOnly);
HColumnDescriptor columnFamily = null;
if (!(columnFamilyNames == null || columnFamilyNames.length == 0)) {
for (String columnFamilyName : columnFamilyNames) {
columnFamily = new HColumnDescriptor(columnFamilyName);
/*
* Start : Do these steps ensure that the column
* family(actually, the column data) is in-memory???
*/
columnFamily.setBlockCacheEnabled(blockCacheEnabled);
columnFamily.setInMemory(inMemory);
/*
* End : Do these steps ensure that the column family(actually,
* the column data) is in-memory???
*/
tableDesc.addFamily(columnFamily);
}
}
hbaseAdmin.createTable(tableDesc);
hbaseAdmin.close();
}
一旦完成:
- 如何验证列是否在内存中(当然,描述语句和浏览器反映了它)并且从那里而不是磁盘访问?
- 从内存或从磁盘读取对客户端是否透明?简单来说,我是否需要更改化简器类中的 HTable 访问代码?如果是,有哪些变化?
(...)会比扫描提供任何性能优势吗?
Get直接对作为参数传递给 Get 实例的行键标识的特定行进行操作。虽然 Scan 对所有行进行操作,但如果您尚未通过向 Scan 实例提供开始和结束行键来使用范围查询。显然,如果您事先知道要对哪一行进行操作,则效率更高。您可以直接去那里执行所需的操作。
如何验证列是否在内存中(当然,描述语句和浏览器反映了它)并且从那里而不是磁盘访问?
您可以使用 HColumnDescriptor 提供的 isInMemory() 方法来验证特定 CF 是否在内存中。但是,您无法发现整个表是否在内存中,以及是从磁盘还是内存中获取。尽管内存中块具有最高优先级,但不能 100% 确定所有内容始终都在内存中。这里重要的一点是,即使在内存中 CF 的情况下,数据也会持久保存到磁盘。
从内存或从磁盘读取对客户端是否透明?简单来说,我是否需要更改化简器类中的 HTable 访问代码?如果是,有哪些变化?
是的。它是完全透明的。您不必执行任何额外的操作。
- 就执行而言,它们之间没有实质性区别。它们都与客户相同。