diff --git a/components/playground/instance/pd.go b/components/playground/instance/pd.go index 52cb360d28..d8b2dd483c 100644 --- a/components/playground/instance/pd.go +++ b/components/playground/instance/pd.go @@ -84,7 +84,14 @@ func (inst *PDInstance) InitCluster(pds []*PDInstance) *PDInstance { // Name return the name of pd. func (inst *PDInstance) Name() string { - return fmt.Sprintf("pd-%d", inst.ID) + switch inst.Role { + case PDRoleTSO: + return fmt.Sprintf("tso-%d", inst.ID) + case PDRoleScheduling: + return fmt.Sprintf("scheduling-%d", inst.ID) + default: + return fmt.Sprintf("pd-%d", inst.ID) + } } // Start calls set inst.cmd and Start @@ -137,6 +144,7 @@ func (inst *PDInstance) Start(ctx context.Context, version utils.Version) error args = []string{ "services", "tso", + "--name=" + uid, fmt.Sprintf("--listen-addr=http://%s", utils.JoinHostPort(inst.Host, inst.StatusPort)), fmt.Sprintf("--advertise-listen-addr=http://%s", utils.JoinHostPort(AdvertiseHost(inst.Host), inst.StatusPort)), fmt.Sprintf("--backend-endpoints=%s", strings.Join(endpoints, ",")), @@ -148,6 +156,7 @@ func (inst *PDInstance) Start(ctx context.Context, version utils.Version) error args = []string{ "services", "scheduling", + "--name=" + uid, fmt.Sprintf("--listen-addr=http://%s", utils.JoinHostPort(inst.Host, inst.StatusPort)), fmt.Sprintf("--advertise-listen-addr=http://%s", utils.JoinHostPort(AdvertiseHost(inst.Host), inst.StatusPort)), fmt.Sprintf("--backend-endpoints=%s", strings.Join(endpoints, ",")), diff --git a/embed/templates/scripts/run_scheduling.sh.tpl b/embed/templates/scripts/run_scheduling.sh.tpl index a15b1ba4f7..d548d07c6f 100644 --- a/embed/templates/scripts/run_scheduling.sh.tpl +++ b/embed/templates/scripts/run_scheduling.sh.tpl @@ -12,6 +12,7 @@ exec numactl --cpunodebind={{.NumaNode}} --membind={{.NumaNode}} env GODEBUG=mad {{- else}} exec env GODEBUG=madvdontneed=1 bin/pd-server services scheduling \ {{- end}} + --name="{{.Name}}" \ --backend-endpoints="{{.BackendEndpoints}}" \ --listen-addr="{{.ListenURL}}" \ --advertise-listen-addr="{{.AdvertiseListenURL}}" \ diff --git a/embed/templates/scripts/run_tso.sh.tpl b/embed/templates/scripts/run_tso.sh.tpl index 0d6486d73e..fe236d1410 100644 --- a/embed/templates/scripts/run_tso.sh.tpl +++ b/embed/templates/scripts/run_tso.sh.tpl @@ -12,6 +12,7 @@ exec numactl --cpunodebind={{.NumaNode}} --membind={{.NumaNode}} env GODEBUG=mad {{- else}} exec env GODEBUG=madvdontneed=1 bin/pd-server services tso \ {{- end}} + --name="{{.Name}}" \ --backend-endpoints="{{.BackendEndpoints}}" \ --listen-addr="{{.ListenURL}}" \ --advertise-listen-addr="{{.AdvertiseListenURL}}" \ diff --git a/pkg/cluster/spec/scheduling.go b/pkg/cluster/spec/scheduling.go index efbe7def00..c7257cc666 100644 --- a/pkg/cluster/spec/scheduling.go +++ b/pkg/cluster/spec/scheduling.go @@ -30,6 +30,8 @@ import ( // SchedulingSpec represents the scheduling topology specification in topology.yaml type SchedulingSpec struct { + // Use Name to get the name with a default value if it's empty. + Name string `yaml:"name"` Host string `yaml:"host"` ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` ListenHost string `yaml:"listen_host,omitempty"` @@ -169,7 +171,7 @@ func (c *SchedulingComponent) Instances() []Instance { ins = append(ins, &SchedulingInstance{ BaseInstance: BaseInstance{ InstanceSpec: s, - Name: c.Name(), + Name: s.Name, Host: s.Host, ManageHost: s.ManageHost, ListenHost: utils.Ternary(s.ListenHost != "", s.ListenHost, c.Topology.BaseTopo().GlobalOptions.ListenHost).(string), @@ -229,6 +231,7 @@ func (i *SchedulingInstance) InitConfig( pds = append(pds, pdspec.GetAdvertiseClientURL(enableTLS)) } cfg := &scripts.SchedulingScript{ + Name: spec.Name, ListenURL: fmt.Sprintf("%s://%s", scheme, utils.JoinHostPort(i.GetListenHost(), spec.Port)), AdvertiseListenURL: spec.GetAdvertiseListenURL(enableTLS), BackendEndpoints: strings.Join(pds, ","), diff --git a/pkg/cluster/spec/tso.go b/pkg/cluster/spec/tso.go index a84069f6ee..2f342a33df 100644 --- a/pkg/cluster/spec/tso.go +++ b/pkg/cluster/spec/tso.go @@ -30,6 +30,8 @@ import ( // TSOSpec represents the TSO topology specification in topology.yaml type TSOSpec struct { + // Use Name to get the name with a default value if it's empty. + Name string `yaml:"name"` Host string `yaml:"host"` ManageHost string `yaml:"manage_host,omitempty" validate:"manage_host:editable"` ListenHost string `yaml:"listen_host,omitempty"` @@ -169,7 +171,7 @@ func (c *TSOComponent) Instances() []Instance { ins = append(ins, &TSOInstance{ BaseInstance: BaseInstance{ InstanceSpec: s, - Name: c.Name(), + Name: s.Name, Host: s.Host, ManageHost: s.ManageHost, ListenHost: utils.Ternary(s.ListenHost != "", s.ListenHost, c.Topology.BaseTopo().GlobalOptions.ListenHost).(string), @@ -229,6 +231,7 @@ func (i *TSOInstance) InitConfig( pds = append(pds, pdspec.GetAdvertiseClientURL(enableTLS)) } cfg := &scripts.TSOScript{ + Name: spec.Name, ListenURL: fmt.Sprintf("%s://%s", scheme, utils.JoinHostPort(i.GetListenHost(), spec.Port)), AdvertiseListenURL: spec.GetAdvertiseListenURL(enableTLS), BackendEndpoints: strings.Join(pds, ","), diff --git a/pkg/cluster/spec/validate.go b/pkg/cluster/spec/validate.go index 99384cbec7..ce73682c01 100644 --- a/pkg/cluster/spec/validate.go +++ b/pkg/cluster/spec/validate.go @@ -984,6 +984,38 @@ func (s *Specification) validatePDNames() error { return nil } +func (s *Specification) validateTSONames() error { + // check tso server name + tsoNames := set.NewStringSet() + for _, tso := range s.TSOServers { + if tso.Name == "" { + continue + } + + if tsoNames.Exist(tso.Name) { + return errors.Errorf("component tso_servers.name is not supported duplicated, the name %s is duplicated", tso.Name) + } + tsoNames.Insert(tso.Name) + } + return nil +} + +func (s *Specification) validateSchedulingNames() error { + // check scheduling server name + schedulingNames := set.NewStringSet() + for _, scheduling := range s.SchedulingServers { + if scheduling.Name == "" { + continue + } + + if schedulingNames.Exist(scheduling.Name) { + return errors.Errorf("component scheduling_servers.name is not supported duplicated, the name %s is duplicated", scheduling.Name) + } + schedulingNames.Insert(scheduling.Name) + } + return nil +} + func (s *Specification) validateTiFlashConfigs() error { c := FindComponent(s, ComponentTiFlash) for _, ins := range c.Instances() { @@ -1063,6 +1095,8 @@ func (s *Specification) Validate() error { s.dirConflictsDetect, s.validateUserGroup, s.validatePDNames, + s.validateTSONames, + s.validateSchedulingNames, s.validateTiSparkSpec, s.validateTiFlashConfigs, s.validateMonitorAgent, diff --git a/pkg/cluster/template/scripts/scheduling.go b/pkg/cluster/template/scripts/scheduling.go index 6167d9336e..7c3dca84e8 100644 --- a/pkg/cluster/template/scripts/scheduling.go +++ b/pkg/cluster/template/scripts/scheduling.go @@ -18,12 +18,14 @@ import ( "path" "text/template" + "github.com/pingcap/errors" "github.com/pingcap/tiup/embed" "github.com/pingcap/tiup/pkg/utils" ) // SchedulingScript represent the data to generate scheduling config type SchedulingScript struct { + Name string ListenURL string AdvertiseListenURL string BackendEndpoints string @@ -48,6 +50,10 @@ func (c *SchedulingScript) ConfigToFile(file string) error { return err } + if c.Name == "" { + return errors.New("empty name") + } + content := bytes.NewBufferString("") if err := tmpl.Execute(content, c); err != nil { return err diff --git a/pkg/cluster/template/scripts/tso.go b/pkg/cluster/template/scripts/tso.go index 0197b82c38..59fd74c41f 100644 --- a/pkg/cluster/template/scripts/tso.go +++ b/pkg/cluster/template/scripts/tso.go @@ -18,12 +18,14 @@ import ( "path" "text/template" + "github.com/pingcap/errors" "github.com/pingcap/tiup/embed" "github.com/pingcap/tiup/pkg/utils" ) // TSOScript represent the data to generate tso config type TSOScript struct { + Name string ListenURL string AdvertiseListenURL string BackendEndpoints string @@ -48,6 +50,10 @@ func (c *TSOScript) ConfigToFile(file string) error { return err } + if c.Name == "" { + return errors.New("empty name") + } + content := bytes.NewBufferString("") if err := tmpl.Execute(content, c); err != nil { return err