簡體   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