Skip to content

Commit 85321bd

Browse files
committed
feat: add deployment mode switching for QueryNode (#298)
- Added DeployMode field to MilvusQueryNode struct to support OneDeployMode and TwoDeployMode - Modified DeployControllerImpl to reconcile QueryNode deployment mode based on configuration - Implemented ChangeToOneDeployMode and ChangeToTwoDeployMode in DeployControllerBizImpl - Updated test cases in deploy_ctrl_test.go to cover deployment mode switching Signed-off-by: hodie-aurora <zhw1726195788@gmail.com>
1 parent 01440d5 commit 85321bd

File tree

5 files changed

+736
-27
lines changed

5 files changed

+736
-27
lines changed

apis/milvus.io/v1beta1/components_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,10 @@ type Component struct {
264264

265265
type MilvusQueryNode struct {
266266
Component `json:",inline"`
267+
// +kubebuilder:validation:Enum=OneDeployMode;TwoDeployMode
268+
// +kubebuilder:default:=TwoDeployMode
269+
// +kubebuilder:validation:Optional
270+
DeployMode string `json:"deployMode,omitempty"`
267271
}
268272

269273
type MilvusDataNode struct {

pkg/controllers/deploy_ctrl.go

Lines changed: 160 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,48 @@ func (c *DeployControllerImpl) Reconcile(ctx context.Context, mc v1beta1.Milvus,
5151
return errors.Wrap(err, "update milvus rolling mode status")
5252
}
5353
biz := c.bizFactory.GetBiz(component)
54+
// Reconcile QueryNode deploy mode
55+
if component == QueryNode {
56+
// Parse and compare deploy mode
57+
configuredDeployMode, err := parseDeployMode(mc.Spec.Com.QueryNode)
58+
if err != nil {
59+
return errors.Wrap(err, "parse deploy mode")
60+
}
61+
currentDeployMode, err := biz.CheckDeployMode(ctx, mc)
62+
if err != nil {
63+
return errors.Wrap(err, "check deploy mode")
64+
}
65+
if configuredDeployMode != currentDeployMode {
66+
logger.Info("deploy mode mismatch detected", "configured", configuredDeployMode, "current", currentDeployMode)
67+
if configuredDeployMode == v1beta1.OneDeployMode {
68+
err = biz.ChangeToOneDeployMode(ctx, mc)
69+
if err != nil {
70+
return errors.Wrap(err, "change to OneDeployMode")
71+
}
72+
} else if configuredDeployMode == v1beta1.TwoDeployMode {
73+
err = biz.ChangeToTwoDeployMode(ctx, mc)
74+
if err != nil {
75+
return errors.Wrap(err, "change to TwoDeployMode")
76+
}
77+
}
78+
err = biz.MarkDeployModeChanging(ctx, mc, true)
79+
if err != nil {
80+
return err
81+
}
82+
return errors.New("requeue after deploy mode change")
83+
}
84+
err = biz.MarkDeployModeChanging(ctx, mc, false)
85+
if err != nil {
86+
return err
87+
}
88+
return c.handleTwoDeployMode(ctx, mc, biz)
89+
}
90+
91+
err = c.rollingModeStatusUpdater.Update(ctx, &mc)
92+
if err != nil {
93+
return errors.Wrap(err, "update milvus rolling mode status")
94+
}
95+
biz = c.bizFactory.GetBiz(component)
5496
deployMode, err := biz.CheckDeployMode(ctx, mc)
5597
if err != nil {
5698
return errors.Wrap(err, "check deploy mode")
@@ -138,6 +180,7 @@ type DeployControllerBiz interface {
138180
type DeployModeChanger interface {
139181
MarkDeployModeChanging(ctx context.Context, mc v1beta1.Milvus, changing bool) error
140182
ChangeToTwoDeployMode(ctx context.Context, mc v1beta1.Milvus) error
183+
ChangeToOneDeployMode(ctx context.Context, mc v1beta1.Milvus) error
141184
}
142185

143186
var _ DeployControllerBiz = &DeployControllerBizImpl{}
@@ -169,7 +212,28 @@ func (c *DeployControllerBizImpl) CheckDeployMode(ctx context.Context, mc v1beta
169212
}
170213
fallthrough
171214
default:
172-
// check in cluster
215+
// continue
216+
}
217+
// Check QueryNode cluster state
218+
if c.component == QueryNode {
219+
mode, err := c.checkDeployModeInCluster(ctx, mc)
220+
if err == nil {
221+
return mode, nil
222+
}
223+
if kerrors.IsNotFound(err) {
224+
return v1beta1.TwoDeployMode, nil
225+
}
226+
if err != nil {
227+
return v1beta1.DeployModeUnknown, errors.Wrap(err, "check deploy mode in cluster")
228+
}
229+
}
230+
// Prioritize configured QueryNode mode
231+
if c.component == QueryNode && mc.Spec.Com.QueryNode != nil && mc.Spec.Com.QueryNode.DeployMode != "" {
232+
configuredDeployMode, err := parseDeployMode(mc.Spec.Com.QueryNode)
233+
if err != nil {
234+
return v1beta1.DeployModeUnknown, errors.Wrap(err, "parse deploy mode in CheckDeployMode")
235+
}
236+
return configuredDeployMode, nil
173237
}
174238
if v1beta1.Labels().IsChangingMode(mc, c.component.Name) {
175239
return v1beta1.OneDeployMode, nil
@@ -336,3 +400,98 @@ func (c *DeployControllerBizImpl) HandleManualMode(ctx context.Context, mc v1bet
336400
}
337401
return nil
338402
}
403+
404+
// ParseDeployMode converts QueryNode DeployMode to ComponentDeployMode
405+
func parseDeployMode(queryNode *v1beta1.MilvusQueryNode) (v1beta1.ComponentDeployMode, error) {
406+
if queryNode == nil || queryNode.DeployMode == "" {
407+
return v1beta1.TwoDeployMode, nil
408+
}
409+
switch queryNode.DeployMode {
410+
case "OneDeployMode":
411+
return v1beta1.OneDeployMode, nil
412+
case "TwoDeployMode":
413+
return v1beta1.TwoDeployMode, nil
414+
default:
415+
return v1beta1.DeployModeUnknown, errors.Errorf("invalid DeployMode: %s, must be OneDeployMode or TwoDeployMode", queryNode.DeployMode)
416+
}
417+
}
418+
419+
// ChangeToOneDeployMode switches QueryNode to single deployment mode
420+
func (c *DeployControllerBizImpl) ChangeToOneDeployMode(ctx context.Context, mc v1beta1.Milvus) error {
421+
if c.component != QueryNode {
422+
return nil
423+
}
424+
currentDeploy, lastDeploy, err := c.util.GetDeploys(ctx, mc)
425+
if err != nil {
426+
return errors.Wrap(err, "get querynode deploys for ChangeToOneDeployMode")
427+
}
428+
if currentDeploy != nil && lastDeploy != nil {
429+
lastDeploy.Spec.Replicas = int32Ptr(0)
430+
err = c.cli.Update(ctx, lastDeploy)
431+
if err != nil {
432+
return errors.Wrap(err, "scale down last deployment")
433+
}
434+
err = c.cli.Delete(ctx, lastDeploy)
435+
if err != nil && !kerrors.IsNotFound(err) {
436+
return errors.Wrap(err, "delete last deployment")
437+
}
438+
}
439+
if currentDeploy != nil {
440+
err = c.util.MarkMilvusComponentGroupId(ctx, mc, c.component, 0)
441+
if err != nil {
442+
return errors.Wrap(err, "mark group id to 0")
443+
}
444+
}
445+
return nil
446+
}
447+
448+
// ChangeToTwoDeployMode switches QueryNode to dual deployment mode
449+
func (c *DeployControllerBizImpl) ChangeToTwoDeployMode(ctx context.Context, mc v1beta1.Milvus) error {
450+
if c.component != QueryNode {
451+
return nil
452+
}
453+
currentDeploy, lastDeploy, err := c.util.GetDeploys(ctx, mc)
454+
if err != nil {
455+
return errors.Wrap(err, "get querynode deploys for ChangeToTwoDeployMode")
456+
}
457+
if currentDeploy != nil && lastDeploy != nil {
458+
return nil
459+
}
460+
if currentDeploy != nil && lastDeploy == nil {
461+
err = c.util.CreateDeploy(ctx, mc, nil, 1)
462+
if err != nil {
463+
return errors.Wrap(err, "create second deployment")
464+
}
465+
currentDeploy.Spec.Replicas = int32Ptr(0)
466+
err = c.cli.Update(ctx, currentDeploy)
467+
if err != nil {
468+
return errors.Wrap(err, "scale down current deployment")
469+
}
470+
}
471+
return nil
472+
}
473+
474+
// handleTwoDeployMode manages QueryNode in dual deployment mode
475+
func (c *DeployControllerImpl) handleTwoDeployMode(ctx context.Context, mc v1beta1.Milvus, biz DeployControllerBiz) error {
476+
if err := biz.HandleCreate(ctx, mc); err != nil {
477+
return errors.Wrap(err, "handle create")
478+
}
479+
if biz.IsPaused(ctx, mc) {
480+
return nil
481+
}
482+
if mc.Spec.Com.EnableManualMode {
483+
return biz.HandleManualMode(ctx, mc)
484+
}
485+
if ReplicasValue(QueryNode.GetReplicas(mc.Spec)) == 0 {
486+
return biz.HandleStop(ctx, mc)
487+
}
488+
err := biz.HandleRolling(ctx, mc)
489+
if err != nil {
490+
return errors.Wrap(err, "handle rolling")
491+
}
492+
err = biz.HandleScaling(ctx, mc)
493+
if err != nil {
494+
return errors.Wrap(err, "handle scaling")
495+
}
496+
return nil
497+
}

0 commit comments

Comments
 (0)