cache:
在默認情況下,如果你需要從hbase中查詢數據,在獲取結果ResultScanner時,hbase會在你每次調用ResultScanner.next()操作時對返回的每個Row執行一次RPC操作。即使你使用ResultScanner.next(int nbRows)時也只是在客戶端循環調用RsultScanner.next()操作,你可以理解為hbase將執行查詢請求以迭代器的模式設計,在執行next()操作時才會真正的執行查詢操作,而對每個Row都會執行一次RPC操作。
因此顯而易見的就會想如果我對多個Row返回查詢結果才執行一次RPC調用,那么就會減少實際的通訊開銷。這個就是hbase配置屬性“hbase.client.scanner.caching”的由來,設置cache可以在hbase配置文件中顯示靜態的配置,也可以在程序動態的設置。
cache值得設置並不是越大越好,需要做一個平衡。cache的值越大,則查詢的性能就越高,但是與此同時,每一次調用next()操作都需要花費更長的時間,因為獲取的數據更多並且數據量大了傳輸到客戶端需要的時間就越長,一旦你超過了maximum heap the client process 擁有的值,就會報outofmemoryException異常。當傳輸rows數據到客戶端的時候,如果花費時間過長,則會拋出ScannerTimeOutException異常。
batch:
在cache的情況下,我們一般討論的是相對比較小的row,那么如果一個Row特別大的時候應該怎么處理呢?要知道cache的值增加,那么在client process 占用的內存就會隨着row的增大而增大。在hbase中同樣為解決這種情況提供了類似的操作:Batch。可以這么理解,cache是面向行的優化處理,batch是面向列的優化處理。它用來控制每次調用next()操作時會返回多少列,比如你設置setBatch(5),那么每一個Result實例就會返回5列,如果你的列數為17的話,那么就會獲得四個Result實例,分別含有5,5,5,2個列。
下面會以表格的形式來幫助理解,假設我們擁有10Row,每個row擁有2個family,每個family擁有10個列。(也就是說每個Row含有20列)
caching | batch | Results | RPCs | Notes |
1 | 1 | 200 | 201 | 額外的一個RPC是用來判斷scan是否完成 |
200 | 1 | 200 | 2 | |
2000 | 100 | 10 | 1 | 超過的部分沒有用處,但是判斷scan也在那一個RPC 中完成 |
2 | 100 | 10 | 6 | 10/2 +1 (額外的判斷開銷) |
2 | 10 | 20 | 11 | |
5 | 100 | 10 | 3 | |
5 | 20 | 10 | 3 | |
10 | 10 | 20 | 3 |
RPCs=(Rows* Cols per Row) / Min(Cols per Row, Batch size) / Scanner caching

上圖引用自hbase權威指南,是用來表示一個RPC call的構成。