您好,登錄后才能下訂單哦!
這篇文章主要介紹HBase中Scan類屬性maxResultSize有什么用,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
如果你看過HRegionServer的啟動過程,你會發現他也有一個類似的屬性maxScannerResultSize(配置文件中通過hbase.client.scanner.max.result.size設置),其實這個值就是Scan做掃描時候maxResultSize的默認值,那這個maxResultSize到底有什么用,我們看下面的源碼(摘自hbase0.98.9 HRegionServer的scan方法):
LOG.info("*******4444************maxResultSize:"+maxResultSize + ";rows:"+rows); synchronized(scanner) { while (i < rows) { // Stop collecting results if maxScannerResultSize is set and we have exceeded it if ((maxScannerResultSize < Long.MAX_VALUE) && (currentScanResultSize >= maxResultSize)) { LOG.info("*************kreak i :"+i); break; } // Collect values to be returned here boolean moreRows = scanner.nextRaw(values); if (!values.isEmpty()) { for (Cell cell : values) { KeyValue kv = KeyValueUtil.ensureKeyValue(cell); LOG.info("*************kv :"+kv +";kv.heapSize():"+kv.heapSize()); LOG.info("*************currentScanResultSize :"+currentScanResultSize); currentScanResultSize += kv.heapSize(); totalKvSize += kv.getLength(); } results.add(Result.create(values)); i++; } if (!moreRows) { break; } values.clear(); } }
大家會看到一些調試代碼,也莫見怪了。
大家看“if((maxScannerResultSize < Long.MAX_VALUE) && (currentScanResultSize >= maxResultSize))” 這個條件判斷語句,很重要的一個判斷是currentScanResultSize >= maxResultSize,而這里的currentScanResultSize,其實是每行所有KeyValue的bytes的統計數,意思是當在Scan對象中設置了maxResultSize后(沒設置的話,默認值為HRegionServer的maxScannerResultSize),在HRegionServer中掃描數據的時候,會對所查數據的bytes統計和與這個值做比較,這樣的結果是如果maxResultSize比較小,那么本來需要10條數據一次能夠查詢到的,需要分成多次查詢,其maxResultSize的值,并不會影響查詢的結果,只會影響scan發起遠程調用的次數,這里可能說得有點抽象,我舉個例子說明:
在我的HBase數據庫中存在記錄:row-10,row-11,...,row-19,row-20,row-21,...,row-29,...,row-91,row-92,...,row-99
分別用兩種下面三種方式查詢,都能得到一樣的結果:
keyvalues={row-10/colfam1:col-5/1423054405356/Put/vlen=8/mvcc=0, row-10/colfam2:col-33/1423054405467/Put/vlen=9/mvcc=0} keyvalues={row-100/colfam1:col-5/1423054437916/Put/vlen=9/mvcc=0, row-100/colfam2:col-33/1423054437979/Put/vlen=10/mvcc=0} keyvalues={row-11/colfam1:col-5/1423054405753/Put/vlen=8/mvcc=0, row-11/colfam2:col-33/1423054405869/Put/vlen=9/mvcc=0} keyvalues={row-12/colfam1:col-5/1423054406160/Put/vlen=8/mvcc=0, row-12/colfam2:col-33/1423054406268/Put/vlen=9/mvcc=0} keyvalues={row-13/colfam1:col-5/1423054406541/Put/vlen=8/mvcc=0, row-13/colfam2:col-33/1423054406646/Put/vlen=9/mvcc=0} keyvalues={row-14/colfam1:col-5/1423054406937/Put/vlen=8/mvcc=0, row-14/colfam2:col-33/1423054407028/Put/vlen=9/mvcc=0} keyvalues={row-15/colfam1:col-5/1423054407305/Put/vlen=8/mvcc=0, row-15/colfam2:col-33/1423054407424/Put/vlen=9/mvcc=0} keyvalues={row-16/colfam1:col-5/1423054407715/Put/vlen=8/mvcc=0, row-16/colfam2:col-33/1423054407813/Put/vlen=9/mvcc=0} keyvalues={row-17/colfam1:col-5/1423054408084/Put/vlen=8/mvcc=0, row-17/colfam2:col-33/1423054408198/Put/vlen=9/mvcc=0} keyvalues={row-18/colfam1:col-5/1423054408490/Put/vlen=8/mvcc=0, row-18/colfam2:col-33/1423054408598/Put/vlen=9/mvcc=0} keyvalues={row-19/colfam1:col-5/1423054408895/Put/vlen=8/mvcc=0, row-19/colfam2:col-33/1423054409007/Put/vlen=9/mvcc=0} keyvalues={row-2/colfam1:col-5/1423054402056/Put/vlen=7/mvcc=0, row-2/colfam2:col-33/1423054402181/Put/vlen=8/mvcc=0}
方法一:
Scan scan3 = new Scan(); scan3.setCaching(9); scan3.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col-5")) .addColumn(Bytes.toBytes("colfam2"), Bytes.toBytes("col-33")) .setStartRow(Bytes.toBytes("row-10")).setStopRow(Bytes.toBytes("row-20")); ResultScanner scanner3 = table.getScanner(scan3); for (Result res : scanner3) { System.err.println(res); } scanner3.close();
方法二:
Scan scan3 = new Scan(); //scan3.setCaching(9); scan3.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col-5")) .addColumn(Bytes.toBytes("colfam2"), Bytes.toBytes("col-33")) .setStartRow(Bytes.toBytes("row-10")).setStopRow(Bytes.toBytes("row-20")).setMaxResultSize(5); ResultScanner scanner3 = table.getScanner(scan3); for (Result res : scanner3) { System.err.println(res); } scanner3.close();
方法三:
Scan scan3 = new Scan(); scan3.setCaching(9); scan3.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col-5")) .addColumn(Bytes.toBytes("colfam2"), Bytes.toBytes("col-33")) .setStartRow(Bytes.toBytes("row-10")).setStopRow(Bytes.toBytes("row-20")).setMaxResultSize(5); ResultScanner scanner3 = table.getScanner(scan3); for (Result res : scanner3) { System.err.println(res); } scanner3.close();
方法一和方法二的區別,在于方法一中scan設置了caching屬性為9,方法二中沒設置該屬性,但設置了maxResultSize屬性,
方法二和方法三的區別,在于方法三在方法二的基礎上設置了caching屬性為9,
基于上面的例子,做以下幾點說明:
1、如果不設置scan的caching屬性,本例中要查詢row-10到row-20的屬性,需要在client發起最少11次的遠程訪問,從HRegionServer中獲取數據,并且每次只查詢一條記錄。
2、對于maxResultSize,只對一次client的遠程訪問起作用,如果一次遠程調用只取一條數據,這個值的設置沒有意義;對于批量數據獲取,即Scan設置caching后,這個值會起到限制作用,比如,例子中Scan設置caching為9,同時設置maxResultSize為5,并且事先可以知道每行數據的bytes是112,在這樣的條件下,結合HRegionServer中scan方法中的限制代碼,即使Scan設置了caching為9,一次遠程調用也只能取到一條記錄,原因也就是“if ((maxScannerResultSize < Long.MAX_VALUE) && (currentScanResultSize >= maxResultSize)) “ 執行這個邏輯檢查的時候,被break,跳出循環了。 所以,Scan設置caching為9理想情況下,是能2次遠程調用就取到12條記錄,但是由于設置了maxResultSize為5,在檢查每次遠程調用能返回的bytes數的時候,就只能返回一條記錄了。
3、方法二和方法三效果完全一樣,方法一只需要client發起三次遠程調用,便可取到所需數據。
4、maxResultSize的意義:限制每次client從HRegionServer取到的bytes總數,bytes總數通過row的KeyValue計算得出。
以上是“HBase中Scan類屬性maxResultSize有什么用”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。