mirror of
https://gitee.com/milvus-io/milvus.git
synced 2025-12-06 17:18:35 +08:00
Fix segment loader skip wait if all segments are loading (#25643)
Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
This commit is contained in:
parent
49655d2f13
commit
c490b30db7
@ -131,17 +131,16 @@ func (loader *segmentLoader) Load(ctx context.Context,
|
|||||||
zap.String("segmentType", segmentType.String()),
|
zap.String("segmentType", segmentType.String()),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if len(segments) == 0 {
|
||||||
|
log.Info("no segment to load")
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
// Filter out loaded & loading segments
|
// Filter out loaded & loading segments
|
||||||
infos := loader.prepare(segmentType, segments...)
|
infos := loader.prepare(segmentType, segments...)
|
||||||
defer loader.unregister(infos...)
|
defer loader.unregister(infos...)
|
||||||
|
|
||||||
segmentNum := len(infos)
|
// continue to wait other task done
|
||||||
if segmentNum == 0 {
|
log.Info("start loading...", zap.Int("segmentNum", len(segments)), zap.Int("afterFilter", len(infos)))
|
||||||
log.Info("no segment to load")
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("start loading...", zap.Int("segmentNum", segmentNum))
|
|
||||||
|
|
||||||
// Check memory & storage limit
|
// Check memory & storage limit
|
||||||
memUsage, diskUsage, concurrencyLevel, err := loader.requestResource(infos...)
|
memUsage, diskUsage, concurrencyLevel, err := loader.requestResource(infos...)
|
||||||
@ -210,12 +209,10 @@ func (loader *segmentLoader) Load(ctx context.Context,
|
|||||||
log.Info("load segment done", zap.Int64("segmentID", segmentID))
|
log.Info("load segment done", zap.Int64("segmentID", segmentID))
|
||||||
|
|
||||||
metrics.QueryNodeLoadSegmentLatency.WithLabelValues(fmt.Sprint(paramtable.GetNodeID())).Observe(float64(tr.ElapseSpan().Milliseconds()))
|
metrics.QueryNodeLoadSegmentLatency.WithLabelValues(fmt.Sprint(paramtable.GetNodeID())).Observe(float64(tr.ElapseSpan().Milliseconds()))
|
||||||
|
waitCh, ok := loader.loadingSegments.Get(loadInfo.GetSegmentID())
|
||||||
waitCh, ok := loader.loadingSegments.Get(segmentID)
|
if ok {
|
||||||
if !ok {
|
close(waitCh)
|
||||||
return errors.New("segment was removed from the loading map early")
|
|
||||||
}
|
}
|
||||||
close(waitCh)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -223,9 +220,9 @@ func (loader *segmentLoader) Load(ctx context.Context,
|
|||||||
// Start to load,
|
// Start to load,
|
||||||
// Make sure we can always benefit from concurrency, and not spawn too many idle goroutines
|
// Make sure we can always benefit from concurrency, and not spawn too many idle goroutines
|
||||||
log.Info("start to load segments in parallel",
|
log.Info("start to load segments in parallel",
|
||||||
zap.Int("segmentNum", segmentNum),
|
zap.Int("segmentNum", len(infos)),
|
||||||
zap.Int("concurrencyLevel", concurrencyLevel))
|
zap.Int("concurrencyLevel", concurrencyLevel))
|
||||||
err = funcutil.ProcessFuncParallel(segmentNum,
|
err = funcutil.ProcessFuncParallel(len(infos),
|
||||||
concurrencyLevel, loadSegmentFunc, "loadSegmentFunc")
|
concurrencyLevel, loadSegmentFunc, "loadSegmentFunc")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
clearAll()
|
clearAll()
|
||||||
@ -290,7 +287,14 @@ func (loader *segmentLoader) unregister(segments ...*querypb.SegmentLoadInfo) {
|
|||||||
loader.mut.Lock()
|
loader.mut.Lock()
|
||||||
defer loader.mut.Unlock()
|
defer loader.mut.Unlock()
|
||||||
for i := range segments {
|
for i := range segments {
|
||||||
loader.loadingSegments.GetAndRemove(segments[i].GetSegmentID())
|
waitCh, ok := loader.loadingSegments.GetAndRemove(segments[i].GetSegmentID())
|
||||||
|
if ok {
|
||||||
|
select {
|
||||||
|
case <-waitCh:
|
||||||
|
default: // close wait channel for failed task
|
||||||
|
close(waitCh)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,26 +306,32 @@ func (loader *segmentLoader) requestResource(infos ...*querypb.SegmentLoadInfo)
|
|||||||
|
|
||||||
concurrencyLevel := funcutil.Min(runtime.GOMAXPROCS(0), len(infos))
|
concurrencyLevel := funcutil.Min(runtime.GOMAXPROCS(0), len(infos))
|
||||||
|
|
||||||
logNum := 0
|
var memUsage, diskUsage uint64
|
||||||
for _, field := range infos[0].GetBinlogPaths() {
|
for _, info := range infos {
|
||||||
logNum += len(field.GetBinlogs())
|
logNum := 0
|
||||||
}
|
for _, field := range info.GetBinlogPaths() {
|
||||||
if logNum > 0 {
|
logNum += len(field.GetBinlogs())
|
||||||
// IO pool will be run out even with the new smaller level
|
}
|
||||||
concurrencyLevel = funcutil.Min(concurrencyLevel, funcutil.Max(loader.ioPool.Free()/logNum, 1))
|
if logNum > 0 {
|
||||||
}
|
// IO pool will be run out even with the new smaller level
|
||||||
|
concurrencyLevel = funcutil.Min(concurrencyLevel, funcutil.Max(loader.ioPool.Free()/logNum, 1))
|
||||||
for ; concurrencyLevel > 1; concurrencyLevel /= 2 {
|
|
||||||
_, _, err := loader.checkSegmentSize(infos, concurrencyLevel)
|
|
||||||
if err == nil {
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
memUsage, diskUsage, err := loader.checkSegmentSize(infos, concurrencyLevel)
|
for ; concurrencyLevel > 1; concurrencyLevel /= 2 {
|
||||||
if err != nil {
|
_, _, err := loader.checkSegmentSize(infos, concurrencyLevel)
|
||||||
log.Warn("no sufficient resource to load segments", zap.Error(err))
|
if err == nil {
|
||||||
return 0, 0, 0, err
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mu, du, err := loader.checkSegmentSize(infos, concurrencyLevel)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("no sufficient resource to load segments", zap.Error(err))
|
||||||
|
return 0, 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
memUsage += mu
|
||||||
|
diskUsage += du
|
||||||
}
|
}
|
||||||
|
|
||||||
loader.committedMemSize += memUsage
|
loader.committedMemSize += memUsage
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user