您好,登錄后才能下訂單哦!
這篇文章主要介紹HBase中Scan類屬性maxResultSize有什么用,文中介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們一定要看完!
如果你看過HRegionServer的啟動過程,你會發(fā)現(xiàn)他也有一個類似的屬性maxScannerResultSize(配置文件中通過hbase.client.scanner.max.result.size設(shè)置),其實這個值就是Scan做掃描時候maxResultSize的默認(rèn)值,那這個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(); } }
大家會看到一些調(diào)試代碼,也莫見怪了。
大家看“if((maxScannerResultSize < Long.MAX_VALUE) && (currentScanResultSize >= maxResultSize))” 這個條件判斷語句,很重要的一個判斷是currentScanResultSize >= maxResultSize,而這里的currentScanResultSize,其實是每行所有KeyValue的bytes的統(tǒng)計數(shù),意思是當(dāng)在Scan對象中設(shè)置了maxResultSize后(沒設(shè)置的話,默認(rèn)值為HRegionServer的maxScannerResultSize),在HRegionServer中掃描數(shù)據(jù)的時候,會對所查數(shù)據(jù)的bytes統(tǒng)計和與這個值做比較,這樣的結(jié)果是如果maxResultSize比較小,那么本來需要10條數(shù)據(jù)一次能夠查詢到的,需要分成多次查詢,其maxResultSize的值,并不會影響查詢的結(jié)果,只會影響scan發(fā)起遠(yuǎn)程調(diào)用的次數(shù),這里可能說得有點抽象,我舉個例子說明:
在我的HBase數(shù)據(jù)庫中存在記錄:row-10,row-11,...,row-19,row-20,row-21,...,row-29,...,row-91,row-92,...,row-99
分別用兩種下面三種方式查詢,都能得到一樣的結(jié)果:
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();
方法一和方法二的區(qū)別,在于方法一中scan設(shè)置了caching屬性為9,方法二中沒設(shè)置該屬性,但設(shè)置了maxResultSize屬性,
方法二和方法三的區(qū)別,在于方法三在方法二的基礎(chǔ)上設(shè)置了caching屬性為9,
基于上面的例子,做以下幾點說明:
1、如果不設(shè)置scan的caching屬性,本例中要查詢row-10到row-20的屬性,需要在client發(fā)起最少11次的遠(yuǎn)程訪問,從HRegionServer中獲取數(shù)據(jù),并且每次只查詢一條記錄。
2、對于maxResultSize,只對一次client的遠(yuǎn)程訪問起作用,如果一次遠(yuǎn)程調(diào)用只取一條數(shù)據(jù),這個值的設(shè)置沒有意義;對于批量數(shù)據(jù)獲取,即Scan設(shè)置caching后,這個值會起到限制作用,比如,例子中Scan設(shè)置caching為9,同時設(shè)置maxResultSize為5,并且事先可以知道每行數(shù)據(jù)的bytes是112,在這樣的條件下,結(jié)合HRegionServer中scan方法中的限制代碼,即使Scan設(shè)置了caching為9,一次遠(yuǎn)程調(diào)用也只能取到一條記錄,原因也就是“if ((maxScannerResultSize < Long.MAX_VALUE) && (currentScanResultSize >= maxResultSize)) “ 執(zhí)行這個邏輯檢查的時候,被break,跳出循環(huán)了。 所以,Scan設(shè)置caching為9理想情況下,是能2次遠(yuǎn)程調(diào)用就取到12條記錄,但是由于設(shè)置了maxResultSize為5,在檢查每次遠(yuǎn)程調(diào)用能返回的bytes數(shù)的時候,就只能返回一條記錄了。
3、方法二和方法三效果完全一樣,方法一只需要client發(fā)起三次遠(yuǎn)程調(diào)用,便可取到所需數(shù)據(jù)。
4、maxResultSize的意義:限制每次client從HRegionServer取到的bytes總數(shù),bytes總數(shù)通過row的KeyValue計算得出。
以上是“HBase中Scan類屬性maxResultSize有什么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。