[英]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();
}
完成后:
get(...)會在掃描中提供任何性能優勢嗎?
獲取直接操作在由作為參數傳遞給Get實例的rowkey標識的特定行上。 雖然掃描對所有行都有效,但如果您沒有通過向Scan實例提供開始和結束行鍵來使用范圍查詢。 顯然,如果事先知道要操作哪一行,效率會更高。 您可以直接去那里並執行所需的操作。
如何驗證列是在內存中(當然,describe語句和瀏覽器反映它)並從那里訪問而不是磁盤?
可以使用由HColumnDescriptor提供isInMemory()方法來驗證是否一個特定的CF為在內存中或沒有。 但是,你無法發現整個表都在內存中,是否從磁盤或內存中進行了提取。 雖然內存塊具有最高優先級,但並不是100%確定所有內容始終都在內存中。 這里一個重要的事情是,即使在內存CF的情況下,數據也會持久存儲到磁盤。
來自內存或來自磁盤的讀取對客戶端是否透明? 簡單來說,我是否需要在reducer類中更改HTable訪問代碼? 如果是,有什么變化?
是。 它是完全透明的。 你不需要做任何額外的事情。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.