hbase:get(…)vs扫描和内存表

pzfprimi  于 2021-06-03  发布在  Hadoop
关注(0)|答案(2)|浏览(536)

我要处决哈贝斯先生。
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");

在reduce(…)

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();
    }

一旦完成:
如何验证列是否在内存中(当然,descripe语句和浏览器反映了它),并从内存而不是磁盘中访问?
从内存还是从磁盘读取对客户端是透明的?简单地说,我是否需要更改reducer类中的htable访问代码?如果是,有什么变化?

kmynzznz

kmynzznz1#

get(…)是否比扫描有任何性能优势?
get直接对由作为参数传递给get示例的rowkey标识的特定行进行操作。当scan对所有行进行操作时,如果您还没有通过向scan示例提供start和end rowkey来使用范围查询。显然,如果你事先知道该在哪一行操作,效率会更高。您可以直接去那里执行所需的操作。
如何验证列是否在内存中(当然,descripe语句和浏览器反映了它),并从内存而不是磁盘中访问?
可以使用hcolumndescriptor提供的isinmemory()方法验证特定cf是否在内存中。但是,您无法确定整个表是否在内存中,以及是从磁盘还是从内存中获取数据。虽然内存中的块具有最高的优先级,但并不能100%确定所有的东西都一直在内存中。这里一个重要的事情是数据被持久化到磁盘,即使是在内存中的cf。
从内存还是从磁盘读取对客户端是透明的?简单地说,我是否需要更改reducer类中的htable访问代码?如果是,有什么变化?
对。它是完全透明的。你不需要做任何额外的事情。

cbjzeqam

cbjzeqam2#

就实施而言,这两者之间没有实质性的区别。它们都与客户端相同。

相关问题