!574 A-Tune识别应用场景及动态推荐调优参数的实现-修改分类识别go客户端和服务端代码

From: @SWWBF 
Reviewed-by: @gaoruoshu 
Signed-off-by: @gaoruoshu
This commit is contained in:
openeuler-ci-bot
2023-10-21 02:21:15 +00:00
committed by Gitee
4 changed files with 102 additions and 25 deletions

View File

@@ -183,9 +183,10 @@ type AnalysisMessage struct {
Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
Model string `protobuf:"bytes,2,opt,name=Model,proto3" json:"Model,omitempty"`
Characterization bool `protobuf:"varint,3,opt,name=Characterization,proto3" json:"Characterization,omitempty"`
Times string `protobuf:"bytes,4,opt,name=Time,proto3" json:"Time,omitempty"`
Flag string `protobuf:"bytes,5,opt,name=Flag,proto3" json:"Flag,omitempty"`
Id string `protobuf:"bytes,6,opt,name=Id,proto3" json:"Id,omitempty"`
Bottleneck bool `protobuf:"varint,4,opt,name=Bottleneck,proto3" json:"Bottleneck,omitempty"`
Times string `protobuf:"bytes,5,opt,name=Time,proto3" json:"Time,omitempty"`
Flag string `protobuf:"bytes,6,opt,name=Flag,proto3" json:"Flag,omitempty"`
Id string `protobuf:"bytes,7,opt,name=Id,proto3" json:"Id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -237,6 +238,13 @@ func (m *AnalysisMessage) GetCharacterization() bool {
return false
}
func (m *AnalysisMessage) GetBottleneck() bool {
if m != nil {
return m.Bottleneck
}
return false
}
func (m *AnalysisMessage) GetTime() string {
if m != nil {
return m.Times

View File

@@ -51,9 +51,10 @@ message AnalysisMessage {
string Name = 1;
string Model = 2;
bool Characterization = 3;
string Times = 4 ;
string Flag = 5;
string Id = 6;
bool Bottleneck = 4;
string Times = 5;
string Flag = 6;
string Id = 7;
}
message Ack {

View File

@@ -44,6 +44,10 @@ var profileAnalysisCommand = cli.Command{
Name: "characterization, c",
Usage: "only analysis the workload type",
},
cli.BoolFlag{
Name: "bottleneck, b",
Usage: "identify and tune system bottlenecks",
},
cli.StringFlag{
Name: "times, t",
Usage: "specify the collection times",
@@ -65,7 +69,9 @@ var profileAnalysisCommand = cli.Command{
example: atune-adm analysis --model ./self_trained.m
you can only analysis the workload type.
example: atune-adm analysis --characterization
you can specify the collecting times.
you can identify and tune system bottlenecks.
example: atune-adm analysis --bottleneck
you can specify the collecting times.
example: atune-adm analysis -t 5
you can specify the script to be executed.
example: atune-adm analysis -s script.sh`
@@ -132,7 +138,7 @@ func profileAnalysis(ctx *cli.Context) error {
flag = "start"
}
stream, _ := svc.Analysis(CTX.Background(), &PB.AnalysisMessage{Name: appname, Model: modelFile,
Characterization: ctx.Bool("characterization"), Times: times, Flag: flag, Id:id})
Characterization: ctx.Bool("characterization"), Bottleneck: ctx.Bool("bottleneck"), Times: times, Flag: flag, Id:id})
endCollect := false
for {
@@ -150,7 +156,7 @@ func profileAnalysis(ctx *cli.Context) error {
svcend := PB.NewProfileMgrClient(c.Connection())
endCollect = true
_, _ = svcend.Analysis(CTX.Background(), &PB.AnalysisMessage{Name: appname, Model: modelFile,
Characterization: ctx.Bool("characterization"), Times: times, Flag: "end", Id:id})
Characterization: ctx.Bool("characterization"), Bottleneck: ctx.Bool("bottleneck"), Times: times, Flag: "end", Id:id})
}
}

View File

@@ -84,6 +84,7 @@ type ClassifyPostBody struct {
// RespClassify : the response of classify model
type RespClassify struct {
Bottleneck int `json:"bottleneck_binary"`
ResourceLimit string `json:"resource_limit"`
WorkloadType string `json:"workload_type"`
Percentage float32 `json:"percentage"`
@@ -518,7 +519,7 @@ func (s *ProfileServer) Analysis(message *PB.AnalysisMessage, stream PB.ProfileM
subProcess = false
workloadType, resourceLimit, err := s.classify(respCollectPost.Path, message.GetModel())
bottleneck, workloadType, resourceLimit, err := s.classify(respCollectPost.Path, message.GetModel())
if err != nil {
_ = stream.Send(&PB.AckCheck{Name: err.Error()})
return err
@@ -575,13 +576,42 @@ func (s *ProfileServer) Analysis(message *PB.AnalysisMessage, stream PB.ProfileM
log.Infof("workload %s support app: %s", workloadType, apps)
log.Infof("workload %s resource limit: %s, cluster result resource limit: %s",
workloadType, apps, resourceLimit)
workloadType, apps, resourceLimit)
var step int = 3
cpuExist := bottleneck&16 > 0
memExist := bottleneck&8 > 0
netQualityExist := bottleneck&4 > 0
netIOExist := bottleneck&2 > 0
diskIOExist := bottleneck&1 > 0
if message.Bottleneck {
if bottleneck == 0 {
_ = stream.Send(&PB.AckCheck{Name: fmt.Sprintf("\n %d. Current System does not detected the five bottlenecks of Computing, Memory, Network, Network I/O and disk I/O", step)})
log.Infof("Current System does not detected the five bottlenecks of Computing, Memory, Network, Network I/O and disk I/O")
} else {
bottleneckTypes := []string{"Computing", "Memory", "Network", "Network I/O", "disk I/O"}
bottlenecks := []string{}
boolValues := []bool{cpuExist, memExist, netQualityExist, netIOExist, diskIOExist}
for i, exist := range boolValues {
if exist {
bottlenecks = append(bottlenecks, bottleneckTypes[i])
}
}
bottlenecksStr := strings.Join(bottlenecks, ", ")
_ = stream.Send(&PB.AckCheck{Name: fmt.Sprintf("\n %d. Current System bottlenecks: %s", step, bottlenecksStr)})
log.Infof("Current System bottlenecks: %s", bottlenecksStr)
}
step++
}
if message.Characterization {
return nil
}
_ = stream.Send(&PB.AckCheck{Name: "\n 3. Build the best resource model..."})
_ = stream.Send(&PB.AckCheck{Name: fmt.Sprintf("\n %d. Build the best resource model...", step)})
step++
//5. get the profile type depend on the workload type
profileType := classProfile.Result[0].ProfileType
@@ -591,14 +621,43 @@ func (s *ProfileServer) Analysis(message *PB.AnalysisMessage, stream PB.ProfileM
return fmt.Errorf("no profile or invalid profiles were specified")
}
if message.Bottleneck {
bottleneck_profiles := []struct {
bottleneck bool
profile string
}{
{cpuExist, "include-compute-intensive"},
{memExist, "include-memory-intensive"},
{netQualityExist, "include-network-intensive"},
{netIOExist, "include-network-intensive"},
{diskIOExist, "include-io-intensive"},
}
for _, c := range bottleneck_profiles {
if c.bottleneck {
exists := false
for _, existingProfile := range profileNames {
if existingProfile == c.profile {
exists = true
break
}
}
if !exists {
profileNames = append(profileNames, c.profile)
}
}
}
}
//6. get the profile info depend on the profile type
log.Infof("the resource model of the profile type is %s", profileType)
_ = stream.Send(&PB.AckCheck{Name: fmt.Sprintf("\n 4. Match profile: %s", profileType)})
log.Infof("the resource model of the profile type is %s", strings.Join(profileNames, ", "))
_ = stream.Send(&PB.AckCheck{Name: fmt.Sprintf("\n %d. Match profile: %s", step, strings.Join(profileNames, ", "))})
step++
pro, _ := profile.Load(profileNames)
pro.SetWorkloadType(workloadType)
pro.SetCollectionId(collectionId)
_ = stream.Send(&PB.AckCheck{Name: "\n 5. begin to set static profile"})
_ = stream.Send(&PB.AckCheck{Name: fmt.Sprintf("\n %d. begin to set static profile", step)})
step++
log.Infof("begin to set static profile")
//static profile setting
@@ -633,7 +692,8 @@ func (s *ProfileServer) Analysis(message *PB.AnalysisMessage, stream PB.ProfileM
}
log.Info("begin to dynamic tuning depending on rules")
_ = stream.Send(&PB.AckCheck{Name: "\n 6. begin to set dynamic profile"})
_ = stream.Send(&PB.AckCheck{Name: fmt.Sprintf("\n %d. begin to set dynamic profile", step)})
step++
if err := tuning.RuleTuned(workloadType); err != nil {
return err
}
@@ -1431,14 +1491,15 @@ func (s *ProfileServer) collection(npipe string, time string) (*RespCollectorPos
return respCollectPost, nil
}
func (s *ProfileServer) classify(dataPath string, customeModel string) (string, string, error) {
func (s *ProfileServer) classify(dataPath string, customeModel string) (int, string, string, error) {
//2. send the collected data to the model for completion type identification
var resourceLimit string
var workloadType string
var bottleneck int
localPath, timestamp, err := utils.ChangeFileName(dataPath)
if err != nil {
log.Errorf("Failed to change file name: %v", localPath)
return workloadType, resourceLimit, err
return bottleneck, workloadType, resourceLimit, err
}
defer os.Remove(localPath)
@@ -1448,13 +1509,13 @@ func (s *ProfileServer) classify(dataPath string, customeModel string) (string,
_, err = os.OpenFile(logPath, os.O_WRONLY|os.O_CREATE, 0640)
if err != nil {
log.Errorf("Failed to create log file: %v", err)
return workloadType, resourceLimit, err
return bottleneck, workloadType, resourceLimit, err
}
dataPath, err = Post("classification", "file", localPath)
if err != nil {
log.Errorf("Failed transfer file to server: %v", err)
return workloadType, resourceLimit, err
return bottleneck, workloadType, resourceLimit, err
}
body := new(ClassifyPostBody)
@@ -1466,14 +1527,15 @@ func (s *ProfileServer) classify(dataPath string, customeModel string) (string,
}
respPostIns, err := body.Post()
if err != nil {
return workloadType, resourceLimit, err
return bottleneck, workloadType, resourceLimit, err
}
log.Infof("workload: %s, cluster result resource limit: %s",
respPostIns.WorkloadType, respPostIns.ResourceLimit)
resourceLimit = respPostIns.ResourceLimit
workloadType = respPostIns.WorkloadType
return workloadType, resourceLimit, nil
bottleneck = respPostIns.Bottleneck
return bottleneck, workloadType, resourceLimit, nil
}
func (s *ProfileServer) Getworkload() (string, error) {
@@ -1484,7 +1546,7 @@ func (s *ProfileServer) Getworkload() (string, error) {
return "", err
}
workload, _, err := s.classify(respCollectPost.Path, customeModel)
_, workload, _, err := s.classify(respCollectPost.Path, customeModel)
if err != nil {
return "", err
}