2021-04-19 03:13:52 +00:00
|
|
|
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
|
|
|
|
// with the License. You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
|
|
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
|
|
// or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
|
|
|
2021-04-08 06:14:43 +00:00
|
|
|
package miniokv
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
2021-04-22 06:45:57 +00:00
|
|
|
"github.com/milvus-io/milvus/internal/log"
|
2021-04-08 06:14:43 +00:00
|
|
|
"github.com/minio/minio-go/v7"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
)
|
|
|
|
|
|
|
|
type MinioStatsWatcher struct {
|
|
|
|
mu sync.RWMutex
|
|
|
|
client *minio.Client
|
|
|
|
objCreateSize int64
|
|
|
|
startTime time.Time
|
|
|
|
bucketName string
|
|
|
|
helper MinioStatsWatcherHelper
|
|
|
|
}
|
|
|
|
|
|
|
|
type MinioStatsWatcherHelper struct {
|
|
|
|
eventAfterStartWatch func()
|
|
|
|
eventAfterNotify func()
|
|
|
|
}
|
|
|
|
|
|
|
|
func defaultStatsHelper() MinioStatsWatcherHelper {
|
|
|
|
return MinioStatsWatcherHelper{
|
|
|
|
eventAfterStartWatch: func() {},
|
|
|
|
eventAfterNotify: func() {},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewMinioStatsWatcher(client *minio.Client, bucketName string) *MinioStatsWatcher {
|
|
|
|
return &MinioStatsWatcher{
|
|
|
|
client: client,
|
|
|
|
bucketName: bucketName,
|
|
|
|
helper: defaultStatsHelper(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewMinioStatsWatcherWithHelper(client *minio.Client, bucketName string, helper MinioStatsWatcherHelper) *MinioStatsWatcher {
|
|
|
|
stats := NewMinioStatsWatcher(client, bucketName)
|
|
|
|
stats.helper = helper
|
|
|
|
return stats
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *MinioStatsWatcher) StartBackground(ctx context.Context) {
|
|
|
|
s.mu.Lock()
|
|
|
|
s.startTime = time.Now()
|
|
|
|
s.mu.Unlock()
|
|
|
|
ch := s.client.ListenBucketNotification(ctx, s.bucketName, "", "", []string{"s3:ObjectCreated:*"})
|
|
|
|
|
|
|
|
s.helper.eventAfterStartWatch()
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-ctx.Done():
|
|
|
|
log.Debug("minio stats shutdown")
|
|
|
|
return
|
|
|
|
case info := <-ch:
|
|
|
|
if info.Err != nil {
|
|
|
|
log.Error("minio receive wrong notification", zap.Error(info.Err))
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
var size int64
|
|
|
|
for _, record := range info.Records {
|
|
|
|
size += record.S3.Object.Size
|
|
|
|
}
|
|
|
|
s.mu.Lock()
|
|
|
|
s.objCreateSize += size
|
|
|
|
s.mu.Unlock()
|
|
|
|
s.helper.eventAfterNotify()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *MinioStatsWatcher) GetObjectCreateSize() int64 {
|
|
|
|
s.mu.RLock()
|
|
|
|
defer s.mu.RUnlock()
|
|
|
|
return s.objCreateSize
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *MinioStatsWatcher) GetStartTime() time.Time {
|
|
|
|
s.mu.RLock()
|
|
|
|
defer s.mu.RUnlock()
|
|
|
|
return s.startTime
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *MinioStatsWatcher) String() string {
|
|
|
|
s.mu.RLock()
|
|
|
|
defer s.mu.RUnlock()
|
|
|
|
duration := time.Since(s.startTime).Seconds()
|
|
|
|
return fmt.Sprintf("object create %d bytes in %f seconds, avg: %f", s.objCreateSize, duration, float64(s.objCreateSize)/duration)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *MinioStatsWatcher) Reset() {
|
|
|
|
s.mu.Lock()
|
|
|
|
defer s.mu.Unlock()
|
|
|
|
s.objCreateSize = 0
|
|
|
|
s.startTime = time.Now()
|
|
|
|
}
|