HBase scan timerange
背景
scanコマンドラインではtimerange(時間区間)を設定する方法があります.
hbase shellの使い方:
ここのタイムスタンプはsではなくmsに着くべきです
1
scan
't1'
, {COLUMNS =>
'c1'
, TIMERANGE => [
1303668804
,
1303668904
]}
機能
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 ==
null
?
true
:
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で、新しいtimerangeTrackerをnewすることができます
そしてwriterでデータを書くとkvごとにappend操作が行われ、trtのminとmax値が更新されます