2022-10-11 11:39:22 +08:00
|
|
|
// Licensed to the LF AI & Data foundation under one
|
|
|
|
// or more contributor license agreements. See the NOTICE file
|
|
|
|
// distributed with this work for additional information
|
|
|
|
// regarding copyright ownership. The ASF licenses this file
|
|
|
|
// to you under the Apache License, Version 2.0 (the
|
|
|
|
// "License"); you may not use this file except in compliance
|
|
|
|
// with the License. You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2022-09-15 18:48:32 +08:00
|
|
|
package task
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"time"
|
|
|
|
|
2022-12-13 16:17:22 +08:00
|
|
|
"go.uber.org/zap"
|
|
|
|
|
2022-10-16 20:49:27 +08:00
|
|
|
"github.com/milvus-io/milvus-proto/go-api/commonpb"
|
2023-03-04 23:21:50 +08:00
|
|
|
"github.com/milvus-io/milvus-proto/go-api/msgpb"
|
2022-10-16 20:49:27 +08:00
|
|
|
"github.com/milvus-io/milvus-proto/go-api/schemapb"
|
2022-12-13 16:17:22 +08:00
|
|
|
"github.com/milvus-io/milvus/internal/log"
|
2022-09-15 18:48:32 +08:00
|
|
|
"github.com/milvus-io/milvus/internal/proto/datapb"
|
|
|
|
"github.com/milvus-io/milvus/internal/proto/querypb"
|
|
|
|
"github.com/milvus-io/milvus/internal/querycoordv2/meta"
|
2022-10-21 15:57:28 +08:00
|
|
|
"github.com/milvus-io/milvus/internal/util/commonpbutil"
|
2022-12-13 16:17:22 +08:00
|
|
|
"github.com/milvus-io/milvus/internal/util/tsoutil"
|
2022-09-15 18:48:32 +08:00
|
|
|
"github.com/milvus-io/milvus/internal/util/typeutil"
|
|
|
|
)
|
|
|
|
|
|
|
|
func Wait(ctx context.Context, timeout time.Duration, tasks ...Task) error {
|
|
|
|
ctx, cancel := context.WithTimeout(ctx, timeout)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
var err error
|
|
|
|
go func() {
|
|
|
|
for _, task := range tasks {
|
|
|
|
err = task.Wait()
|
|
|
|
if err != nil {
|
|
|
|
cancel()
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cancel()
|
|
|
|
}()
|
|
|
|
<-ctx.Done()
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-11-07 14:53:02 +08:00
|
|
|
func SetPriority(priority Priority, tasks ...Task) {
|
|
|
|
for i := range tasks {
|
|
|
|
tasks[i].SetPriority(priority)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-06 22:59:19 +08:00
|
|
|
func SetPriorityWithFunc(f func(t Task) Priority, tasks ...Task) {
|
|
|
|
for i := range tasks {
|
|
|
|
tasks[i].SetPriority(f(tasks[i]))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-15 18:48:32 +08:00
|
|
|
// GetTaskType returns the task's type,
|
|
|
|
// for now, only 3 types;
|
|
|
|
// - only 1 grow action -> Grow
|
|
|
|
// - only 1 reduce action -> Reduce
|
|
|
|
// - 1 grow action, and ends with 1 reduce action -> Move
|
|
|
|
func GetTaskType(task Task) Type {
|
|
|
|
if len(task.Actions()) > 1 {
|
|
|
|
return TaskTypeMove
|
|
|
|
} else if task.Actions()[0].Type() == ActionTypeGrow {
|
|
|
|
return TaskTypeGrow
|
|
|
|
} else {
|
|
|
|
return TaskTypeReduce
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func packLoadSegmentRequest(
|
|
|
|
task *SegmentTask,
|
|
|
|
action Action,
|
|
|
|
schema *schemapb.CollectionSchema,
|
|
|
|
loadMeta *querypb.LoadMetaInfo,
|
|
|
|
loadInfo *querypb.SegmentLoadInfo,
|
2022-12-13 16:17:22 +08:00
|
|
|
resp *datapb.GetSegmentInfoResponse,
|
2022-09-15 18:48:32 +08:00
|
|
|
) *querypb.LoadSegmentsRequest {
|
2023-03-04 23:21:50 +08:00
|
|
|
var deltaPosition *msgpb.MsgPosition
|
2022-12-13 16:17:22 +08:00
|
|
|
segment := resp.GetInfos()[0]
|
|
|
|
|
|
|
|
var posSrcStr string
|
|
|
|
if resp.GetChannelCheckpoint() != nil && resp.ChannelCheckpoint[segment.InsertChannel] != nil {
|
|
|
|
deltaPosition = resp.ChannelCheckpoint[segment.InsertChannel]
|
|
|
|
posSrcStr = "channelCheckpoint"
|
|
|
|
} else if segment.GetDmlPosition() != nil {
|
|
|
|
deltaPosition = segment.GetDmlPosition()
|
|
|
|
posSrcStr = "segmentDMLPos"
|
|
|
|
} else {
|
2022-09-30 17:20:55 +08:00
|
|
|
deltaPosition = segment.GetStartPosition()
|
2022-12-13 16:17:22 +08:00
|
|
|
posSrcStr = "segmentStartPos"
|
|
|
|
}
|
|
|
|
|
|
|
|
posTime := tsoutil.PhysicalTime(deltaPosition.GetTimestamp())
|
|
|
|
tsLag := time.Since(posTime)
|
|
|
|
if tsLag >= 10*time.Minute {
|
|
|
|
log.Warn("deltaPosition is quite stale when packLoadSegmentRequest",
|
|
|
|
zap.Int64("taskID", task.ID()),
|
|
|
|
zap.Int64("collectionID", task.CollectionID()),
|
|
|
|
zap.Int64("segmentID", task.SegmentID()),
|
|
|
|
zap.Int64("node", action.Node()),
|
|
|
|
zap.Int64("source", task.SourceID()),
|
|
|
|
zap.String("channel", segment.InsertChannel),
|
|
|
|
zap.String("posSource", posSrcStr),
|
|
|
|
zap.Uint64("posTs", deltaPosition.GetTimestamp()),
|
|
|
|
zap.Time("posTime", posTime),
|
|
|
|
zap.Duration("tsLag", tsLag))
|
2022-09-30 17:20:55 +08:00
|
|
|
}
|
|
|
|
|
2022-09-15 18:48:32 +08:00
|
|
|
return &querypb.LoadSegmentsRequest{
|
2022-10-21 15:57:28 +08:00
|
|
|
Base: commonpbutil.NewMsgBase(
|
|
|
|
commonpbutil.WithMsgType(commonpb.MsgType_LoadSegments),
|
|
|
|
commonpbutil.WithMsgID(task.ID()),
|
|
|
|
),
|
2022-09-15 18:48:32 +08:00
|
|
|
Infos: []*querypb.SegmentLoadInfo{loadInfo},
|
|
|
|
Schema: schema,
|
|
|
|
LoadMeta: loadMeta,
|
|
|
|
CollectionID: task.CollectionID(),
|
|
|
|
ReplicaID: task.ReplicaID(),
|
2023-03-04 23:21:50 +08:00
|
|
|
DeltaPositions: []*msgpb.MsgPosition{deltaPosition},
|
2022-09-15 18:48:32 +08:00
|
|
|
DstNodeID: action.Node(),
|
|
|
|
Version: time.Now().UnixNano(),
|
|
|
|
NeedTransfer: true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-26 14:08:52 +08:00
|
|
|
func packReleaseSegmentRequest(task *SegmentTask, action *SegmentAction) *querypb.ReleaseSegmentsRequest {
|
2022-09-15 18:48:32 +08:00
|
|
|
return &querypb.ReleaseSegmentsRequest{
|
2022-10-21 15:57:28 +08:00
|
|
|
Base: commonpbutil.NewMsgBase(
|
|
|
|
commonpbutil.WithMsgType(commonpb.MsgType_ReleaseSegments),
|
|
|
|
commonpbutil.WithMsgID(task.ID()),
|
|
|
|
),
|
2022-09-15 18:48:32 +08:00
|
|
|
|
|
|
|
NodeID: action.Node(),
|
|
|
|
CollectionID: task.CollectionID(),
|
|
|
|
SegmentIDs: []int64{task.SegmentID()},
|
|
|
|
Scope: action.Scope(),
|
2022-09-28 12:10:54 +08:00
|
|
|
Shard: action.Shard(),
|
2022-09-15 18:48:32 +08:00
|
|
|
NeedTransfer: false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func packLoadMeta(loadType querypb.LoadType, collectionID int64, partitions ...int64) *querypb.LoadMetaInfo {
|
|
|
|
return &querypb.LoadMetaInfo{
|
|
|
|
LoadType: loadType,
|
|
|
|
CollectionID: collectionID,
|
|
|
|
PartitionIDs: partitions,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func packSubDmChannelRequest(
|
|
|
|
task *ChannelTask,
|
|
|
|
action Action,
|
|
|
|
schema *schemapb.CollectionSchema,
|
|
|
|
loadMeta *querypb.LoadMetaInfo,
|
|
|
|
channel *meta.DmChannel,
|
|
|
|
) *querypb.WatchDmChannelsRequest {
|
|
|
|
return &querypb.WatchDmChannelsRequest{
|
2022-10-21 15:57:28 +08:00
|
|
|
Base: commonpbutil.NewMsgBase(
|
|
|
|
commonpbutil.WithMsgType(commonpb.MsgType_WatchDmChannels),
|
|
|
|
commonpbutil.WithMsgID(task.ID()),
|
|
|
|
),
|
2022-09-15 18:48:32 +08:00
|
|
|
NodeID: action.Node(),
|
|
|
|
CollectionID: task.CollectionID(),
|
|
|
|
Infos: []*datapb.VchannelInfo{channel.VchannelInfo},
|
|
|
|
Schema: schema,
|
|
|
|
LoadMeta: loadMeta,
|
|
|
|
ReplicaID: task.ReplicaID(),
|
2022-11-15 13:21:07 +08:00
|
|
|
Version: time.Now().UnixNano(),
|
2022-09-15 18:48:32 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func fillSubDmChannelRequest(
|
|
|
|
ctx context.Context,
|
|
|
|
req *querypb.WatchDmChannelsRequest,
|
|
|
|
broker meta.Broker,
|
|
|
|
) error {
|
|
|
|
segmentIDs := typeutil.NewUniqueSet()
|
|
|
|
for _, vchannel := range req.GetInfos() {
|
|
|
|
segmentIDs.Insert(vchannel.GetFlushedSegmentIds()...)
|
|
|
|
segmentIDs.Insert(vchannel.GetUnflushedSegmentIds()...)
|
|
|
|
}
|
|
|
|
|
|
|
|
if segmentIDs.Len() == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err := broker.GetSegmentInfo(ctx, segmentIDs.Collect()...)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
segmentInfos := make(map[int64]*datapb.SegmentInfo)
|
2022-12-13 16:17:22 +08:00
|
|
|
for _, info := range resp.GetInfos() {
|
2022-09-15 18:48:32 +08:00
|
|
|
segmentInfos[info.GetID()] = info
|
|
|
|
}
|
|
|
|
req.SegmentInfos = segmentInfos
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func packUnsubDmChannelRequest(task *ChannelTask, action Action) *querypb.UnsubDmChannelRequest {
|
|
|
|
return &querypb.UnsubDmChannelRequest{
|
2022-10-21 15:57:28 +08:00
|
|
|
Base: commonpbutil.NewMsgBase(
|
|
|
|
commonpbutil.WithMsgType(commonpb.MsgType_UnsubDmChannel),
|
|
|
|
commonpbutil.WithMsgID(task.ID()),
|
|
|
|
),
|
2022-09-15 18:48:32 +08:00
|
|
|
NodeID: action.Node(),
|
|
|
|
CollectionID: task.CollectionID(),
|
|
|
|
ChannelName: task.Channel(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func getShardLeader(replicaMgr *meta.ReplicaManager, distMgr *meta.DistributionManager, collectionID, nodeID int64, channel string) (int64, bool) {
|
|
|
|
replica := replicaMgr.GetByCollectionAndNode(collectionID, nodeID)
|
|
|
|
if replica == nil {
|
|
|
|
return 0, false
|
|
|
|
}
|
|
|
|
return distMgr.GetShardLeader(replica, channel)
|
|
|
|
}
|