记录一次HBase的scan的分页查询
生活随笔
收集整理的這篇文章主要介紹了
记录一次HBase的scan的分页查询
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
修改前任bug,Hbase查詢過于慢了,以至于都查不出來了,看了代碼發(fā)現(xiàn)使用的Scan只設(shè)置了withStartRow、withEndRow、setCaching掃描,拿到全部數(shù)據(jù)后存入集合再subList進(jìn)行分頁,但是HBase中存在某些數(shù)據(jù)有幾百萬條,根本scan不出來了。
前任設(shè)置如下: 其中start 和 end 拼接0和z是因?yàn)镠Base中RowKey按照字典順序排序,
String start = rowKey + "0"; String end = rowKey + "z"; Scan scan = new Scan(); scan.withStartRow(start.getBytes()); scan.withStopRow(end.getBytes()); scan.setCaching(1000); scan.setCacheBlocks(false);先根據(jù)業(yè)務(wù)邏輯找他的問題,首先沒限定時間戳,然后這樣分頁數(shù)據(jù)量大就出現(xiàn)問題了。
1.加上時間戳限定范圍
時間根據(jù)自己的時間來定,我這里是查詢前一天的數(shù)據(jù),所以就是零點(diǎn)到末尾
try {scan.setTimeRange(getStartOfDay("2021-11-23"), getEndOfDay("2021-11-23")); } catch (IOException e) {e.printStackTrace(); }日期代碼網(wǎng)上找的,一搜一堆
// 獲取指定日期 的 零點(diǎn)時間戳public static Long getStartOfDay(String date) {if (StringUtils.isEmpty(date)) {date = date2String(new Date(), "yyyy-MM-dd");}DateTimeFormatter ofPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.CHINA);LocalDate parse = LocalDate.parse(date, ofPattern);return parse.atStartOfDay().toInstant(ZoneOffset.of("+8")).toEpochMilli();}// 獲取指定日期 的 末尾時間戳public static Long getEndOfDay(String date) {if (StringUtils.isEmpty(date)) {date = date2String(new Date(), "yyyy-MM-dd");}DateTimeFormatter ofPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.CHINA);LocalDate parse = LocalDate.parse(date, ofPattern);return LocalDateTime.of(parse, LocalTime.MAX).toInstant(ZoneOffset.of("+8")).toEpochMilli();}public static String date2String(Date date, String format) {SimpleDateFormat yyyy_MM_dd = new SimpleDateFormat(format);return yyyy_MM_dd.format(date);}//獲取前多少小時到現(xiàn)在的時間范圍//可以將 cal1.add(11, -(hour + 2))進(jìn)行修改,我這里是當(dāng)前時間往前走倆小時,hour是前多少小時public static long[] getHourTimeLimit(int hour) {Calendar cal1 = Calendar.getInstance();Date date = new Date();cal1.setTime(date);cal1.add(11, -(hour + 2));Date d = cal1.getTime();return new long[]{d.getTime(), date.getTime()};}2.修改分頁查詢
1.網(wǎng)上找到的實(shí)現(xiàn)方式
Hbase有一個PageFilter(x),設(shè)置一個數(shù),往后查詢多少個
但是有個問題就是需要設(shè)置具體的withStartRow,從withStartRow開始往后查詢x個,需要先找到startrow,每次根據(jù)startrow往后查x,感覺有點(diǎn)冗余就沒用,自己想了個思路。
鏈接貼上:想了解可以看看
https://blog.csdn.net/HANLIPENGHANLIPENG/article/details/53203646
2.自己實(shí)現(xiàn)的思路
scan的設(shè)置:
public Scan getScan(String rowKey){Scan scan = new Scan();String start = rowKey + "0";scan.withStartRow(start.getBytes());scan.setCaching(6000);scan.setCacheBlocks(false);scan.setMaxResultSize(2 * 1024 * 1024 * 100);try {scan.setTimeRange(getStartOfDay("2021-11-23"), getEndOfDay("2021-11-23"));} catch (IOException e) {e.printStackTrace();}scan.setFilter(new PrefixFilter(rowKey));return scan; }大概意思就是:使用scanner.next(pageSize)根據(jù)頁數(shù)來輪詢,輪詢到當(dāng)前頁就將數(shù)據(jù)進(jìn)行解析,結(jié)束循環(huán)返回。數(shù)據(jù)量大估計(jì)也需要挺長時間,測試了一下每頁20條,1000頁以內(nèi)都還挺快的
前提是將scan.setCaching(6000);這個參數(shù)調(diào)到適合自己的集群,這將決定你多頁查詢的速度,或者將他設(shè)置為一個范圍,根據(jù)當(dāng)前頁大小來做判斷設(shè)置不同的大小,頁數(shù)小就設(shè)置小點(diǎn),頁數(shù)大就相對大一些,盡量一次緩存能查找到,這樣速度就會更快。
scan.setCaching(pageSize * currentPage > 6000 ? 6000 : pageSize * currentPage); Scan scan = getScan(rowKey); //設(shè)置上要查詢的列 for (int i = 0; i < theHour; i++) {long hour = this.timeUtil.getHour(i);scan.addColumn(Bytes.toBytes("D"), String.format("%02d", new Object[]{Long.valueOf(hour)}).getBytes()); }List<xxxx> alls = new ArrayList<>(); long count = 0L; String startRow; try (Table table = this.hbaseConnection.getTable(TableName.valueOf("table"));ResultScanner scanner = table.getScanner(scan)) {Result[] results;int pageCount = 0;while ((results = scanner.next(pageSize)).length != 0) {pageCount++;if (pageCount < currentPage) {continue;}for (Result rs : results) {//在此處解析獲取數(shù)據(jù)alls.add(xxxx)}break;} } catch (Exception e) {log.error("", e); }我查詢第600頁每頁10個,算上解析,用時2278ms,速度還可以吧,只能說相比前任已經(jīng)是可以查出來了,后面在做優(yōu)化吧,第一種方法沒嘗試,感覺上來講第一種也是一個一個掃描的,不知道速度如何,有時間的時候在做下測試吧。
[root@11 scanHbaseTest]# java -jar scanHbaseTest-1.0-SNAPSHOT.jar xxxxxx 600 10 today get Results time = 2278msHbase分頁查詢還真不太好弄,除非能緩存一下每頁的第一條數(shù)據(jù),這樣速度會快很多吧,但是不太現(xiàn)實(shí)。
目前也沒想到特別好的辦法,如果有可以分享給我。
總結(jié)
以上是生活随笔為你收集整理的记录一次HBase的scan的分页查询的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中国最难高铁襄万段难度有多大?耗时12年
- 下一篇: gibmacos 网络加速_黑苹果教程续