mirror of
https://github.com/minio/minio.git
synced 2025-12-08 16:53:11 -05:00
Add ability to test drive speeds on a MinIO setup (#7664)
- Extends existing Admin API to measure disk performance
This commit is contained in:
committed by
kannappanr
parent
e7b3f39064
commit
6ba323b009
@@ -45,7 +45,6 @@ import (
|
||||
xhttp "github.com/minio/minio/cmd/http"
|
||||
"github.com/minio/minio/cmd/logger"
|
||||
"github.com/minio/minio/pkg/cpu"
|
||||
"github.com/minio/minio/pkg/disk"
|
||||
"github.com/minio/minio/pkg/handlers"
|
||||
iampolicy "github.com/minio/minio/pkg/iam/policy"
|
||||
"github.com/minio/minio/pkg/madmin"
|
||||
@@ -318,15 +317,6 @@ func (a adminAPIHandlers) ServerInfoHandler(w http.ResponseWriter, r *http.Reque
|
||||
writeSuccessResponseJSON(w, jsonBytes)
|
||||
}
|
||||
|
||||
// ServerDrivesPerfInfo holds information about address, performance
|
||||
// of all drives on one server. It also reports any errors if encountered
|
||||
// while trying to reach this server.
|
||||
type ServerDrivesPerfInfo struct {
|
||||
Addr string `json:"addr"`
|
||||
Error string `json:"error,omitempty"`
|
||||
Perf []disk.Performance `json:"perf"`
|
||||
}
|
||||
|
||||
// ServerCPULoadInfo holds informantion about cpu utilization
|
||||
// of one minio node. It also reports any errors if encountered
|
||||
// while trying to reach this server.
|
||||
@@ -406,16 +396,25 @@ func (a adminAPIHandlers) PerfInfoHandler(w http.ResponseWriter, r *http.Request
|
||||
writeSuccessResponseJSON(w, jsonBytes)
|
||||
|
||||
case "drive":
|
||||
info := objectAPI.StorageInfo(ctx)
|
||||
if !(info.Backend.Type == BackendFS || info.Backend.Type == BackendErasure) {
|
||||
// Drive Perf is only implemented for Erasure coded backends
|
||||
if !globalIsXL {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL)
|
||||
return
|
||||
}
|
||||
|
||||
var size int64 = madmin.DefaultDrivePerfSize
|
||||
if sizeStr, found := vars["size"]; found {
|
||||
var err error
|
||||
if size, err = strconv.ParseInt(sizeStr, 10, 64); err != nil || size <= 0 {
|
||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrBadRequest), r.URL)
|
||||
return
|
||||
}
|
||||
}
|
||||
// Get drive performance details from local server's drive(s)
|
||||
dp := getLocalDrivesPerf(globalEndpoints, r)
|
||||
dp := getLocalDrivesPerf(globalEndpoints, size, r)
|
||||
|
||||
// Notify all other MinIO peers to report drive performance numbers
|
||||
dps := globalNotificationSys.DrivePerfInfo()
|
||||
dps := globalNotificationSys.DrivePerfInfo(size)
|
||||
dps = append(dps, dp)
|
||||
|
||||
// Marshal API response
|
||||
|
||||
@@ -64,7 +64,7 @@ func registerAdminRouter(router *mux.Router, enableConfigOps, enableIAMOps bool)
|
||||
|
||||
}
|
||||
// Performance command - return performance details based on input type
|
||||
adminV1Router.Methods(http.MethodGet).Path("/performance").HandlerFunc(httpTraceAll(adminAPI.PerfInfoHandler)).Queries("perfType", "{perfType:.*}")
|
||||
adminV1Router.Methods(http.MethodGet).Path("/performance").HandlerFunc(httpTraceAll(adminAPI.PerfInfoHandler)).Queries("perfType", "{perfType:.*}").Queries("size", "{size:.*}")
|
||||
|
||||
// Profiling operations
|
||||
adminV1Router.Methods(http.MethodPost).Path("/profiling/start").HandlerFunc(httpTraceAll(adminAPI.StartProfilingHandler)).
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/minio/minio-go/pkg/set"
|
||||
"github.com/minio/minio/pkg/cpu"
|
||||
"github.com/minio/minio/pkg/disk"
|
||||
"github.com/minio/minio/pkg/madmin"
|
||||
"github.com/minio/minio/pkg/mem"
|
||||
)
|
||||
|
||||
@@ -86,7 +87,7 @@ func getLocalCPULoad(endpoints EndpointList, r *http.Request) ServerCPULoadInfo
|
||||
|
||||
// getLocalDrivesPerf - returns ServerDrivesPerfInfo for only the
|
||||
// local endpoints from given list of endpoints
|
||||
func getLocalDrivesPerf(endpoints EndpointList, r *http.Request) ServerDrivesPerfInfo {
|
||||
func getLocalDrivesPerf(endpoints EndpointList, size int64, r *http.Request) madmin.ServerDrivesPerfInfo {
|
||||
var dps []disk.Performance
|
||||
for _, endpoint := range endpoints {
|
||||
// Only proceed for local endpoints
|
||||
@@ -96,7 +97,7 @@ func getLocalDrivesPerf(endpoints EndpointList, r *http.Request) ServerDrivesPer
|
||||
dps = append(dps, disk.Performance{Path: endpoint.Path, Error: err.Error()})
|
||||
continue
|
||||
}
|
||||
dp := disk.GetPerformance(pathJoin(endpoint.Path, minioMetaTmpBucket, mustGetUUID()))
|
||||
dp := disk.GetPerformance(pathJoin(endpoint.Path, minioMetaTmpBucket, mustGetUUID()), size)
|
||||
dp.Path = endpoint.Path
|
||||
dps = append(dps, dp)
|
||||
}
|
||||
@@ -105,7 +106,7 @@ func getLocalDrivesPerf(endpoints EndpointList, r *http.Request) ServerDrivesPer
|
||||
if globalIsDistXL {
|
||||
addr = GetLocalPeer(endpoints)
|
||||
}
|
||||
return ServerDrivesPerfInfo{
|
||||
return madmin.ServerDrivesPerfInfo{
|
||||
Addr: addr,
|
||||
Perf: dps,
|
||||
}
|
||||
|
||||
@@ -977,8 +977,8 @@ func (sys *NotificationSys) CollectNetPerfInfo(size int64) map[string][]ServerNe
|
||||
}
|
||||
|
||||
// DrivePerfInfo - Drive speed (read and write) information
|
||||
func (sys *NotificationSys) DrivePerfInfo() []ServerDrivesPerfInfo {
|
||||
reply := make([]ServerDrivesPerfInfo, len(sys.peerClients))
|
||||
func (sys *NotificationSys) DrivePerfInfo(size int64) []madmin.ServerDrivesPerfInfo {
|
||||
reply := make([]madmin.ServerDrivesPerfInfo, len(sys.peerClients))
|
||||
var wg sync.WaitGroup
|
||||
for i, client := range sys.peerClients {
|
||||
if client == nil {
|
||||
@@ -987,7 +987,7 @@ func (sys *NotificationSys) DrivePerfInfo() []ServerDrivesPerfInfo {
|
||||
wg.Add(1)
|
||||
go func(client *peerRESTClient, idx int) {
|
||||
defer wg.Done()
|
||||
di, err := client.DrivePerfInfo()
|
||||
di, err := client.DrivePerfInfo(size)
|
||||
if err != nil {
|
||||
reqInfo := (&logger.ReqInfo{}).AppendTags("remotePeer", client.host.String())
|
||||
ctx := logger.SetReqInfo(context.Background(), reqInfo)
|
||||
|
||||
@@ -173,8 +173,10 @@ func (client *peerRESTClient) CPULoadInfo() (info ServerCPULoadInfo, err error)
|
||||
}
|
||||
|
||||
// DrivePerfInfo - fetch Drive performance information for a remote node.
|
||||
func (client *peerRESTClient) DrivePerfInfo() (info ServerDrivesPerfInfo, err error) {
|
||||
respBody, err := client.call(peerRESTMethodDrivePerfInfo, nil, nil, -1)
|
||||
func (client *peerRESTClient) DrivePerfInfo(size int64) (info madmin.ServerDrivesPerfInfo, err error) {
|
||||
params := make(url.Values)
|
||||
params.Set(peerRESTDrivePerfSize, strconv.FormatInt(size, 10))
|
||||
respBody, err := client.call(peerRESTMethodDrivePerfInfo, params, nil, -1)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ const (
|
||||
|
||||
const (
|
||||
peerRESTNetPerfSize = "netperfsize"
|
||||
peerRESTDrivePerfSize = "driveperfsize"
|
||||
peerRESTBucket = "bucket"
|
||||
peerRESTUser = "user"
|
||||
peerRESTGroup = "group"
|
||||
|
||||
@@ -431,8 +431,23 @@ func (s *peerRESTServer) DrivePerfInfoHandler(w http.ResponseWriter, r *http.Req
|
||||
return
|
||||
}
|
||||
|
||||
params := mux.Vars(r)
|
||||
|
||||
sizeStr, found := params[peerRESTDrivePerfSize]
|
||||
if !found {
|
||||
s.writeErrorResponse(w, errors.New("size is missing"))
|
||||
return
|
||||
}
|
||||
|
||||
size, err := strconv.ParseInt(sizeStr, 10, 64)
|
||||
if err != nil || size < 0 {
|
||||
s.writeErrorResponse(w, errInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
ctx := newContext(r, w, "DrivePerfInfo")
|
||||
info := getLocalDrivesPerf(globalEndpoints, r)
|
||||
|
||||
info := getLocalDrivesPerf(globalEndpoints, size, r)
|
||||
|
||||
defer w.(http.Flusher).Flush()
|
||||
logger.LogIf(ctx, gob.NewEncoder(w).Encode(info))
|
||||
@@ -960,7 +975,7 @@ func registerPeerRESTHandlers(router *mux.Router) {
|
||||
subrouter.Methods(http.MethodPost).Path(SlashSeparator + peerRESTMethodServerInfo).HandlerFunc(httpTraceHdrs(server.ServerInfoHandler))
|
||||
subrouter.Methods(http.MethodPost).Path(SlashSeparator + peerRESTMethodCPULoadInfo).HandlerFunc(httpTraceHdrs(server.CPULoadInfoHandler))
|
||||
subrouter.Methods(http.MethodPost).Path(SlashSeparator + peerRESTMethodMemUsageInfo).HandlerFunc(httpTraceHdrs(server.MemUsageInfoHandler))
|
||||
subrouter.Methods(http.MethodPost).Path(SlashSeparator + peerRESTMethodDrivePerfInfo).HandlerFunc(httpTraceHdrs(server.DrivePerfInfoHandler))
|
||||
subrouter.Methods(http.MethodPost).Path(SlashSeparator + peerRESTMethodDrivePerfInfo).HandlerFunc(httpTraceHdrs(server.DrivePerfInfoHandler)).Queries(restQueries(peerRESTDrivePerfSize)...)
|
||||
subrouter.Methods(http.MethodPost).Path(SlashSeparator + peerRESTMethodDeleteBucket).HandlerFunc(httpTraceHdrs(server.DeleteBucketHandler)).Queries(restQueries(peerRESTBucket)...)
|
||||
subrouter.Methods(http.MethodPost).Path(SlashSeparator + peerRESTMethodSignalService).HandlerFunc(httpTraceHdrs(server.SignalServiceHandler)).Queries(restQueries(peerRESTSignal)...)
|
||||
subrouter.Methods(http.MethodPost).Path(SlashSeparator + peerRESTMethodServerUpdate).HandlerFunc(httpTraceHdrs(server.ServerUpdateHandler)).Queries(restQueries(peerRESTUpdateURL, peerRESTSha256Hex, peerRESTLatestRelease)...)
|
||||
|
||||
Reference in New Issue
Block a user