HBase scan优化之设置 timerange

 

 

 

背景

当一个表的查询,是带有时间范围的;并且此表下面数据时间跨度很大,怎样才能扫更少的数据呢?

HBase的scan操作给出了一个timerange的设置,可以只扫描在timerange范围内的文件。直接减少了扫描的文件量.

(思考:如果用户可能存在一些写入断掉/补数等行为,可以适当放宽timerange,比如表中数据是3个月,查询数据在2个小时内,那么可以timerange设置一个至少2天内的范围)


scan在命令行有一个用法是设置timerange(时间区间)

hbase shell给出的用法:

这里的时间戳应该到ms而不是s

1

scan 't1', {COLUMNS => 'c1', TIMERANGE => [13036688040001303668904000]}

功能

scan的时候只扫描时间范围内的文件

 

结论

写入的时候,更新memstore的timeRangeTracker的min和max 时间戳

flush的时候,timeRangeTracker的值赋值给snapshotTimeRangeTracker

写文件的时候,写入snapshotTimeRangeTracker到文件的元数据中对应的key是TIMERANGE_KEY

查询的时候客户端传递过来的scan.getTimeRange在shouldUseScanner方法中通过passesTimerangeFilter进行过滤

 

 

请求链路分析

 

扫描文件(查询操作)的时候涉及的代码

StoreFileScanner.shouldUseScanner

1

2

3

4

5

@Override

public boolean shouldUseScanner(Scan scan, SortedSet<byte[]> columns, long oldestUnexpiredTS) {

  return reader.passesTimerangeFilter(scan.getTimeRange(), oldestUnexpiredTS)

      && reader.passesKeyRangeFilter(scan) && reader.passesBloomFilter(scan, columns);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

StoreFile.Reader

 

 

/**

 * Check if this storeFile may contain keys within the TimeRange that

 * have not expired (i.e. not older than oldestUnexpiredTS).

 * @param scan the current scan

 * @param oldestUnexpiredTS the oldest timestamp that is not expired, as

 *          determined by the column family's TTL

 * @return false if queried keys definitely don't exist in this StoreFile

 */

boolean passesTimerangeFilter(TimeRange tr, long oldestUnexpiredTS) {

  return this.timeRange == nulltrue:

    this.timeRange.includesTimeRange(tr) && this.timeRange.getMax() >= oldestUnexpiredTS;

}

 

 

//Reader.timeRange是从文件的metadataMap.get(TIMERANGE_KEY)  中获取的文件信息

 

 

请求堆栈

HRegionServer.scan

→HRegion.getScanner

→HRegion.instantiateRegionScanner

→RegionScannerImpl

→HStore.getScanner

→StoreScanner 构造方法

→StoreScanner.getScannersNoCompaction

→StoreScanner.selectScannersFrom

KeyValueScanner.shouldUseScanner

 

 

 

timerange信息在如何写入文件?

 

 

 

/**

 * Add TimestampRange and earliest put timestamp to Metadata

 */

public void appendTrackedTimestampsToMetadata() throws IOException {

  appendFileInfo(TIMERANGE_KEY,WritableUtils.toByteArray(timeRangeTracker));

  appendFileInfo(EARLIEST_PUT_TS, Bytes.toBytes(earliestPutTs));

}

 

 

//关键点是:Writer.timeRangeTracker

 

StoreFile.WriterBuilder.build() 中调用new Writer 初始化timeRangeTracker

再上层是StoreFile.WriterBuilder.trt

⬆️HStore.createWriterInTmp

 

第一个引用:

 

这里面timerange的向上跟踪可以知道是:HStore中的snapshotTimeRangeTracker

那么snapshotTimeRangeTracker的设置从何而来?

 

在memstore初始化的时候,初始化TimeRangeTracker

TimeRangeTracker中的时间戳最小最大值

snapshotTimeRangeTracker的值,在MemStore snapshot方法(不是hbase的snapshot,是memstore概念的snapshot,flush中用到的)中

this.snapshotTimeRangeTracker = this.timeRangeTracker;

timeRangeTracker中min和max时间戳的更新是做写入操作的时候会调用memstore.put等操作更新

 

compact情况下:

初始writer的时候trt为null,会new一个新的timerangeTracker

然后通过writer写数据的时候,写入每个kv会进行append操作,里面会更新trt的  min和max值

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值