1 Star 0 Fork 0

liucxer / ceph-tools

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
exec_config.go 7.84 KB
一键复制 编辑 原始数据 按行查看 历史
刘昌喜 提交于 2023-05-25 17:08 . feat: 🎸 裸盘测试bug修复
package bare_disk
import (
"encoding/json"
"errors"
"fmt"
cmd "gitee.com/liucxer/ceph-tools/pkg/cmd_mgr"
"gitee.com/liucxer/ceph-tools/pkg/csv"
"gitee.com/liucxer/ceph-tools/pkg/fio"
"github.com/google/uuid"
"github.com/sirupsen/logrus"
"io/ioutil"
"os"
"strconv"
"strings"
"sync"
)
func NewExecConfig(configPath string) (*ExecConfig, error) {
execConfig := ExecConfig{}
err := execConfig.ReadConfig(configPath)
if err != nil {
return &execConfig, nil
}
resultDir := "output_" + uuid.New().String()
err = os.Mkdir(resultDir, os.ModePerm)
if err != nil {
return &execConfig, err
}
execConfig.ResultDir = resultDir
logrus.Debugf("NewExecConfig. execConfig:%+v", execConfig)
return &execConfig, nil
}
type numJobsItem struct {
NumJobs int64 `json:"numJobs"`
IoDepth []int64 `json:"ioDepth"`
}
type blockSizeItem struct {
BlockSize string `json:"blockSize"`
NumJobsItem []numJobsItem `json:"numJobsItem"`
}
type ioTypeItem struct {
IOType string `json:"ioType"`
BlockSizeItem []blockSizeItem `json:"blockSizeItem"`
}
type DirectItem struct {
Direct int64 `json:"direct"`
IOTypeItem []ioTypeItem `json:"ioTypeItem"`
}
type ExecConfig struct {
DirectItem []DirectItem `json:"directItem"`
Disk []string `json:"disk"`
Runtime int64 `json:"runtime"`
TestCount int64 `json:"testCount"`
ResultDir string `json:"resultDir"`
}
func (execConfig *ExecConfig) ReadConfig(configFilePath string) error {
bts, err := ioutil.ReadFile(configFilePath)
if err != nil {
logrus.Errorf("ioutil.ReadFile err:%v", err)
return err
}
err = json.Unmarshal(bts, execConfig)
if err != nil {
logrus.Errorf("json.Unmarshal err:%v", err)
return err
}
return err
}
type fioOpItem struct {
BW float64 `json:"bw"`
Iops float64 `json:"iops"`
SlatNS struct {
Min float64 `json:"min"`
Max float64 `json:"max"`
Mean float64 `json:"mean"`
StdDev float64 `json:"stddev"`
} `json:"slat_ns"`
ClatNS struct {
Min float64 `json:"min"`
Max float64 `json:"max"`
Mean float64 `json:"mean"`
StdDev float64 `json:"stddev"`
Percentile struct {
Key95 float64 `json:"95.000000"`
Key99 float64 `json:"99.000000"`
} `json:"percentile"`
} `json:"clat_ns"`
LatNS struct {
Min float64 `json:"min"`
Max float64 `json:"max"`
Mean float64 `json:"mean"`
StdDev float64 `json:"stddev"`
} `json:"lat_ns"`
}
type fioResp struct {
Jobs []struct {
Jobname string `json:"jobname"`
Read fioOpItem `json:"read"`
Write fioOpItem `json:"write"`
} `json:"jobs"`
}
type JobConfig struct {
DiskName string `json:"diskName"`
Count int64 `json:"count"`
}
type DiskInfo struct {
UserCapacity string `json:"userCapacity"`
RotationRate string `json:"rotationRate"`
}
type JobResult struct {
JobConfig JobConfig `json:"jobConfig"`
DiskInfo DiskInfo `json:"diskInfo"`
JobItem JobItem `json:"jobItem"`
FioResult fio.FioResult `json:"fioResult"`
}
type JobItem struct {
Disk string `json:"disk"`
BlockSize string `json:"blockSize"`
Direct int64 `json:"direct"`
IOType string `json:"ioType"`
Numjob int64 `json:"numjobs"`
Iodepth int64 `json:"iodepth"`
}
func (execConfig *ExecConfig) RunOneJob(item JobItem) (JobResult, error) {
var (
err error
res JobResult
fioResult fio.FioResult
)
cmdMgr := cmd.NewCmdMgr()
fioStr := "fio --ioengine=libaio " +
" --direct=" + strconv.Itoa(int(item.Direct)) +
" --bs=" + item.BlockSize + " " +
" --rw=" + item.IOType +
" --runtime=" + strconv.Itoa(int(execConfig.Runtime)) +
" --numjobs=" + strconv.Itoa(int(item.Numjob)) +
" --iodepth=" + strconv.Itoa(int(item.Iodepth)) +
" --filename=" + "/dev/" + item.Disk +
" --thread --time_based " +
" --group_reporting " +
" --name=fioJob " +
" --output-format=json"
status, err := cmdMgr.SyncExecute(fioStr)
if err != nil {
return res, err
}
fioRes := fioResp{}
err = json.Unmarshal([]byte(status.Stdout), &fioRes)
if err != nil {
return res, err
}
for _, item := range fioRes.Jobs {
if item.Jobname != "fioJob" {
continue
}
fioResult.WriteIops, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", item.Write.Iops), 64)
fioResult.WriteBandwidth = item.Write.BW
fioResult.WriteSlat = item.Write.SlatNS.Mean / float64(1000000)
fioResult.WriteClat = item.Write.ClatNS.Mean / float64(1000000)
fioResult.WriteLat = item.Write.LatNS.Mean / float64(1000000)
fioResult.WriteClat95, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", item.Write.ClatNS.Percentile.Key95/float64(1000000)), 64)
fioResult.WriteClat99, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", item.Write.ClatNS.Percentile.Key99/float64(1000000)), 64)
fioResult.ReadIops, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", item.Read.Iops), 64)
fioResult.ReadBandwidth = item.Read.BW
fioResult.ReadSlat = item.Read.SlatNS.Mean / float64(1000000)
fioResult.ReadClat = item.Read.LatNS.Mean / float64(1000000)
fioResult.ReadLat = item.Read.LatNS.Mean / float64(1000000)
fioResult.ReadClat95, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", item.Read.ClatNS.Percentile.Key95/float64(1000000)), 64)
fioResult.ReadClat99, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", item.Read.ClatNS.Percentile.Key99/float64(1000000)), 64)
}
res.FioResult = fioResult
return res, err
}
func (execConfig *ExecConfig) RunOneDisk(jobItem JobItem) ([]JobResult, error) {
var (
err error
fioResultList []JobResult
)
if jobItem.Disk == "" {
return nil, errors.New("item.Disk == \"\"")
}
cmdMgr := cmd.NewCmdMgr()
diskInfo := DiskInfo{}
status, err := cmdMgr.SyncExecute("smartctl -a /dev/" + jobItem.Disk + " |grep \"User Capacity\" |awk -F\"[\" '{print $2}' |awk -F\"]\" '{print $1}'")
if err != nil {
return nil, err
}
diskInfo.UserCapacity = strings.Trim(status.Stdout, " ")
diskInfo.UserCapacity = strings.Trim(diskInfo.UserCapacity, "\n")
status, err = cmdMgr.SyncExecute("smartctl -a /dev/" + jobItem.Disk + " |grep \"Rotation Rate\" |awk -F\":\" '{print $2}'")
if err != nil {
return nil, err
}
diskInfo.RotationRate = strings.Trim(status.Stdout, " ")
diskInfo.RotationRate = strings.Trim(diskInfo.RotationRate, "\n")
for i := 0; i < int(execConfig.TestCount); i++ {
jobConfig := JobConfig{
DiskName: jobItem.Disk,
Count: int64(i),
}
item, err := execConfig.RunOneJob(jobItem)
if err != nil {
continue
}
item.DiskInfo = diskInfo
item.JobConfig = jobConfig
name, value, err := csv.ObjectToCsv(item)
if err != nil {
continue
}
item.JobItem = jobItem
logrus.Infof("RunOneJob res:%+v", item)
logrus.Infof("RunOneJob name:%s", name)
logrus.Infof("RunOneJob value:%s", value)
fioResultList = append(fioResultList, item)
}
return fioResultList, nil
}
func (execConfig *ExecConfig) Run() (*[]JobResult, error) {
var (
err error
fioResultList []JobResult
)
for _, directItem := range execConfig.DirectItem {
for _, ioTypeItem := range directItem.IOTypeItem {
for _, blockSizeItem := range ioTypeItem.BlockSizeItem {
for _, numJobsItem := range blockSizeItem.NumJobsItem {
for _, iodepth := range numJobsItem.IoDepth {
var vg sync.WaitGroup
for _, disk := range execConfig.Disk {
var item JobItem
item.Direct = directItem.Direct
item.IOType = ioTypeItem.IOType
item.Iodepth = iodepth
item.BlockSize = blockSizeItem.BlockSize
item.Numjob = numJobsItem.NumJobs
item.Iodepth = iodepth
item.Disk = disk
vg.Add(1)
go func(jobItem JobItem) {
defer vg.Done()
logrus.Infof("jobItem:%+v", jobItem)
fioResultListSub, err := execConfig.RunOneDisk(jobItem)
if err != nil {
logrus.Errorf("execConfig.RunOneDisk err:%v", err)
return
}
fioResultList = append(fioResultList, fioResultListSub...)
}(item)
}
vg.Wait()
}
}
}
}
}
return &fioResultList, err
}
1
https://gitee.com/liucxer/ceph-tools.git
git@gitee.com:liucxer/ceph-tools.git
liucxer
ceph-tools
ceph-tools
db53517fcc53

搜索帮助