2021-04-19 13:47:10 +08:00
|
|
|
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
|
|
|
//
|
|
|
|
// Licensed 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.
|
|
|
|
|
2021-01-16 10:12:14 +08:00
|
|
|
package querynode
|
2020-11-26 16:01:31 +08:00
|
|
|
|
|
|
|
import "C"
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
2021-03-23 05:59:46 +08:00
|
|
|
"github.com/zilliztech/milvus-distributed/internal/log"
|
|
|
|
"github.com/zilliztech/milvus-distributed/internal/msgstream"
|
2021-03-25 14:41:46 +08:00
|
|
|
"github.com/zilliztech/milvus-distributed/internal/util/trace"
|
2021-03-22 16:36:10 +08:00
|
|
|
"go.uber.org/zap"
|
2021-01-18 19:32:08 +08:00
|
|
|
"strconv"
|
2021-03-05 18:16:50 +08:00
|
|
|
"strings"
|
2020-11-26 16:01:31 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
type searchService struct {
|
|
|
|
ctx context.Context
|
|
|
|
cancel context.CancelFunc
|
|
|
|
|
2021-03-23 05:59:46 +08:00
|
|
|
replica ReplicaInterface
|
2020-11-26 16:01:31 +08:00
|
|
|
|
2020-12-08 14:41:04 +08:00
|
|
|
searchMsgStream msgstream.MsgStream
|
|
|
|
searchResultMsgStream msgstream.MsgStream
|
2021-03-23 05:59:46 +08:00
|
|
|
|
2020-12-08 14:41:04 +08:00
|
|
|
queryNodeID UniqueID
|
2021-03-23 05:59:46 +08:00
|
|
|
searchCollections map[UniqueID]*searchCollection
|
|
|
|
emptySearchCollection *searchCollection
|
2020-11-26 16:01:31 +08:00
|
|
|
}
|
|
|
|
|
2021-03-05 16:52:45 +08:00
|
|
|
func newSearchService(ctx context.Context, replica ReplicaInterface, factory msgstream.Factory) *searchService {
|
2021-03-19 20:16:04 +08:00
|
|
|
searchStream, _ := factory.NewQueryMsgStream(ctx)
|
|
|
|
searchResultStream, _ := factory.NewQueryMsgStream(ctx)
|
2021-02-09 17:09:26 +08:00
|
|
|
|
|
|
|
// query node doesn't need to consumer any search or search result channel actively.
|
2021-02-18 16:26:02 +08:00
|
|
|
consumeChannels := Params.SearchChannelNames
|
|
|
|
consumeSubName := Params.MsgChannelSubName
|
|
|
|
searchStream.AsConsumer(consumeChannels, consumeSubName)
|
2021-03-23 05:59:46 +08:00
|
|
|
log.Debug("query node AsConsumer: " + strings.Join(consumeChannels, ", ") + " : " + consumeSubName)
|
2021-02-18 16:26:02 +08:00
|
|
|
producerChannels := Params.SearchResultChannelNames
|
|
|
|
searchResultStream.AsProducer(producerChannels)
|
2021-03-23 05:59:46 +08:00
|
|
|
log.Debug("query node AsProducer: " + strings.Join(producerChannels, ", "))
|
2020-11-26 16:01:31 +08:00
|
|
|
|
|
|
|
searchServiceCtx, searchServiceCancel := context.WithCancel(ctx)
|
|
|
|
return &searchService{
|
2021-03-23 05:59:46 +08:00
|
|
|
ctx: searchServiceCtx,
|
|
|
|
cancel: searchServiceCancel,
|
2020-11-26 16:01:31 +08:00
|
|
|
|
2021-03-23 05:59:46 +08:00
|
|
|
replica: replica,
|
2020-11-26 16:01:31 +08:00
|
|
|
|
2021-02-09 17:09:26 +08:00
|
|
|
searchMsgStream: searchStream,
|
|
|
|
searchResultMsgStream: searchResultStream,
|
2020-11-26 16:01:31 +08:00
|
|
|
|
2021-03-23 05:59:46 +08:00
|
|
|
queryNodeID: Params.QueryNodeID,
|
|
|
|
searchCollections: make(map[UniqueID]*searchCollection),
|
2020-12-08 14:41:04 +08:00
|
|
|
}
|
2020-11-26 16:01:31 +08:00
|
|
|
}
|
|
|
|
|
2021-03-23 05:59:46 +08:00
|
|
|
func (s *searchService) start() {
|
|
|
|
s.searchMsgStream.Start()
|
|
|
|
s.searchResultMsgStream.Start()
|
|
|
|
s.startEmptySearchCollection()
|
|
|
|
s.consumeSearch()
|
2020-11-26 16:01:31 +08:00
|
|
|
}
|
|
|
|
|
2021-03-23 05:59:46 +08:00
|
|
|
func (s *searchService) collectionCheck(collectionID UniqueID) error {
|
2021-03-22 16:36:10 +08:00
|
|
|
// check if collection exists
|
2021-03-23 05:59:46 +08:00
|
|
|
if ok := s.replica.hasCollection(collectionID); !ok {
|
2021-03-22 16:36:10 +08:00
|
|
|
err := errors.New("no collection found, collectionID = " + strconv.FormatInt(collectionID, 10))
|
|
|
|
log.Error(err.Error())
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-03-23 05:59:46 +08:00
|
|
|
return nil
|
2021-03-22 16:36:10 +08:00
|
|
|
}
|
|
|
|
|
2021-03-23 05:59:46 +08:00
|
|
|
func (s *searchService) consumeSearch() {
|
2020-11-26 16:01:31 +08:00
|
|
|
for {
|
|
|
|
select {
|
2021-03-23 05:59:46 +08:00
|
|
|
case <-s.ctx.Done():
|
2020-11-26 16:01:31 +08:00
|
|
|
return
|
|
|
|
default:
|
2021-03-25 14:41:46 +08:00
|
|
|
msgPack := s.searchMsgStream.Consume()
|
2020-11-26 16:01:31 +08:00
|
|
|
if msgPack == nil || len(msgPack.Msgs) <= 0 {
|
|
|
|
continue
|
|
|
|
}
|
2021-03-22 16:36:10 +08:00
|
|
|
for _, msg := range msgPack.Msgs {
|
2021-03-26 07:09:47 +08:00
|
|
|
log.Debug("consume search message", zap.Int64("msgID", msg.ID()))
|
2021-03-22 16:36:10 +08:00
|
|
|
sm, ok := msg.(*msgstream.SearchMsg)
|
|
|
|
if !ok {
|
2020-11-26 16:01:31 +08:00
|
|
|
continue
|
|
|
|
}
|
2021-03-26 15:13:33 +08:00
|
|
|
sp, ctx := trace.StartSpanFromContext(sm.TraceCtx())
|
|
|
|
sm.SetTraceCtx(ctx)
|
2021-03-23 05:59:46 +08:00
|
|
|
err := s.collectionCheck(sm.CollectionID)
|
2021-03-22 16:36:10 +08:00
|
|
|
if err != nil {
|
2021-03-23 05:59:46 +08:00
|
|
|
s.emptySearchCollection.emptySearch(sm)
|
2021-03-26 07:09:47 +08:00
|
|
|
log.Debug("cannot found collection, do empty search done",
|
|
|
|
zap.Int64("msgID", sm.ID()),
|
|
|
|
zap.Int64("collectionID", sm.CollectionID))
|
2021-03-22 16:36:10 +08:00
|
|
|
continue
|
|
|
|
}
|
2021-04-16 14:40:33 +08:00
|
|
|
_, ok = s.searchCollections[sm.CollectionID]
|
2021-03-22 16:36:10 +08:00
|
|
|
if !ok {
|
2021-03-23 05:59:46 +08:00
|
|
|
s.startSearchCollection(sm.CollectionID)
|
2021-03-26 07:09:47 +08:00
|
|
|
log.Debug("new search collection, start search collection service",
|
|
|
|
zap.Int64("collectionID", sm.CollectionID))
|
2020-11-26 16:01:31 +08:00
|
|
|
}
|
2021-04-16 14:40:33 +08:00
|
|
|
s.searchCollections[sm.CollectionID].msgBuffer <- sm
|
2021-03-25 14:41:46 +08:00
|
|
|
sp.Finish()
|
2020-11-26 16:01:31 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-23 05:59:46 +08:00
|
|
|
func (s *searchService) close() {
|
|
|
|
if s.searchMsgStream != nil {
|
|
|
|
s.searchMsgStream.Close()
|
2020-12-03 19:00:11 +08:00
|
|
|
}
|
2021-03-23 05:59:46 +08:00
|
|
|
if s.searchResultMsgStream != nil {
|
|
|
|
s.searchResultMsgStream.Close()
|
2020-11-26 16:01:31 +08:00
|
|
|
}
|
2021-03-23 05:59:46 +08:00
|
|
|
for collectionID := range s.searchCollections {
|
|
|
|
s.stopSearchCollection(collectionID)
|
2020-11-26 16:01:31 +08:00
|
|
|
}
|
2021-03-23 05:59:46 +08:00
|
|
|
s.searchCollections = make(map[UniqueID]*searchCollection)
|
|
|
|
s.cancel()
|
2020-11-26 16:01:31 +08:00
|
|
|
}
|
|
|
|
|
2021-03-23 05:59:46 +08:00
|
|
|
func (s *searchService) startSearchCollection(collectionID UniqueID) {
|
|
|
|
ctx1, cancel := context.WithCancel(s.ctx)
|
|
|
|
sc := newSearchCollection(ctx1, cancel, collectionID, s.replica, s.searchResultMsgStream)
|
|
|
|
s.searchCollections[collectionID] = sc
|
|
|
|
sc.start()
|
2020-11-26 16:01:31 +08:00
|
|
|
}
|
|
|
|
|
2021-03-23 05:59:46 +08:00
|
|
|
func (s *searchService) startEmptySearchCollection() {
|
|
|
|
ctx1, cancel := context.WithCancel(s.ctx)
|
|
|
|
sc := newSearchCollection(ctx1, cancel, UniqueID(-1), s.replica, s.searchResultMsgStream)
|
|
|
|
s.emptySearchCollection = sc
|
|
|
|
sc.start()
|
|
|
|
}
|
2020-11-26 16:01:31 +08:00
|
|
|
|
2021-03-23 05:59:46 +08:00
|
|
|
func (s *searchService) hasSearchCollection(collectionID UniqueID) bool {
|
|
|
|
_, ok := s.searchCollections[collectionID]
|
|
|
|
return ok
|
|
|
|
}
|
2021-01-18 19:32:08 +08:00
|
|
|
|
2021-03-23 05:59:46 +08:00
|
|
|
func (s *searchService) stopSearchCollection(collectionID UniqueID) {
|
|
|
|
sc, ok := s.searchCollections[collectionID]
|
|
|
|
if !ok {
|
|
|
|
log.Error("stopSearchCollection failed, collection doesn't exist", zap.Int64("collectionID", collectionID))
|
2020-11-26 16:01:31 +08:00
|
|
|
}
|
2021-03-23 05:59:46 +08:00
|
|
|
sc.cancel()
|
|
|
|
delete(s.searchCollections, collectionID)
|
2020-11-26 16:01:31 +08:00
|
|
|
}
|