|
@@ -15,6 +15,8 @@
|
|
|
package etcdserver
|
|
package etcdserver
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
|
|
|
+ "sync"
|
|
|
|
|
+
|
|
|
pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
|
|
pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
|
|
|
|
|
|
|
|
humanize "github.com/dustin/go-humanize"
|
|
humanize "github.com/dustin/go-humanize"
|
|
@@ -60,61 +62,75 @@ const (
|
|
|
kvOverhead = 256
|
|
kvOverhead = 256
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+var (
|
|
|
|
|
+ // only log once
|
|
|
|
|
+ quotaLogOnce sync.Once
|
|
|
|
|
+
|
|
|
|
|
+ defaultQuotaSize = humanize.Bytes(uint64(DefaultQuotaBytes))
|
|
|
|
|
+ maxQuotaSize = humanize.Bytes(uint64(MaxQuotaBytes))
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+// NewBackendQuota creates a quota layer with the given storage limit.
|
|
|
func NewBackendQuota(s *EtcdServer, name string) Quota {
|
|
func NewBackendQuota(s *EtcdServer, name string) Quota {
|
|
|
lg := s.getLogger()
|
|
lg := s.getLogger()
|
|
|
quotaBackendBytes.Set(float64(s.Cfg.QuotaBackendBytes))
|
|
quotaBackendBytes.Set(float64(s.Cfg.QuotaBackendBytes))
|
|
|
|
|
|
|
|
if s.Cfg.QuotaBackendBytes < 0 {
|
|
if s.Cfg.QuotaBackendBytes < 0 {
|
|
|
// disable quotas if negative
|
|
// disable quotas if negative
|
|
|
- if lg != nil {
|
|
|
|
|
- lg.Info(
|
|
|
|
|
- "disabled backend quota",
|
|
|
|
|
- zap.String("quota-name", name),
|
|
|
|
|
- zap.Int64("quota-size-bytes", s.Cfg.QuotaBackendBytes),
|
|
|
|
|
- )
|
|
|
|
|
- } else {
|
|
|
|
|
- plog.Warningf("disabling backend quota")
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ quotaLogOnce.Do(func() {
|
|
|
|
|
+ if lg != nil {
|
|
|
|
|
+ lg.Info(
|
|
|
|
|
+ "disabled backend quota",
|
|
|
|
|
+ zap.String("quota-name", name),
|
|
|
|
|
+ zap.Int64("quota-size-bytes", s.Cfg.QuotaBackendBytes),
|
|
|
|
|
+ )
|
|
|
|
|
+ } else {
|
|
|
|
|
+ plog.Warningf("disabling backend quota")
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
return &passthroughQuota{}
|
|
return &passthroughQuota{}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if s.Cfg.QuotaBackendBytes == 0 {
|
|
if s.Cfg.QuotaBackendBytes == 0 {
|
|
|
// use default size if no quota size given
|
|
// use default size if no quota size given
|
|
|
- if lg != nil {
|
|
|
|
|
- lg.Info(
|
|
|
|
|
- "enabled backend quota with default value",
|
|
|
|
|
- zap.String("quota-name", name),
|
|
|
|
|
- zap.Int64("quota-size-bytes", DefaultQuotaBytes),
|
|
|
|
|
- zap.String("quota-size", humanize.Bytes(uint64(DefaultQuotaBytes))),
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ quotaLogOnce.Do(func() {
|
|
|
|
|
+ if lg != nil {
|
|
|
|
|
+ lg.Info(
|
|
|
|
|
+ "enabled backend quota with default value",
|
|
|
|
|
+ zap.String("quota-name", name),
|
|
|
|
|
+ zap.Int64("quota-size-bytes", DefaultQuotaBytes),
|
|
|
|
|
+ zap.String("quota-size", defaultQuotaSize),
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
quotaBackendBytes.Set(float64(DefaultQuotaBytes))
|
|
quotaBackendBytes.Set(float64(DefaultQuotaBytes))
|
|
|
return &backendQuota{s, DefaultQuotaBytes}
|
|
return &backendQuota{s, DefaultQuotaBytes}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if s.Cfg.QuotaBackendBytes > MaxQuotaBytes {
|
|
|
|
|
|
|
+ quotaLogOnce.Do(func() {
|
|
|
|
|
+ if s.Cfg.QuotaBackendBytes > MaxQuotaBytes {
|
|
|
|
|
+ if lg != nil {
|
|
|
|
|
+ lg.Warn(
|
|
|
|
|
+ "quota exceeds the maximum value",
|
|
|
|
|
+ zap.String("quota-name", name),
|
|
|
|
|
+ zap.Int64("quota-size-bytes", s.Cfg.QuotaBackendBytes),
|
|
|
|
|
+ zap.String("quota-size", humanize.Bytes(uint64(s.Cfg.QuotaBackendBytes))),
|
|
|
|
|
+ zap.Int64("quota-maximum-size-bytes", MaxQuotaBytes),
|
|
|
|
|
+ zap.String("quota-maximum-size", maxQuotaSize),
|
|
|
|
|
+ )
|
|
|
|
|
+ } else {
|
|
|
|
|
+ plog.Warningf("backend quota %v exceeds maximum recommended quota %v", s.Cfg.QuotaBackendBytes, MaxQuotaBytes)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
if lg != nil {
|
|
if lg != nil {
|
|
|
- lg.Warn(
|
|
|
|
|
- "quota exceeds the maximum value",
|
|
|
|
|
|
|
+ lg.Info(
|
|
|
|
|
+ "enabled backend quota",
|
|
|
zap.String("quota-name", name),
|
|
zap.String("quota-name", name),
|
|
|
zap.Int64("quota-size-bytes", s.Cfg.QuotaBackendBytes),
|
|
zap.Int64("quota-size-bytes", s.Cfg.QuotaBackendBytes),
|
|
|
zap.String("quota-size", humanize.Bytes(uint64(s.Cfg.QuotaBackendBytes))),
|
|
zap.String("quota-size", humanize.Bytes(uint64(s.Cfg.QuotaBackendBytes))),
|
|
|
- zap.Int64("quota-maximum-size-bytes", MaxQuotaBytes),
|
|
|
|
|
- zap.String("quota-maximum-size", humanize.Bytes(uint64(MaxQuotaBytes))),
|
|
|
|
|
)
|
|
)
|
|
|
- } else {
|
|
|
|
|
- plog.Warningf("backend quota %v exceeds maximum recommended quota %v", s.Cfg.QuotaBackendBytes, MaxQuotaBytes)
|
|
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if lg != nil {
|
|
|
|
|
- lg.Info(
|
|
|
|
|
- "enabled backend quota",
|
|
|
|
|
- zap.String("quota-name", name),
|
|
|
|
|
- zap.Int64("quota-size-bytes", s.Cfg.QuotaBackendBytes),
|
|
|
|
|
- zap.String("quota-size", humanize.Bytes(uint64(s.Cfg.QuotaBackendBytes))),
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ })
|
|
|
return &backendQuota{s, s.Cfg.QuotaBackendBytes}
|
|
return &backendQuota{s, s.Cfg.QuotaBackendBytes}
|
|
|
}
|
|
}
|
|
|
|
|
|