繁体   English   中英

HBase:get(...)vs scan和in-memory table

[英]HBase : get(…) vs scan and in-memory table

我正在执行MR over HBase。

reducer中的业务逻辑大量访问两个表,比如T1(40k行)和T2(90k行)。 目前,我正在执行以下步骤:

1.在reducer类的构造函数中,执行以下操作:

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 = new Get(lowercase.getBytes());
Result getResult = t1.get(get);

由于T1和T2将是只读的(大部分),我认为如果保留在内存中,性能将会提高。 根据HBase doc。,我将不得不重新创建表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();
    }

完成后:

  1. 如何验证列是在内存中(当然,describe语句和浏览器反映它)并从那里访问而不是磁盘?
  2. 来自内存或来自磁盘的读取对客户端是否透明? 简单来说,我是否需要在reducer类中更改HTable访问代码? 如果是,有什么变化?

get(...)会在扫描中提供任何性能优势吗?

获取直接操作在由作为参数传递给Get实例的rowkey标识的特定行上。 虽然扫描对所有行都有效,但如果您没有通过向Scan实例提供开始和结束行键来使用范围查询。 显然,如果事先知道要操作哪一行,效率会更高。 您可以直接去那里并执行所需的操作。

如何验证列是在内存中(当然,describe语句和浏览器反映它)并从那里访问而不是磁盘?

可以使用由HColumnDescriptor提供isInMemory()方法来验证是否一个特定的CF为在内存中或没有。 但是,你无法发现整个表都在内存中,是否从磁盘或内存中进行了提取。 虽然内存块具有最高优先级,但并不是100%确定所有内容始终都在内存中。 这里一个重要的事情是,即使在内存CF的情况下,数据也会持久存储到磁盘。

来自内存或来自磁盘的读取对客户端是否透明? 简单来说,我是否需要在reducer类中更改HTable访问代码? 如果是,有什么变化?

是。 它是完全透明的。 你不需要做任何额外的事情。

  1. 就实施而言,这些之间没有实质性差异。 它们都与客户相同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM