2023-10-31 02:30:16 +08:00
|
|
|
package syncmgr
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2023-11-15 15:24:18 +08:00
|
|
|
"fmt"
|
2023-10-31 02:30:16 +08:00
|
|
|
"strconv"
|
|
|
|
|
2023-12-15 09:58:43 +08:00
|
|
|
"go.uber.org/zap"
|
|
|
|
|
2023-10-31 02:30:16 +08:00
|
|
|
"github.com/milvus-io/milvus-proto/go-api/v2/msgpb"
|
|
|
|
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
|
|
|
"github.com/milvus-io/milvus/internal/allocator"
|
|
|
|
"github.com/milvus-io/milvus/internal/datanode/metacache"
|
|
|
|
"github.com/milvus-io/milvus/internal/storage"
|
2023-12-15 09:58:43 +08:00
|
|
|
"github.com/milvus-io/milvus/pkg/config"
|
|
|
|
"github.com/milvus-io/milvus/pkg/log"
|
2023-11-15 15:24:18 +08:00
|
|
|
"github.com/milvus-io/milvus/pkg/util/conc"
|
2023-10-31 02:30:16 +08:00
|
|
|
"github.com/milvus-io/milvus/pkg/util/merr"
|
2023-12-15 09:58:43 +08:00
|
|
|
"github.com/milvus-io/milvus/pkg/util/paramtable"
|
2023-10-31 02:30:16 +08:00
|
|
|
"github.com/milvus-io/milvus/pkg/util/typeutil"
|
|
|
|
)
|
|
|
|
|
|
|
|
type SyncManagerOption struct {
|
|
|
|
chunkManager storage.ChunkManager
|
|
|
|
allocator allocator.Interface
|
|
|
|
parallelTask int
|
|
|
|
}
|
|
|
|
|
|
|
|
type SyncMeta struct {
|
|
|
|
collectionID int64
|
|
|
|
partitionID int64
|
|
|
|
segmentID int64
|
|
|
|
channelName string
|
|
|
|
schema *schemapb.CollectionSchema
|
|
|
|
checkpoint *msgpb.MsgPosition
|
|
|
|
tsFrom typeutil.Timestamp
|
|
|
|
tsTo typeutil.Timestamp
|
|
|
|
|
|
|
|
metacache metacache.MetaCache
|
|
|
|
}
|
|
|
|
|
2024-05-24 09:07:41 +08:00
|
|
|
// SyncManager is the interface for sync manager.
|
2023-11-16 00:22:20 +08:00
|
|
|
// it processes the sync tasks inside and changes the meta.
|
2024-05-24 09:07:41 +08:00
|
|
|
//
|
|
|
|
//go:generate mockery --name=SyncManager --structname=MockSyncManager --output=./ --filename=mock_sync_manager.go --with-expecter --inpackage
|
2023-10-31 02:30:16 +08:00
|
|
|
type SyncManager interface {
|
2023-11-16 00:22:20 +08:00
|
|
|
// SyncData is the method to submit sync task.
|
2024-06-05 10:05:50 +08:00
|
|
|
SyncData(ctx context.Context, task Task, callbacks ...func(error) error) *conc.Future[struct{}]
|
2023-10-31 02:30:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
type syncManager struct {
|
|
|
|
*keyLockDispatcher[int64]
|
|
|
|
chunkManager storage.ChunkManager
|
2023-11-15 15:24:18 +08:00
|
|
|
|
2023-11-23 17:26:24 +08:00
|
|
|
tasks *typeutil.ConcurrentMap[string, Task]
|
2023-10-31 02:30:16 +08:00
|
|
|
}
|
|
|
|
|
2024-07-07 21:26:14 +08:00
|
|
|
func NewSyncManager(chunkManager storage.ChunkManager) (SyncManager, error) {
|
2023-12-15 09:58:43 +08:00
|
|
|
params := paramtable.Get()
|
|
|
|
initPoolSize := params.DataNodeCfg.MaxParallelSyncMgrTasks.GetAsInt()
|
|
|
|
if initPoolSize < 1 {
|
|
|
|
return nil, merr.WrapErrParameterInvalid("positive parallel task number", strconv.FormatInt(int64(initPoolSize), 10))
|
2023-10-31 02:30:16 +08:00
|
|
|
}
|
2023-12-15 09:58:43 +08:00
|
|
|
dispatcher := newKeyLockDispatcher[int64](initPoolSize)
|
|
|
|
log.Info("sync manager initialized", zap.Int("initPoolSize", initPoolSize))
|
|
|
|
|
|
|
|
syncMgr := &syncManager{
|
|
|
|
keyLockDispatcher: dispatcher,
|
2023-10-31 02:30:16 +08:00
|
|
|
chunkManager: chunkManager,
|
2023-11-23 17:26:24 +08:00
|
|
|
tasks: typeutil.NewConcurrentMap[string, Task](),
|
2023-12-15 09:58:43 +08:00
|
|
|
}
|
|
|
|
// setup config update watcher
|
|
|
|
params.Watch(params.DataNodeCfg.MaxParallelSyncMgrTasks.Key, config.NewHandler("datanode.syncmgr.poolsize", syncMgr.resizeHandler))
|
|
|
|
|
|
|
|
return syncMgr, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mgr *syncManager) resizeHandler(evt *config.Event) {
|
|
|
|
if evt.HasUpdated {
|
|
|
|
log := log.Ctx(context.Background()).With(
|
|
|
|
zap.String("key", evt.Key),
|
|
|
|
zap.String("value", evt.Value),
|
|
|
|
)
|
|
|
|
size, err := strconv.ParseInt(evt.Value, 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
log.Warn("failed to parse new datanode syncmgr pool size", zap.Error(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
err = mgr.keyLockDispatcher.workerPool.Resize(int(size))
|
|
|
|
if err != nil {
|
|
|
|
log.Warn("failed to resize datanode syncmgr pool size", zap.String("key", evt.Key), zap.String("value", evt.Value), zap.Error(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
log.Info("sync mgr pool size updated", zap.Int64("newSize", size))
|
|
|
|
}
|
2023-10-31 02:30:16 +08:00
|
|
|
}
|
|
|
|
|
2024-06-05 10:05:50 +08:00
|
|
|
func (mgr *syncManager) SyncData(ctx context.Context, task Task, callbacks ...func(error) error) *conc.Future[struct{}] {
|
2023-11-23 17:26:24 +08:00
|
|
|
switch t := task.(type) {
|
|
|
|
case *SyncTask:
|
2024-07-07 21:26:14 +08:00
|
|
|
t.WithChunkManager(mgr.chunkManager)
|
2023-11-23 17:26:24 +08:00
|
|
|
case *SyncTaskV2:
|
|
|
|
}
|
2023-10-31 02:30:16 +08:00
|
|
|
|
2024-06-25 14:22:04 +08:00
|
|
|
return mgr.safeSubmitTask(ctx, task, callbacks...)
|
2024-02-05 11:33:43 +08:00
|
|
|
}
|
|
|
|
|
2024-06-23 21:12:01 +08:00
|
|
|
// safeSubmitTask submits task to SyncManager
|
2024-06-25 14:22:04 +08:00
|
|
|
func (mgr *syncManager) safeSubmitTask(ctx context.Context, task Task, callbacks ...func(error) error) *conc.Future[struct{}] {
|
2023-11-23 17:26:24 +08:00
|
|
|
taskKey := fmt.Sprintf("%d-%d", task.SegmentID(), task.Checkpoint().GetTimestamp())
|
2023-11-15 15:24:18 +08:00
|
|
|
mgr.tasks.Insert(taskKey, task)
|
|
|
|
|
2024-06-23 21:12:01 +08:00
|
|
|
key := task.SegmentID()
|
2024-06-25 14:22:04 +08:00
|
|
|
return mgr.submit(ctx, key, task, callbacks...)
|
2024-05-09 10:09:30 +08:00
|
|
|
}
|
|
|
|
|
2024-06-25 14:22:04 +08:00
|
|
|
func (mgr *syncManager) submit(ctx context.Context, key int64, task Task, callbacks ...func(error) error) *conc.Future[struct{}] {
|
2024-05-09 10:09:30 +08:00
|
|
|
handler := func(err error) error {
|
2024-05-09 18:03:31 +08:00
|
|
|
if err == nil {
|
|
|
|
return nil
|
|
|
|
}
|
2024-06-23 21:12:01 +08:00
|
|
|
task.HandleError(err)
|
|
|
|
return err
|
2024-05-09 10:09:30 +08:00
|
|
|
}
|
2024-06-05 10:05:50 +08:00
|
|
|
callbacks = append([]func(error) error{handler}, callbacks...)
|
2024-05-09 10:09:30 +08:00
|
|
|
log.Info("sync mgr sumbit task with key", zap.Int64("key", key))
|
2024-06-25 14:22:04 +08:00
|
|
|
return mgr.Submit(ctx, key, task, callbacks...)
|
2023-11-15 15:24:18 +08:00
|
|
|
}
|