HBase scan timerange

 

 

 

背景


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

hbase shell给出的用法:

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

1

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

功能

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值

你可能感兴趣的:(nosql,hadoop,hbase)