【博客712】victoriametrics搜索indexDB时的顺序

victoriametrics搜索indexDB时的顺序

整体

1、先搜索cache,
2、然后搜索当前DB
3、最后是搜搜extDB(也就是上一个数据保留周期的db)

为什么要设计extDB(也就是上一个数据保留周期的db),而不是只有DB

extDB是为了防止当数据过期的时候,或者轮转的时候,如果没有extDB作为过渡,那么对于此时对老metrics的新datapoint都会变成新时序,出现大量的index missing,导致性能大降

源码

func (db *indexDB) getTSIDsFromMetricIDs(qt *querytracer.Tracer, accountID, projectID uint32, metricIDs []uint64, deadline uint64) ([]TSID, error) {
    qt = qt.NewChild("obtain tsids from %d metricIDs", len(metricIDs))
    defer qt.Done()

    if len(metricIDs) == 0 {
        return nil, nil
    }
    tsids := make([]TSID, len(metricIDs))
    var extMetricIDs []uint64
    i := 0
    err := func() error {
        is := db.getIndexSearch(accountID, projectID, deadline)
        defer db.putIndexSearch(is)
        for loopsPaceLimiter, metricID := range metricIDs {
            if loopsPaceLimiter&paceLimiterSlowIterationsMask == 0 {
                if err := checkSearchDeadlineAndPace(is.deadline); err != nil {
                    return err
                }
            }
            // Try obtaining TSIDs from MetricID->TSID cache. This is much faster
            // than scanning the mergeset if it contains a lot of metricIDs.
            tsid := &tsids[i]
            // 1、优先搜索cache
            err := is.db.getFromMetricIDCache(tsid, metricID)
            if err == nil {
                // Fast path - the tsid for metricID is found in cache.
                i++
                continue
            }
            if err != io.EOF {
                return err
            }
            // 2、搜索当前indexDB
            if err := is.getTSIDByMetricID(tsid, metricID); err != nil {
                if err == io.EOF {
                    // Postpone searching for the metricID in the extDB.
                    extMetricIDs = append(extMetricIDs, metricID)
                    continue
                }
                return fmt.Errorf("cannot find tsid %d out of %d for metricID %d: %w", i, len(metricIDs), metricID, err)
            }
            // 填充cache
            is.db.putToMetricIDCache(metricID, tsid)
            i++
        }
        return nil
    }()
    if err != nil {
        return nil, fmt.Errorf("error when searching for TISDs by metricIDs in the current indexdb: %w", err)
    }
    tsidsFound := i
    qt.Printf("found %d tsids for %d metricIDs in the current indexdb", tsidsFound, len(metricIDs))

    // Search for extMetricIDs in the extDB.
    // 3、搜索extDB(也就是上一个数据保留周期的db)
    // 之所以有extDB是为了防止当数据过期的时候,出现大量的index missing,导致性能大降
    db.doExtDB(func(extDB *indexDB) {
        is := extDB.getIndexSearch(accountID, projectID, deadline)
        defer extDB.putIndexSearch(is)
        for loopsPaceLimiter, metricID := range extMetricIDs {
            if loopsPaceLimiter&paceLimiterSlowIterationsMask == 0 {
                if err = checkSearchDeadlineAndPace(is.deadline); err != nil {
                    return
                }
            }
            // There is no need in searching for TSIDs in MetricID->TSID cache, since
            // this has been already done in the loop above (the MetricID->TSID cache is global).
            tsid := &tsids[i]
            if err = is.getTSIDByMetricID(tsid, metricID); err != nil {
                if err == io.EOF {
                    // Cannot find TSID for the given metricID.
                    // This may be the case on incomplete indexDB
                    // due to snapshot or due to unflushed entries.
                    // Just increment errors counter and skip it for now.
                    atomic.AddUint64(&is.db.missingTSIDsForMetricID, 1)
                    err = nil
                    continue
                }
                err = fmt.Errorf("cannot find tsid for metricID=%d: %w", metricID, err)
                return
            }
            is.db.putToMetricIDCache(metricID, tsid)
            i++
        }
    })
    if err != nil {
        return nil, fmt.Errorf("error when searching for TSIDs by metricIDs in the previous indexdb: %w", err)
    }
    qt.Printf("found %d tsids for %d metricIDs in the previous indexdb", i-tsidsFound, len(extMetricIDs))

    tsids = tsids[:i]
    qt.Printf("load %d tsids for %d metricIDs from both current and previous indexdb", len(tsids), len(metricIDs))

    // Sort the found tsids, since they must be passed to TSID search
    // in the sorted order.
    sort.Slice(tsids, func(i, j int) bool { return tsids[i].Less(&tsids[j]) })
    qt.Printf("sort %d tsids", len(tsids))
    return tsids, nil
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值