mirror of
https://github.com/cubefs/cubefs.git
synced 2026-08-02 02:00:56 +00:00
feat(master): support config decommission settings
Signed-off-by: NaturalSelect <huangzhibin1@oppo.com>
This commit is contained in:
parent
8386685205
commit
5365949f7c
@ -253,7 +253,10 @@ func newClusterSetParasCmd(client *master.MasterClient) *cobra.Command {
|
|||||||
dataNodeSelector := ""
|
dataNodeSelector := ""
|
||||||
metaNodeSelector := ""
|
metaNodeSelector := ""
|
||||||
markBrokenDiskThreshold := ""
|
markBrokenDiskThreshold := ""
|
||||||
|
autoDecommissionDisk := ""
|
||||||
|
autoDecommissionDiskInterval := ""
|
||||||
autoDpMetaRepair := ""
|
autoDpMetaRepair := ""
|
||||||
|
autoDpMetaRepairParallelCnt := ""
|
||||||
opMaxMpCntLimit := ""
|
opMaxMpCntLimit := ""
|
||||||
dpRepairTimeout := ""
|
dpRepairTimeout := ""
|
||||||
dpTimeout := ""
|
dpTimeout := ""
|
||||||
@ -273,11 +276,36 @@ func newClusterSetParasCmd(client *master.MasterClient) *cobra.Command {
|
|||||||
}
|
}
|
||||||
markBrokenDiskThreshold = fmt.Sprintf("%v", val)
|
markBrokenDiskThreshold = fmt.Sprintf("%v", val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if autoDecommissionDisk != "" {
|
||||||
|
if _, err = strconv.ParseBool(autoDecommissionDisk); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if autoDecommissionDiskInterval != "" {
|
||||||
|
var interval time.Duration
|
||||||
|
interval, err = time.ParseDuration(autoDecommissionDiskInterval)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if interval < time.Second {
|
||||||
|
err = fmt.Errorf("auto decommission disk interval %v smaller than 1s", interval)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
autoDecommissionDiskInterval = strconv.FormatInt(int64(interval), 10)
|
||||||
|
}
|
||||||
|
|
||||||
if autoDpMetaRepair != "" {
|
if autoDpMetaRepair != "" {
|
||||||
if _, err = strconv.ParseBool(autoDpMetaRepair); err != nil {
|
if _, err = strconv.ParseBool(autoDpMetaRepair); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if autoDpMetaRepairParallelCnt != "" {
|
||||||
|
if _, err = strconv.ParseInt(autoDpMetaRepairParallelCnt, 10, 64); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if dpRepairTimeout != "" {
|
if dpRepairTimeout != "" {
|
||||||
var repairTimeout time.Duration
|
var repairTimeout time.Duration
|
||||||
@ -308,7 +336,10 @@ func newClusterSetParasCmd(client *master.MasterClient) *cobra.Command {
|
|||||||
if err = client.AdminAPI().SetClusterParas(optDelBatchCount, optMarkDeleteRate, optDelWorkerSleepMs,
|
if err = client.AdminAPI().SetClusterParas(optDelBatchCount, optMarkDeleteRate, optDelWorkerSleepMs,
|
||||||
optAutoRepairRate, optLoadFactor, opMaxDpCntLimit, opMaxMpCntLimit, clientIDKey,
|
optAutoRepairRate, optLoadFactor, opMaxDpCntLimit, opMaxMpCntLimit, clientIDKey,
|
||||||
dataNodesetSelector, metaNodesetSelector,
|
dataNodesetSelector, metaNodesetSelector,
|
||||||
dataNodeSelector, metaNodeSelector, markBrokenDiskThreshold, autoDpMetaRepair, dpRepairTimeout, dpTimeout); err != nil {
|
dataNodeSelector, metaNodeSelector, markBrokenDiskThreshold,
|
||||||
|
autoDecommissionDisk, autoDecommissionDiskInterval,
|
||||||
|
autoDpMetaRepair, autoDpMetaRepairParallelCnt,
|
||||||
|
dpRepairTimeout, dpTimeout); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
stdout("Cluster parameters has been set successfully. \n")
|
stdout("Cluster parameters has been set successfully. \n")
|
||||||
@ -328,8 +359,11 @@ func newClusterSetParasCmd(client *master.MasterClient) *cobra.Command {
|
|||||||
cmd.Flags().StringVar(&metaNodeSelector, CliFlagMetaNodeSelector, "", "Set the node select policy(metanode) for cluster")
|
cmd.Flags().StringVar(&metaNodeSelector, CliFlagMetaNodeSelector, "", "Set the node select policy(metanode) for cluster")
|
||||||
cmd.Flags().StringVar(&markBrokenDiskThreshold, CliFlagMarkDiskBrokenThreshold, "", "Threshold to mark disk as broken")
|
cmd.Flags().StringVar(&markBrokenDiskThreshold, CliFlagMarkDiskBrokenThreshold, "", "Threshold to mark disk as broken")
|
||||||
cmd.Flags().StringVar(&autoDpMetaRepair, CliFlagAutoDpMetaRepair, "", "Enable or disable auto data partition meta repair")
|
cmd.Flags().StringVar(&autoDpMetaRepair, CliFlagAutoDpMetaRepair, "", "Enable or disable auto data partition meta repair")
|
||||||
|
cmd.Flags().StringVar(&autoDpMetaRepairParallelCnt, CliFlagAutoDpMetaRepairParallelCnt, "", "Parallel count of auto data partition meta repair")
|
||||||
cmd.Flags().StringVar(&dpRepairTimeout, CliFlagDpRepairTimeout, "", "Data partition repair timeout(example: 1h)")
|
cmd.Flags().StringVar(&dpRepairTimeout, CliFlagDpRepairTimeout, "", "Data partition repair timeout(example: 1h)")
|
||||||
cmd.Flags().StringVar(&dpTimeout, CliFlagDpTimeout, "", "Data partition heartbeat timeout(example: 10s)")
|
cmd.Flags().StringVar(&dpTimeout, CliFlagDpTimeout, "", "Data partition heartbeat timeout(example: 10s)")
|
||||||
|
cmd.Flags().StringVar(&autoDecommissionDisk, CliFlagAutoDecommissionDisk, "", "Enable od disable auto decommission disk")
|
||||||
|
cmd.Flags().StringVar(&autoDecommissionDiskInterval, CliFlagAutoDecommissionDiskInterval, "", "Interval of auto decommission disk(example: 10s)")
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
141
cli/cmd/const.go
141
cli/cmd/const.go
@ -68,75 +68,78 @@ const (
|
|||||||
CliResourceConfig = "config"
|
CliResourceConfig = "config"
|
||||||
|
|
||||||
// Flags
|
// Flags
|
||||||
CliFlagName = "name"
|
CliFlagName = "name"
|
||||||
CliFlagOnwer = "user"
|
CliFlagOnwer = "user"
|
||||||
CliFlagDataPartitionSize = "dp-size"
|
CliFlagDataPartitionSize = "dp-size"
|
||||||
CliFlagDataPartitionCount = "dp-count"
|
CliFlagDataPartitionCount = "dp-count"
|
||||||
CliFlagMetaPartitionCount = "mp-count"
|
CliFlagMetaPartitionCount = "mp-count"
|
||||||
CliFlagReplicas = "replicas"
|
CliFlagReplicas = "replicas"
|
||||||
CliFlagEnable = "enable"
|
CliFlagEnable = "enable"
|
||||||
CliFlagEnableFollowerRead = "follower-read"
|
CliFlagEnableFollowerRead = "follower-read"
|
||||||
CliFlagAuthenticate = "authenticate"
|
CliFlagAuthenticate = "authenticate"
|
||||||
CliFlagCapacity = "capacity"
|
CliFlagCapacity = "capacity"
|
||||||
CliFlagBusiness = "description"
|
CliFlagBusiness = "description"
|
||||||
CliFlagMPCount = "mp-count"
|
CliFlagMPCount = "mp-count"
|
||||||
CliFlagDPCount = "dp-count"
|
CliFlagDPCount = "dp-count"
|
||||||
CliFlagReplicaNum = "replica-num"
|
CliFlagReplicaNum = "replica-num"
|
||||||
CliFlagSize = "size"
|
CliFlagSize = "size"
|
||||||
CliFlagVolType = "vol-type"
|
CliFlagVolType = "vol-type"
|
||||||
CliFlagFollowerRead = "follower-read"
|
CliFlagFollowerRead = "follower-read"
|
||||||
CliFlagCacheRuleKey = "cache-rule-key"
|
CliFlagCacheRuleKey = "cache-rule-key"
|
||||||
CliFlagEbsBlkSize = "ebs-blk-size"
|
CliFlagEbsBlkSize = "ebs-blk-size"
|
||||||
CliFlagCacheCapacity = "cache-capacity"
|
CliFlagCacheCapacity = "cache-capacity"
|
||||||
CliFlagCacheAction = "cache-action"
|
CliFlagCacheAction = "cache-action"
|
||||||
CliFlagCacheThreshold = "cache-threshold"
|
CliFlagCacheThreshold = "cache-threshold"
|
||||||
CliFlagCacheTTL = "cache-ttl"
|
CliFlagCacheTTL = "cache-ttl"
|
||||||
CliFlagCacheHighWater = "cache-high-water"
|
CliFlagCacheHighWater = "cache-high-water"
|
||||||
CliFlagCacheLowWater = "cache-low-water"
|
CliFlagCacheLowWater = "cache-low-water"
|
||||||
CliFlagCacheLRUInterval = "cache-lru-interval"
|
CliFlagCacheLRUInterval = "cache-lru-interval"
|
||||||
CliFlagCacheRule = "cache-rule"
|
CliFlagCacheRule = "cache-rule"
|
||||||
CliFlagThreshold = "threshold"
|
CliFlagThreshold = "threshold"
|
||||||
CliFlagAddress = "addr"
|
CliFlagAddress = "addr"
|
||||||
CliFlagDiskPath = "path"
|
CliFlagDiskPath = "path"
|
||||||
CliFlagAuthKey = "authkey"
|
CliFlagAuthKey = "authkey"
|
||||||
CliFlagINodeStartID = "inode-start"
|
CliFlagINodeStartID = "inode-start"
|
||||||
CliFlagId = "id"
|
CliFlagId = "id"
|
||||||
CliFlagZoneName = "zone-name"
|
CliFlagZoneName = "zone-name"
|
||||||
CliFlagDescription = "description"
|
CliFlagDescription = "description"
|
||||||
CliFlagAutoRepairRate = "autoRepairRate"
|
CliFlagAutoRepairRate = "autoRepairRate"
|
||||||
CliFlagDelBatchCount = "batchCount"
|
CliFlagDelBatchCount = "batchCount"
|
||||||
CliFlagDelWorkerSleepMs = "deleteWorkerSleepMs"
|
CliFlagDelWorkerSleepMs = "deleteWorkerSleepMs"
|
||||||
CliFlagLoadFactor = "loadFactor"
|
CliFlagLoadFactor = "loadFactor"
|
||||||
CliFlagMarkDelRate = "markDeleteRate"
|
CliFlagMarkDelRate = "markDeleteRate"
|
||||||
CliFlagMaxDpCntLimit = "maxDpCntLimit"
|
CliFlagMaxDpCntLimit = "maxDpCntLimit"
|
||||||
CliFlagMaxMpCntLimit = "maxMpCntLimit"
|
CliFlagMaxMpCntLimit = "maxMpCntLimit"
|
||||||
CliFlagDataNodeSelector = "dataNodeSelector"
|
CliFlagDataNodeSelector = "dataNodeSelector"
|
||||||
CliFlagMetaNodeSelector = "metaNodeSelector"
|
CliFlagMetaNodeSelector = "metaNodeSelector"
|
||||||
CliFlagDataNodesetSelector = "dataNodesetSelector"
|
CliFlagDataNodesetSelector = "dataNodesetSelector"
|
||||||
CliFlagMetaNodesetSelector = "metaNodesetSelector"
|
CliFlagMetaNodesetSelector = "metaNodesetSelector"
|
||||||
CliFlagCrossZone = "crossZone"
|
CliFlagCrossZone = "crossZone"
|
||||||
CliNormalZonesFirst = "normalZonesFirst"
|
CliNormalZonesFirst = "normalZonesFirst"
|
||||||
CliFlagCount = "count"
|
CliFlagCount = "count"
|
||||||
CliDpReadOnlyWhenVolFull = "readonly-when-full"
|
CliDpReadOnlyWhenVolFull = "readonly-when-full"
|
||||||
CliTxMask = "transaction-mask"
|
CliTxMask = "transaction-mask"
|
||||||
CliTxTimeout = "transaction-timeout"
|
CliTxTimeout = "transaction-timeout"
|
||||||
CliTxOpLimit = "transaction-limit"
|
CliTxOpLimit = "transaction-limit"
|
||||||
CliTxConflictRetryNum = "tx-conflict-retry-num"
|
CliTxConflictRetryNum = "tx-conflict-retry-num"
|
||||||
CliTxConflictRetryInterval = "tx-conflict-retry-Interval"
|
CliTxConflictRetryInterval = "tx-conflict-retry-Interval"
|
||||||
CliTxForceReset = "transaction-force-reset"
|
CliTxForceReset = "transaction-force-reset"
|
||||||
CliFlagMaxFiles = "maxFiles"
|
CliFlagMaxFiles = "maxFiles"
|
||||||
CliFlagMaxBytes = "maxBytes"
|
CliFlagMaxBytes = "maxBytes"
|
||||||
CliFlagMaxConcurrencyInode = "maxConcurrencyInode"
|
CliFlagMaxConcurrencyInode = "maxConcurrencyInode"
|
||||||
CliFlagForceInode = "forceInode"
|
CliFlagForceInode = "forceInode"
|
||||||
CliFlagEnableQuota = "enableQuota"
|
CliFlagEnableQuota = "enableQuota"
|
||||||
CliFlagDeleteLockTime = "delete-lock-time"
|
CliFlagDeleteLockTime = "delete-lock-time"
|
||||||
CliFlagClientIDKey = "clientIDKey"
|
CliFlagClientIDKey = "clientIDKey"
|
||||||
CliFlagMarkDiskBrokenThreshold = "markBrokenDiskThreshold"
|
CliFlagMarkDiskBrokenThreshold = "markBrokenDiskThreshold"
|
||||||
CliFlagForce = "force"
|
CliFlagForce = "force"
|
||||||
CliFlagEnableCrossZone = "cross-zone"
|
CliFlagEnableCrossZone = "cross-zone"
|
||||||
CliFlagAutoDpMetaRepair = "autoDpMetaRepair"
|
CliFlagAutoDpMetaRepair = "autoDpMetaRepair"
|
||||||
CliFlagDpRepairTimeout = "dpRepairTimeout"
|
CliFlagAutoDpMetaRepairParallelCnt = "autoDpMetaRepairParallelCnt"
|
||||||
CliFlagDpTimeout = "dpTimeout"
|
CliFlagDpRepairTimeout = "dpRepairTimeout"
|
||||||
|
CliFlagDpTimeout = "dpTimeout"
|
||||||
|
CliFlagAutoDecommissionDisk = "autoDecommissionDisk"
|
||||||
|
CliFlagAutoDecommissionDiskInterval = "autoDecommissionDiskInterval"
|
||||||
|
|
||||||
// CliFlagSetDataPartitionCount = "count" use dp-count instead
|
// CliFlagSetDataPartitionCount = "count" use dp-count instead
|
||||||
|
|
||||||
|
|||||||
@ -65,17 +65,19 @@ func formatClusterView(cv *proto.ClusterView, cn *proto.ClusterNodeInfo, cp *pro
|
|||||||
sb.WriteString(fmt.Sprintf(" DataNode available : %v GB\n", cv.DataNodeStatInfo.AvailGB))
|
sb.WriteString(fmt.Sprintf(" DataNode available : %v GB\n", cv.DataNodeStatInfo.AvailGB))
|
||||||
sb.WriteString(fmt.Sprintf(" DataNode total : %v GB\n", cv.DataNodeStatInfo.TotalGB))
|
sb.WriteString(fmt.Sprintf(" DataNode total : %v GB\n", cv.DataNodeStatInfo.TotalGB))
|
||||||
|
|
||||||
sb.WriteString(fmt.Sprintf(" Volume count : %v\n", len(cv.VolStatInfo)))
|
sb.WriteString(fmt.Sprintf(" Volume count : %v\n", len(cv.VolStatInfo)))
|
||||||
sb.WriteString(fmt.Sprintf(" Allow Mp Decomm : %v\n", formatEnabledDisabled(!cv.ForbidMpDecommission)))
|
sb.WriteString(fmt.Sprintf(" Allow Mp Decomm : %v\n", formatEnabledDisabled(!cv.ForbidMpDecommission)))
|
||||||
sb.WriteString(fmt.Sprintf(" EbsAddr : %v\n", cp.EbsAddr))
|
sb.WriteString(fmt.Sprintf(" EbsAddr : %v\n", cp.EbsAddr))
|
||||||
sb.WriteString(fmt.Sprintf(" LoadFactor : %v\n", cn.LoadFactor))
|
sb.WriteString(fmt.Sprintf(" LoadFactor : %v\n", cn.LoadFactor))
|
||||||
sb.WriteString(fmt.Sprintf(" DpRepairTimeout : %v\n", cv.DpRepairTimeout))
|
sb.WriteString(fmt.Sprintf(" DpRepairTimeout : %v\n", cv.DpRepairTimeout))
|
||||||
sb.WriteString(fmt.Sprintf(" DataPartitionTimeout : %v\n", cv.DpTimeout))
|
sb.WriteString(fmt.Sprintf(" DataPartitionTimeout : %v\n", cv.DpTimeout))
|
||||||
sb.WriteString(fmt.Sprintf(" volDeletionDelayTime : %v h\n", cv.VolDeletionDelayTimeHour))
|
sb.WriteString(fmt.Sprintf(" volDeletionDelayTime : %v h\n", cv.VolDeletionDelayTimeHour))
|
||||||
sb.WriteString(fmt.Sprintf(" EnableAutoDecommission: %v\n", cv.EnableAutoDecommission))
|
sb.WriteString(fmt.Sprintf(" EnableAutoDecommission : %v\n", cv.EnableAutoDecommission))
|
||||||
sb.WriteString(fmt.Sprintf(" EnableAutoDpMetaRepair: %v\n", cv.EnableAutoDpMetaRepair))
|
sb.WriteString(fmt.Sprintf(" AutoDecommissionDiskIntervak : %v\n", cv.AutoDecommissionDiskInterval))
|
||||||
sb.WriteString(fmt.Sprintf(" MarkDiskBrokenThreshold : %v\n", strutil.FormatPercent(cv.MarkDiskBrokenThreshold)))
|
sb.WriteString(fmt.Sprintf(" EnableAutoDpMetaRepair : %v\n", cv.EnableAutoDpMetaRepair))
|
||||||
sb.WriteString(fmt.Sprintf(" DecommissionDiskLimit: %v\n", cv.DecommissionDiskLimit))
|
sb.WriteString(fmt.Sprintf(" AutoDpMetaRepairParallelCnt : %v\n", cv.AutoDpMetaRepairParallelCnt))
|
||||||
|
sb.WriteString(fmt.Sprintf(" MarkDiskBrokenThreshold : %v\n", strutil.FormatPercent(cv.MarkDiskBrokenThreshold)))
|
||||||
|
sb.WriteString(fmt.Sprintf(" DecommissionDiskLimit : %v\n", cv.DecommissionDiskLimit))
|
||||||
return sb.String()
|
return sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1329,6 +1329,28 @@ func parseAndExtractSetNodeInfoParams(r *http.Request) (params map[string]interf
|
|||||||
params[markDiskBrokenThresholdKey] = val
|
params[markDiskBrokenThresholdKey] = val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if value = r.FormValue(autoDecommissionDiskKey); value != "" {
|
||||||
|
noParams = false
|
||||||
|
val := false
|
||||||
|
val, err = strconv.ParseBool(value)
|
||||||
|
if err != nil {
|
||||||
|
err = unmatchedKey(autoDecommissionDiskKey)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
params[autoDecommissionDiskKey] = val
|
||||||
|
}
|
||||||
|
|
||||||
|
if value = r.FormValue(autoDecommissionDiskIntervalKey); value != "" {
|
||||||
|
noParams = false
|
||||||
|
val := int64(0)
|
||||||
|
val, err = strconv.ParseInt(value, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
err = unmatchedKey(autoDecommissionDiskIntervalKey)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
params[autoDecommissionDiskIntervalKey] = time.Duration(val)
|
||||||
|
}
|
||||||
|
|
||||||
if value = r.FormValue(autoDpMetaRepairKey); value != "" {
|
if value = r.FormValue(autoDpMetaRepairKey); value != "" {
|
||||||
noParams = false
|
noParams = false
|
||||||
val := false
|
val := false
|
||||||
@ -1340,6 +1362,17 @@ func parseAndExtractSetNodeInfoParams(r *http.Request) (params map[string]interf
|
|||||||
params[autoDpMetaRepairKey] = val
|
params[autoDpMetaRepairKey] = val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if value = r.FormValue(autoDpMetaRepairParallelCntKey); value != "" {
|
||||||
|
noParams = false
|
||||||
|
val := int64(0)
|
||||||
|
val, err = strconv.ParseInt(value, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
err = unmatchedKey(autoDpMetaRepairParallelCntKey)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
params[autoDpMetaRepairParallelCntKey] = int(val)
|
||||||
|
}
|
||||||
|
|
||||||
if value = r.FormValue(dpTimeoutKey); value != "" {
|
if value = r.FormValue(dpTimeoutKey); value != "" {
|
||||||
noParams = false
|
noParams = false
|
||||||
val := int64(0)
|
val := int64(0)
|
||||||
|
|||||||
@ -783,29 +783,31 @@ func (m *Server) getCluster(w http.ResponseWriter, r *http.Request) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
cv := &proto.ClusterView{
|
cv := &proto.ClusterView{
|
||||||
Name: m.cluster.Name,
|
Name: m.cluster.Name,
|
||||||
CreateTime: time.Unix(m.cluster.CreateTime, 0).Format(proto.TimeFormat),
|
CreateTime: time.Unix(m.cluster.CreateTime, 0).Format(proto.TimeFormat),
|
||||||
LeaderAddr: m.leaderInfo.addr,
|
LeaderAddr: m.leaderInfo.addr,
|
||||||
DisableAutoAlloc: m.cluster.DisableAutoAllocate,
|
DisableAutoAlloc: m.cluster.DisableAutoAllocate,
|
||||||
ForbidMpDecommission: m.cluster.ForbidMpDecommission,
|
ForbidMpDecommission: m.cluster.ForbidMpDecommission,
|
||||||
MetaNodeThreshold: m.cluster.cfg.MetaNodeThreshold,
|
MetaNodeThreshold: m.cluster.cfg.MetaNodeThreshold,
|
||||||
Applied: m.fsm.applied,
|
Applied: m.fsm.applied,
|
||||||
MaxDataPartitionID: m.cluster.idAlloc.dataPartitionID,
|
MaxDataPartitionID: m.cluster.idAlloc.dataPartitionID,
|
||||||
MaxMetaNodeID: m.cluster.idAlloc.commonID,
|
MaxMetaNodeID: m.cluster.idAlloc.commonID,
|
||||||
MaxMetaPartitionID: m.cluster.idAlloc.metaPartitionID,
|
MaxMetaPartitionID: m.cluster.idAlloc.metaPartitionID,
|
||||||
VolDeletionDelayTimeHour: m.cluster.cfg.volDelayDeleteTimeHour,
|
VolDeletionDelayTimeHour: m.cluster.cfg.volDelayDeleteTimeHour,
|
||||||
DpRepairTimeout: m.cluster.GetDecommissionDataPartitionRecoverTimeOut(),
|
DpRepairTimeout: m.cluster.GetDecommissionDataPartitionRecoverTimeOut(),
|
||||||
MarkDiskBrokenThreshold: m.cluster.getMarkDiskBrokenThreshold(),
|
MarkDiskBrokenThreshold: m.cluster.getMarkDiskBrokenThreshold(),
|
||||||
EnableAutoDpMetaRepair: m.cluster.getEnableAutoDpMetaRepair(),
|
EnableAutoDpMetaRepair: m.cluster.getEnableAutoDpMetaRepair(),
|
||||||
EnableAutoDecommission: m.cluster.AutoDecommissionDiskIsEnabled(),
|
AutoDpMetaRepairParallelCnt: m.cluster.GetAutoDpMetaRepairParallelCnt(),
|
||||||
DecommissionDiskLimit: m.cluster.GetDecommissionDiskLimit(),
|
EnableAutoDecommission: m.cluster.AutoDecommissionDiskIsEnabled(),
|
||||||
DpTimeout: time.Duration(m.cluster.getDataPartitionTimeoutSec()) * time.Second,
|
AutoDecommissionDiskInterval: m.cluster.GetAutoDecommissionDiskInterval(),
|
||||||
MasterNodes: make([]proto.NodeView, 0),
|
DecommissionDiskLimit: m.cluster.GetDecommissionDiskLimit(),
|
||||||
MetaNodes: make([]proto.NodeView, 0),
|
DpTimeout: time.Duration(m.cluster.getDataPartitionTimeoutSec()) * time.Second,
|
||||||
DataNodes: make([]proto.NodeView, 0),
|
MasterNodes: make([]proto.NodeView, 0),
|
||||||
VolStatInfo: make([]*proto.VolStatInfo, 0),
|
MetaNodes: make([]proto.NodeView, 0),
|
||||||
BadPartitionIDs: make([]proto.BadPartitionView, 0),
|
DataNodes: make([]proto.NodeView, 0),
|
||||||
BadMetaPartitionIDs: make([]proto.BadPartitionView, 0),
|
VolStatInfo: make([]*proto.VolStatInfo, 0),
|
||||||
|
BadPartitionIDs: make([]proto.BadPartitionView, 0),
|
||||||
|
BadMetaPartitionIDs: make([]proto.BadPartitionView, 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
vols := m.cluster.allVolNames()
|
vols := m.cluster.allVolNames()
|
||||||
@ -3160,6 +3162,27 @@ func (m *Server) setNodeInfoHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if val, ok := params[autoDecommissionDiskKey]; ok {
|
||||||
|
if autoDecomm, ok := val.(bool); ok {
|
||||||
|
old := m.cluster.EnableAutoDecommissionDisk.Load()
|
||||||
|
m.cluster.EnableAutoDecommissionDisk.Store(autoDecomm)
|
||||||
|
if err = m.cluster.syncPutCluster(); err != nil {
|
||||||
|
m.cluster.EnableAutoDecommissionDisk.Store(old)
|
||||||
|
sendErrReply(w, r, newErrHTTPReply(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, ok := params[autoDecommissionDiskIntervalKey]; ok {
|
||||||
|
if interval, ok := val.(time.Duration); ok {
|
||||||
|
if err = m.cluster.setAutoDecommissionDiskInterval(interval); err != nil {
|
||||||
|
sendErrReply(w, r, newErrHTTPReply(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if val, ok := params[autoDpMetaRepairKey]; ok {
|
if val, ok := params[autoDpMetaRepairKey]; ok {
|
||||||
if autoRepair, ok := val.(bool); ok {
|
if autoRepair, ok := val.(bool); ok {
|
||||||
if err = m.cluster.setEnableAutoDpMetaRepair(autoRepair); err != nil {
|
if err = m.cluster.setEnableAutoDpMetaRepair(autoRepair); err != nil {
|
||||||
@ -3169,6 +3192,15 @@ func (m *Server) setNodeInfoHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if val, ok := params[autoDpMetaRepairParallelCntKey]; ok {
|
||||||
|
if cnt, ok := val.(int); ok {
|
||||||
|
if err = m.cluster.setAutoDpMetaRepairParallelCnt(cnt); err != nil {
|
||||||
|
sendErrReply(w, r, newErrHTTPReply(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if val, ok := params[dpTimeoutKey]; ok {
|
if val, ok := params[dpTimeoutKey]; ok {
|
||||||
if dpTimeout, ok := val.(int64); ok {
|
if dpTimeout, ok := val.(int64); ok {
|
||||||
if err = m.cluster.setDataPartitionTimeout(dpTimeout); err != nil {
|
if err = m.cluster.setDataPartitionTimeout(dpTimeout); err != nil {
|
||||||
|
|||||||
@ -1645,6 +1645,30 @@ func TestSetMarkDiskBrokenThreshold(t *testing.T) {
|
|||||||
require.EqualValues(t, oldVal, server.cluster.getMarkDiskBrokenThreshold())
|
require.EqualValues(t, oldVal, server.cluster.getMarkDiskBrokenThreshold())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetEnableAutoDecommissionDisk(t *testing.T) {
|
||||||
|
reqUrl := fmt.Sprintf("%v%v", hostAddr, proto.AdminSetNodeInfo)
|
||||||
|
oldVal := server.cluster.EnableAutoDecommissionDisk.Load()
|
||||||
|
setVal := !oldVal
|
||||||
|
setUrl := fmt.Sprintf("%v?%v=%v&dirSizeLimit=0", reqUrl, autoDecommissionDiskKey, setVal)
|
||||||
|
unsetUrl := fmt.Sprintf("%v?%v=%v&dirSizeLimit=0", reqUrl, autoDecommissionDiskKey, oldVal)
|
||||||
|
process(setUrl, t)
|
||||||
|
require.EqualValues(t, setVal, server.cluster.EnableAutoDecommissionDisk.Load())
|
||||||
|
process(unsetUrl, t)
|
||||||
|
require.EqualValues(t, oldVal, server.cluster.EnableAutoDecommissionDisk.Load())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetDecommissionDiskInterval(t *testing.T) {
|
||||||
|
reqUrl := fmt.Sprintf("%v%v", hostAddr, proto.AdminSetNodeInfo)
|
||||||
|
oldVal := server.cluster.GetAutoDecommissionDiskInterval()
|
||||||
|
setVal := oldVal + 10*time.Second
|
||||||
|
setUrl := fmt.Sprintf("%v?%v=%v&dirSizeLimit=0", reqUrl, autoDecommissionDiskIntervalKey, int64(setVal))
|
||||||
|
unsetUrl := fmt.Sprintf("%v?%v=%v&dirSizeLimit=0", reqUrl, autoDecommissionDiskIntervalKey, int64(oldVal))
|
||||||
|
process(setUrl, t)
|
||||||
|
require.EqualValues(t, setVal, server.cluster.GetAutoDecommissionDiskInterval())
|
||||||
|
process(unsetUrl, t)
|
||||||
|
require.EqualValues(t, oldVal, server.cluster.GetAutoDecommissionDiskInterval())
|
||||||
|
}
|
||||||
|
|
||||||
func TestSetEnableAutoDpMetaRepair(t *testing.T) {
|
func TestSetEnableAutoDpMetaRepair(t *testing.T) {
|
||||||
reqUrl := fmt.Sprintf("%v%v", hostAddr, proto.AdminSetNodeInfo)
|
reqUrl := fmt.Sprintf("%v%v", hostAddr, proto.AdminSetNodeInfo)
|
||||||
oldVal := server.cluster.getEnableAutoDpMetaRepair()
|
oldVal := server.cluster.getEnableAutoDpMetaRepair()
|
||||||
@ -1657,6 +1681,18 @@ func TestSetEnableAutoDpMetaRepair(t *testing.T) {
|
|||||||
require.EqualValues(t, oldVal, server.cluster.getEnableAutoDpMetaRepair())
|
require.EqualValues(t, oldVal, server.cluster.getEnableAutoDpMetaRepair())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetAutoDpMetaRepairParallelCnt(t *testing.T) {
|
||||||
|
reqUrl := fmt.Sprintf("%v%v", hostAddr, proto.AdminSetNodeInfo)
|
||||||
|
oldVal := server.cluster.GetAutoDpMetaRepairParallelCnt()
|
||||||
|
setVal := 200
|
||||||
|
setUrl := fmt.Sprintf("%v?%v=%v&dirSizeLimit=0", reqUrl, autoDpMetaRepairParallelCntKey, setVal)
|
||||||
|
unsetUrl := fmt.Sprintf("%v?%v=%v&dirSizeLimit=0", reqUrl, autoDpMetaRepairParallelCntKey, oldVal)
|
||||||
|
process(setUrl, t)
|
||||||
|
require.EqualValues(t, setVal, server.cluster.GetAutoDpMetaRepairParallelCnt())
|
||||||
|
process(unsetUrl, t)
|
||||||
|
require.EqualValues(t, oldVal, server.cluster.GetAutoDpMetaRepairParallelCnt())
|
||||||
|
}
|
||||||
|
|
||||||
func TestSetDpTimeout(t *testing.T) {
|
func TestSetDpTimeout(t *testing.T) {
|
||||||
reqUrl := fmt.Sprintf("%v%v", hostAddr, proto.AdminSetNodeInfo)
|
reqUrl := fmt.Sprintf("%v%v", hostAddr, proto.AdminSetNodeInfo)
|
||||||
oldVal := server.cluster.getDataPartitionTimeoutSec()
|
oldVal := server.cluster.getDataPartitionTimeoutSec()
|
||||||
|
|||||||
@ -86,7 +86,8 @@ type Cluster struct {
|
|||||||
apiLimiter *ApiLimiter
|
apiLimiter *ApiLimiter
|
||||||
DecommissionDisks sync.Map
|
DecommissionDisks sync.Map
|
||||||
DecommissionLimit uint64
|
DecommissionLimit uint64
|
||||||
EnableAutoDecommissionDisk bool
|
EnableAutoDecommissionDisk atomicutil.Bool
|
||||||
|
AutoDecommissionInterval atomicutil.Int64
|
||||||
AutoDecommissionDiskMux sync.Mutex
|
AutoDecommissionDiskMux sync.Mutex
|
||||||
checkAutoCreateDataPartition bool
|
checkAutoCreateDataPartition bool
|
||||||
masterClient *masterSDK.MasterClient
|
masterClient *masterSDK.MasterClient
|
||||||
@ -106,6 +107,7 @@ type Cluster struct {
|
|||||||
S3ApiQosQuota *sync.Map // (api,uid,limtType) -> limitQuota
|
S3ApiQosQuota *sync.Map // (api,uid,limtType) -> limitQuota
|
||||||
MarkDiskBrokenThreshold atomicutil.Float64
|
MarkDiskBrokenThreshold atomicutil.Float64
|
||||||
EnableAutoDpMetaRepair atomicutil.Bool
|
EnableAutoDpMetaRepair atomicutil.Bool
|
||||||
|
AutoDpMetaRepairParallelCnt atomicutil.Uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type delayDeleteVolInfo struct {
|
type delayDeleteVolInfo struct {
|
||||||
@ -371,6 +373,7 @@ func newCluster(name string, leaderInfo *LeaderInfo, fsm *MetadataFsm, partition
|
|||||||
c.S3ApiQosQuota = new(sync.Map)
|
c.S3ApiQosQuota = new(sync.Map)
|
||||||
c.MarkDiskBrokenThreshold.Store(defaultMarkDiskBrokenThreshold)
|
c.MarkDiskBrokenThreshold.Store(defaultMarkDiskBrokenThreshold)
|
||||||
c.EnableAutoDpMetaRepair.Store(defaultEnableDpMetaRepair)
|
c.EnableAutoDpMetaRepair.Store(defaultEnableDpMetaRepair)
|
||||||
|
c.AutoDecommissionInterval.Store(int64(defaultAutoDecommissionDiskInterval))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4257,7 +4260,7 @@ func (c *Cluster) scheduleToBadDisk() {
|
|||||||
if c.partition.IsRaftLeader() && c.AutoDecommissionDiskIsEnabled() && c.metaReady {
|
if c.partition.IsRaftLeader() && c.AutoDecommissionDiskIsEnabled() && c.metaReady {
|
||||||
c.checkBadDisk()
|
c.checkBadDisk()
|
||||||
}
|
}
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(c.GetAutoDecommissionDiskInterval())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@ -4916,13 +4919,50 @@ func (c *Cluster) addDecommissionDiskToNodeset(dd *DecommissionDisk) (err error)
|
|||||||
func (c *Cluster) AutoDecommissionDiskIsEnabled() bool {
|
func (c *Cluster) AutoDecommissionDiskIsEnabled() bool {
|
||||||
c.AutoDecommissionDiskMux.Lock()
|
c.AutoDecommissionDiskMux.Lock()
|
||||||
defer c.AutoDecommissionDiskMux.Unlock()
|
defer c.AutoDecommissionDiskMux.Unlock()
|
||||||
return c.EnableAutoDecommissionDisk
|
return c.EnableAutoDecommissionDisk.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cluster) SetAutoDecommissionDisk(flag bool) {
|
func (c *Cluster) SetAutoDecommissionDisk(flag bool) {
|
||||||
c.AutoDecommissionDiskMux.Lock()
|
c.AutoDecommissionDiskMux.Lock()
|
||||||
defer c.AutoDecommissionDiskMux.Unlock()
|
defer c.AutoDecommissionDiskMux.Unlock()
|
||||||
c.EnableAutoDecommissionDisk = flag
|
c.EnableAutoDecommissionDisk.Store(flag)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cluster) GetAutoDecommissionDiskInterval() (interval time.Duration) {
|
||||||
|
tmp := c.AutoDecommissionInterval.Load()
|
||||||
|
if tmp == 0 {
|
||||||
|
tmp = int64(defaultAutoDecommissionDiskInterval)
|
||||||
|
}
|
||||||
|
interval = time.Duration(tmp)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cluster) setAutoDecommissionDiskInterval(interval time.Duration) (err error) {
|
||||||
|
old := c.AutoDecommissionInterval.Load()
|
||||||
|
c.AutoDecommissionInterval.Store(int64(interval))
|
||||||
|
if err = c.syncPutCluster(); err != nil {
|
||||||
|
c.AutoDecommissionInterval.Store(old)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cluster) GetAutoDpMetaRepairParallelCnt() (cnt int) {
|
||||||
|
cnt = int(c.AutoDpMetaRepairParallelCnt.Load())
|
||||||
|
if cnt == 0 {
|
||||||
|
cnt = defaultAutoDpMetaRepairPallarelCnt
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cluster) setAutoDpMetaRepairParallelCnt(cnt int) (err error) {
|
||||||
|
old := c.AutoDpMetaRepairParallelCnt.Load()
|
||||||
|
c.AutoDpMetaRepairParallelCnt.Store(uint32(cnt))
|
||||||
|
if err = c.syncPutCluster(); err != nil {
|
||||||
|
c.AutoDpMetaRepairParallelCnt.Store(old)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cluster) GetDecommissionDataPartitionRecoverTimeOut() time.Duration {
|
func (c *Cluster) GetDecommissionDataPartitionRecoverTimeOut() time.Duration {
|
||||||
|
|||||||
187
master/const.go
187
master/const.go
@ -50,97 +50,100 @@ const (
|
|||||||
forbiddenKey = "forbidden"
|
forbiddenKey = "forbidden"
|
||||||
deleteVolKey = "delete"
|
deleteVolKey = "delete"
|
||||||
|
|
||||||
forceDelVolKey = "forceDelVol"
|
forceDelVolKey = "forceDelVol"
|
||||||
ebsBlkSizeKey = "ebsBlkSize"
|
ebsBlkSizeKey = "ebsBlkSize"
|
||||||
cacheCapacity = "cacheCap"
|
cacheCapacity = "cacheCap"
|
||||||
cacheActionKey = "cacheAction"
|
cacheActionKey = "cacheAction"
|
||||||
cacheThresholdKey = "cacheThreshold"
|
cacheThresholdKey = "cacheThreshold"
|
||||||
cacheTTLKey = "cacheTTL"
|
cacheTTLKey = "cacheTTL"
|
||||||
cacheHighWaterKey = "cacheHighWater"
|
cacheHighWaterKey = "cacheHighWater"
|
||||||
cacheLowWaterKey = "cacheLowWater"
|
cacheLowWaterKey = "cacheLowWater"
|
||||||
cacheLRUIntervalKey = "cacheLRUInterval"
|
cacheLRUIntervalKey = "cacheLRUInterval"
|
||||||
clientVersion = "version"
|
clientVersion = "version"
|
||||||
domainIdKey = "domainId"
|
domainIdKey = "domainId"
|
||||||
volOwnerKey = "owner"
|
volOwnerKey = "owner"
|
||||||
volAuthKey = "authKey"
|
volAuthKey = "authKey"
|
||||||
replicaNumKey = "replicaNum"
|
replicaNumKey = "replicaNum"
|
||||||
followerReadKey = "followerRead"
|
followerReadKey = "followerRead"
|
||||||
authenticateKey = "authenticate"
|
authenticateKey = "authenticate"
|
||||||
akKey = "ak"
|
akKey = "ak"
|
||||||
keywordsKey = "keywords"
|
keywordsKey = "keywords"
|
||||||
zoneNameKey = "zoneName"
|
zoneNameKey = "zoneName"
|
||||||
nodesetIdKey = "nodesetId"
|
nodesetIdKey = "nodesetId"
|
||||||
crossZoneKey = "crossZone"
|
crossZoneKey = "crossZone"
|
||||||
normalZonesFirstKey = "normalZonesFirst"
|
normalZonesFirstKey = "normalZonesFirst"
|
||||||
userKey = "user"
|
userKey = "user"
|
||||||
nodeHostsKey = "hosts"
|
nodeHostsKey = "hosts"
|
||||||
nodeDeleteBatchCountKey = "batchCount"
|
nodeDeleteBatchCountKey = "batchCount"
|
||||||
nodeMarkDeleteRateKey = "markDeleteRate"
|
nodeMarkDeleteRateKey = "markDeleteRate"
|
||||||
nodeDeleteWorkerSleepMs = "deleteWorkerSleepMs"
|
nodeDeleteWorkerSleepMs = "deleteWorkerSleepMs"
|
||||||
nodeAutoRepairRateKey = "autoRepairRate"
|
nodeAutoRepairRateKey = "autoRepairRate"
|
||||||
nodeDpRepairTimeOutKey = "dpRepairTimeOut"
|
nodeDpRepairTimeOutKey = "dpRepairTimeOut"
|
||||||
nodeDpMaxRepairErrCntKey = "dpMaxRepairErrCnt"
|
nodeDpMaxRepairErrCntKey = "dpMaxRepairErrCnt"
|
||||||
clusterLoadFactorKey = "loadFactor"
|
clusterLoadFactorKey = "loadFactor"
|
||||||
maxDpCntLimitKey = "maxDpCntLimit"
|
maxDpCntLimitKey = "maxDpCntLimit"
|
||||||
maxMpCntLimitKey = "maxMpCntLimit"
|
maxMpCntLimitKey = "maxMpCntLimit"
|
||||||
clusterCreateTimeKey = "clusterCreateTime"
|
clusterCreateTimeKey = "clusterCreateTime"
|
||||||
descriptionKey = "description"
|
descriptionKey = "description"
|
||||||
dpSelectorNameKey = "dpSelectorName"
|
dpSelectorNameKey = "dpSelectorName"
|
||||||
dpSelectorParmKey = "dpSelectorParm"
|
dpSelectorParmKey = "dpSelectorParm"
|
||||||
nodeTypeKey = "nodeType"
|
nodeTypeKey = "nodeType"
|
||||||
ratio = "ratio"
|
ratio = "ratio"
|
||||||
rdOnlyKey = "rdOnly"
|
rdOnlyKey = "rdOnly"
|
||||||
srcAddrKey = "srcAddr"
|
srcAddrKey = "srcAddr"
|
||||||
targetAddrKey = "targetAddr"
|
targetAddrKey = "targetAddr"
|
||||||
forceKey = "force"
|
forceKey = "force"
|
||||||
raftForceDelKey = "raftForceDel"
|
raftForceDelKey = "raftForceDel"
|
||||||
enablePosixAclKey = "enablePosixAcl"
|
enablePosixAclKey = "enablePosixAcl"
|
||||||
enableTxMaskKey = "enableTxMask"
|
enableTxMaskKey = "enableTxMask"
|
||||||
txTimeoutKey = "txTimeout"
|
txTimeoutKey = "txTimeout"
|
||||||
txConflictRetryNumKey = "txConflictRetryNum"
|
txConflictRetryNumKey = "txConflictRetryNum"
|
||||||
txConflictRetryIntervalKey = "txConflictRetryInterval"
|
txConflictRetryIntervalKey = "txConflictRetryInterval"
|
||||||
txOpLimitKey = "txOpLimit"
|
txOpLimitKey = "txOpLimit"
|
||||||
txForceResetKey = "txForceReset"
|
txForceResetKey = "txForceReset"
|
||||||
QosEnableKey = "qosEnable"
|
QosEnableKey = "qosEnable"
|
||||||
DiskEnableKey = "diskenable"
|
DiskEnableKey = "diskenable"
|
||||||
IopsWKey = "iopsWKey"
|
IopsWKey = "iopsWKey"
|
||||||
IopsRKey = "iopsRKey"
|
IopsRKey = "iopsRKey"
|
||||||
FlowWKey = "flowWKey"
|
FlowWKey = "flowWKey"
|
||||||
FlowRKey = "flowRKey"
|
FlowRKey = "flowRKey"
|
||||||
ClientReqPeriod = "reqPeriod"
|
ClientReqPeriod = "reqPeriod"
|
||||||
ClientTriggerCnt = "triggerCnt"
|
ClientTriggerCnt = "triggerCnt"
|
||||||
QosMasterLimit = "qosLimit"
|
QosMasterLimit = "qosLimit"
|
||||||
decommissionLimit = "decommissionLimit"
|
decommissionLimit = "decommissionLimit"
|
||||||
DiskDisableKey = "diskDisable"
|
DiskDisableKey = "diskDisable"
|
||||||
Limit = "limit"
|
Limit = "limit"
|
||||||
TimeOut = "timeout"
|
TimeOut = "timeout"
|
||||||
CountByMeta = "countByMeta"
|
CountByMeta = "countByMeta"
|
||||||
dpReadOnlyWhenVolFull = "dpReadOnlyWhenVolFull"
|
dpReadOnlyWhenVolFull = "dpReadOnlyWhenVolFull"
|
||||||
PeriodicKey = "periodic"
|
PeriodicKey = "periodic"
|
||||||
IPKey = "ip"
|
IPKey = "ip"
|
||||||
OperateKey = "op"
|
OperateKey = "op"
|
||||||
UIDKey = "uid"
|
UIDKey = "uid"
|
||||||
CapacityKey = "capacity"
|
CapacityKey = "capacity"
|
||||||
configKey = "config"
|
configKey = "config"
|
||||||
MaxFilesKey = "maxFiles"
|
MaxFilesKey = "maxFiles"
|
||||||
MaxBytesKey = "maxBytes"
|
MaxBytesKey = "maxBytes"
|
||||||
fullPathKey = "fullPath"
|
fullPathKey = "fullPath"
|
||||||
inodeKey = "inode"
|
inodeKey = "inode"
|
||||||
quotaKey = "quotaId"
|
quotaKey = "quotaId"
|
||||||
enableQuota = "enableQuota"
|
enableQuota = "enableQuota"
|
||||||
dpDiscardKey = "dpDiscard"
|
dpDiscardKey = "dpDiscard"
|
||||||
ignoreDiscardKey = "ignoreDiscard"
|
ignoreDiscardKey = "ignoreDiscard"
|
||||||
TrashIntervalKey = "trashInterval"
|
TrashIntervalKey = "trashInterval"
|
||||||
ClientIDKey = "clientIDKey"
|
ClientIDKey = "clientIDKey"
|
||||||
verSeqKey = "verSeq"
|
verSeqKey = "verSeq"
|
||||||
Periodic = "periodic"
|
Periodic = "periodic"
|
||||||
DecommissionType = "decommissionType"
|
DecommissionType = "decommissionType"
|
||||||
decommissionDiskLimit = "decommissionDiskLimit"
|
decommissionDiskLimit = "decommissionDiskLimit"
|
||||||
dpRepairBlockSizeKey = "dpRepairBlockSize"
|
dpRepairBlockSizeKey = "dpRepairBlockSize"
|
||||||
markDiskBrokenThresholdKey = "markDiskBrokenThreshold"
|
markDiskBrokenThresholdKey = "markDiskBrokenThreshold"
|
||||||
decommissionTypeKey = "decommissionType"
|
decommissionTypeKey = "decommissionType"
|
||||||
autoDpMetaRepairKey = "autoDpMetaRepair"
|
autoDecommissionDiskKey = "autoDecommissionDisk"
|
||||||
dpTimeoutKey = "dpTimeout"
|
autoDecommissionDiskIntervalKey = "autoDecommissionDiskInterval"
|
||||||
|
autoDpMetaRepairKey = "autoDpMetaRepair"
|
||||||
|
autoDpMetaRepairParallelCntKey = "autoDpMetaRepairParallelCnt"
|
||||||
|
dpTimeoutKey = "dpTimeout"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -214,6 +217,8 @@ const (
|
|||||||
defaultVolDelayDeleteTimeHour = 48
|
defaultVolDelayDeleteTimeHour = 48
|
||||||
defaultMarkDiskBrokenThreshold = 0 // decommission all dp from disk
|
defaultMarkDiskBrokenThreshold = 0 // decommission all dp from disk
|
||||||
defaultEnableDpMetaRepair = false
|
defaultEnableDpMetaRepair = false
|
||||||
|
defaultAutoDpMetaRepairPallarelCnt = 100
|
||||||
|
defaultAutoDecommissionDiskInterval = 10 * time.Second
|
||||||
maxMpCreationCount = 10
|
maxMpCreationCount = 10
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -35,72 +35,76 @@ import (
|
|||||||
transferred over the network. */
|
transferred over the network. */
|
||||||
|
|
||||||
type clusterValue struct {
|
type clusterValue struct {
|
||||||
Name string
|
Name string
|
||||||
CreateTime int64
|
CreateTime int64
|
||||||
Threshold float32
|
Threshold float32
|
||||||
LoadFactor float32
|
LoadFactor float32
|
||||||
DisableAutoAllocate bool
|
DisableAutoAllocate bool
|
||||||
ForbidMpDecommission bool
|
ForbidMpDecommission bool
|
||||||
DataNodeDeleteLimitRate uint64
|
DataNodeDeleteLimitRate uint64
|
||||||
MetaNodeDeleteBatchCount uint64
|
MetaNodeDeleteBatchCount uint64
|
||||||
MetaNodeDeleteWorkerSleepMs uint64
|
MetaNodeDeleteWorkerSleepMs uint64
|
||||||
DataNodeAutoRepairLimitRate uint64
|
DataNodeAutoRepairLimitRate uint64
|
||||||
MaxDpCntLimit uint64
|
MaxDpCntLimit uint64
|
||||||
MaxMpCntLimit uint64
|
MaxMpCntLimit uint64
|
||||||
FaultDomain bool
|
FaultDomain bool
|
||||||
DiskQosEnable bool
|
DiskQosEnable bool
|
||||||
QosLimitUpload uint64
|
QosLimitUpload uint64
|
||||||
DirChildrenNumLimit uint32
|
DirChildrenNumLimit uint32
|
||||||
DecommissionLimit uint64
|
DecommissionLimit uint64
|
||||||
CheckDataReplicasEnable bool
|
CheckDataReplicasEnable bool
|
||||||
FileStatsEnable bool
|
FileStatsEnable bool
|
||||||
ClusterUuid string
|
ClusterUuid string
|
||||||
ClusterUuidEnable bool
|
ClusterUuidEnable bool
|
||||||
MetaPartitionInodeIdStep uint64
|
MetaPartitionInodeIdStep uint64
|
||||||
MaxConcurrentLcNodes uint64
|
MaxConcurrentLcNodes uint64
|
||||||
DpMaxRepairErrCnt uint64
|
DpMaxRepairErrCnt uint64
|
||||||
DpRepairTimeOut uint64
|
DpRepairTimeOut uint64
|
||||||
EnableAutoDecommissionDisk bool
|
EnableAutoDecommissionDisk bool
|
||||||
DecommissionDiskLimit uint32
|
AutoDecommissionDiskInterval int64
|
||||||
VolDeletionDelayTimeHour int64
|
DecommissionDiskLimit uint32
|
||||||
MarkDiskBrokenThreshold float64
|
VolDeletionDelayTimeHour int64
|
||||||
EnableAutoDpMetaRepair bool
|
MarkDiskBrokenThreshold float64
|
||||||
DataPartitionTimeoutSec int64
|
EnableAutoDpMetaRepair bool
|
||||||
|
AutoDpMetaRepairParallelCnt uint32
|
||||||
|
DataPartitionTimeoutSec int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func newClusterValue(c *Cluster) (cv *clusterValue) {
|
func newClusterValue(c *Cluster) (cv *clusterValue) {
|
||||||
cv = &clusterValue{
|
cv = &clusterValue{
|
||||||
Name: c.Name,
|
Name: c.Name,
|
||||||
CreateTime: c.CreateTime,
|
CreateTime: c.CreateTime,
|
||||||
LoadFactor: c.cfg.ClusterLoadFactor,
|
LoadFactor: c.cfg.ClusterLoadFactor,
|
||||||
Threshold: c.cfg.MetaNodeThreshold,
|
Threshold: c.cfg.MetaNodeThreshold,
|
||||||
DataNodeDeleteLimitRate: c.cfg.DataNodeDeleteLimitRate,
|
DataNodeDeleteLimitRate: c.cfg.DataNodeDeleteLimitRate,
|
||||||
MetaNodeDeleteBatchCount: c.cfg.MetaNodeDeleteBatchCount,
|
MetaNodeDeleteBatchCount: c.cfg.MetaNodeDeleteBatchCount,
|
||||||
MetaNodeDeleteWorkerSleepMs: c.cfg.MetaNodeDeleteWorkerSleepMs,
|
MetaNodeDeleteWorkerSleepMs: c.cfg.MetaNodeDeleteWorkerSleepMs,
|
||||||
DataNodeAutoRepairLimitRate: c.cfg.DataNodeAutoRepairLimitRate,
|
DataNodeAutoRepairLimitRate: c.cfg.DataNodeAutoRepairLimitRate,
|
||||||
DisableAutoAllocate: c.DisableAutoAllocate,
|
DisableAutoAllocate: c.DisableAutoAllocate,
|
||||||
ForbidMpDecommission: c.ForbidMpDecommission,
|
ForbidMpDecommission: c.ForbidMpDecommission,
|
||||||
MaxDpCntLimit: c.cfg.MaxDpCntLimit,
|
MaxDpCntLimit: c.cfg.MaxDpCntLimit,
|
||||||
MaxMpCntLimit: c.cfg.MaxMpCntLimit,
|
MaxMpCntLimit: c.cfg.MaxMpCntLimit,
|
||||||
FaultDomain: c.FaultDomain,
|
FaultDomain: c.FaultDomain,
|
||||||
DiskQosEnable: c.diskQosEnable,
|
DiskQosEnable: c.diskQosEnable,
|
||||||
QosLimitUpload: uint64(c.QosAcceptLimit.Limit()),
|
QosLimitUpload: uint64(c.QosAcceptLimit.Limit()),
|
||||||
DirChildrenNumLimit: c.cfg.DirChildrenNumLimit,
|
DirChildrenNumLimit: c.cfg.DirChildrenNumLimit,
|
||||||
DecommissionLimit: c.DecommissionLimit,
|
DecommissionLimit: c.DecommissionLimit,
|
||||||
CheckDataReplicasEnable: c.checkDataReplicasEnable,
|
CheckDataReplicasEnable: c.checkDataReplicasEnable,
|
||||||
FileStatsEnable: c.fileStatsEnable,
|
FileStatsEnable: c.fileStatsEnable,
|
||||||
ClusterUuid: c.clusterUuid,
|
ClusterUuid: c.clusterUuid,
|
||||||
ClusterUuidEnable: c.clusterUuidEnable,
|
ClusterUuidEnable: c.clusterUuidEnable,
|
||||||
MetaPartitionInodeIdStep: c.cfg.MetaPartitionInodeIdStep,
|
MetaPartitionInodeIdStep: c.cfg.MetaPartitionInodeIdStep,
|
||||||
MaxConcurrentLcNodes: c.cfg.MaxConcurrentLcNodes,
|
MaxConcurrentLcNodes: c.cfg.MaxConcurrentLcNodes,
|
||||||
DpMaxRepairErrCnt: c.cfg.DpMaxRepairErrCnt,
|
DpMaxRepairErrCnt: c.cfg.DpMaxRepairErrCnt,
|
||||||
DpRepairTimeOut: c.cfg.DpRepairTimeOut,
|
DpRepairTimeOut: c.cfg.DpRepairTimeOut,
|
||||||
EnableAutoDecommissionDisk: c.EnableAutoDecommissionDisk,
|
EnableAutoDecommissionDisk: c.EnableAutoDecommissionDisk.Load(),
|
||||||
DecommissionDiskLimit: c.GetDecommissionDiskLimit(),
|
AutoDecommissionDiskInterval: c.AutoDecommissionInterval.Load(),
|
||||||
VolDeletionDelayTimeHour: c.cfg.volDelayDeleteTimeHour,
|
DecommissionDiskLimit: c.GetDecommissionDiskLimit(),
|
||||||
MarkDiskBrokenThreshold: c.getMarkDiskBrokenThreshold(),
|
VolDeletionDelayTimeHour: c.cfg.volDelayDeleteTimeHour,
|
||||||
EnableAutoDpMetaRepair: c.getEnableAutoDpMetaRepair(),
|
MarkDiskBrokenThreshold: c.getMarkDiskBrokenThreshold(),
|
||||||
DataPartitionTimeoutSec: c.getDataPartitionTimeoutSec(),
|
EnableAutoDpMetaRepair: c.getEnableAutoDpMetaRepair(),
|
||||||
|
AutoDpMetaRepairParallelCnt: c.AutoDpMetaRepairParallelCnt.Load(),
|
||||||
|
DataPartitionTimeoutSec: c.getDataPartitionTimeoutSec(),
|
||||||
}
|
}
|
||||||
return cv
|
return cv
|
||||||
}
|
}
|
||||||
@ -1057,6 +1061,14 @@ func (c *Cluster) updateEnableAutoDpMetaRepair(val bool) {
|
|||||||
c.EnableAutoDpMetaRepair.Store(val)
|
c.EnableAutoDpMetaRepair.Store(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Cluster) updateAutoDecommissionDiskInterval(val int64) {
|
||||||
|
c.AutoDecommissionInterval.Store(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cluster) updateAutoDpMetaRepairParallelCnt(cnt uint32) {
|
||||||
|
c.AutoDpMetaRepairParallelCnt.Store(cnt)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Cluster) updateDecommissionDiskLimit(val uint32) {
|
func (c *Cluster) updateDecommissionDiskLimit(val uint32) {
|
||||||
if val < 1 {
|
if val < 1 {
|
||||||
val = 1
|
val = 1
|
||||||
@ -1179,7 +1191,8 @@ func (c *Cluster) loadClusterValue() (err error) {
|
|||||||
c.clusterUuid = cv.ClusterUuid
|
c.clusterUuid = cv.ClusterUuid
|
||||||
c.clusterUuidEnable = cv.ClusterUuidEnable
|
c.clusterUuidEnable = cv.ClusterUuidEnable
|
||||||
c.DecommissionLimit = cv.DecommissionLimit
|
c.DecommissionLimit = cv.DecommissionLimit
|
||||||
c.EnableAutoDecommissionDisk = cv.EnableAutoDecommissionDisk
|
c.EnableAutoDecommissionDisk.Store(cv.EnableAutoDecommissionDisk)
|
||||||
|
c.updateAutoDecommissionDiskInterval(cv.AutoDecommissionDiskInterval)
|
||||||
c.DecommissionLimit = cv.DecommissionLimit
|
c.DecommissionLimit = cv.DecommissionLimit
|
||||||
c.cfg.volDelayDeleteTimeHour = cv.VolDeletionDelayTimeHour
|
c.cfg.volDelayDeleteTimeHour = cv.VolDeletionDelayTimeHour
|
||||||
|
|
||||||
@ -1213,6 +1226,7 @@ func (c *Cluster) loadClusterValue() (err error) {
|
|||||||
c.checkDataReplicasEnable = cv.CheckDataReplicasEnable
|
c.checkDataReplicasEnable = cv.CheckDataReplicasEnable
|
||||||
c.updateMarkDiskBrokenThreshold(cv.MarkDiskBrokenThreshold)
|
c.updateMarkDiskBrokenThreshold(cv.MarkDiskBrokenThreshold)
|
||||||
c.updateEnableAutoDpMetaRepair(cv.EnableAutoDpMetaRepair)
|
c.updateEnableAutoDpMetaRepair(cv.EnableAutoDpMetaRepair)
|
||||||
|
c.updateAutoDpMetaRepairParallelCnt(cv.AutoDpMetaRepairParallelCnt)
|
||||||
c.updateDataPartitionTimeoutSec(cv.DataPartitionTimeoutSec)
|
c.updateDataPartitionTimeoutSec(cv.DataPartitionTimeoutSec)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|||||||
@ -607,7 +607,7 @@ func (vol *Vol) checkDataPartitions(c *Cluster) (cnt int) {
|
|||||||
|
|
||||||
partitions := vol.dataPartitions.clonePartitions()
|
partitions := vol.dataPartitions.clonePartitions()
|
||||||
checkMetaDp := make(map[uint64]*DataPartition)
|
checkMetaDp := make(map[uint64]*DataPartition)
|
||||||
checkMetaPool := routinepool.NewRoutinePool(10)
|
checkMetaPool := routinepool.NewRoutinePool(c.GetAutoDpMetaRepairParallelCnt())
|
||||||
defer checkMetaPool.WaitAndClose()
|
defer checkMetaPool.WaitAndClose()
|
||||||
var checkMetaDpWg sync.WaitGroup
|
var checkMetaDpWg sync.WaitGroup
|
||||||
|
|
||||||
|
|||||||
@ -117,31 +117,33 @@ type MetaReplicaInfo struct {
|
|||||||
|
|
||||||
// ClusterView provides the view of a cluster.
|
// ClusterView provides the view of a cluster.
|
||||||
type ClusterView struct {
|
type ClusterView struct {
|
||||||
Name string
|
Name string
|
||||||
CreateTime string
|
CreateTime string
|
||||||
LeaderAddr string
|
LeaderAddr string
|
||||||
DisableAutoAlloc bool
|
DisableAutoAlloc bool
|
||||||
ForbidMpDecommission bool
|
ForbidMpDecommission bool
|
||||||
MetaNodeThreshold float32
|
MetaNodeThreshold float32
|
||||||
Applied uint64
|
Applied uint64
|
||||||
MaxDataPartitionID uint64
|
MaxDataPartitionID uint64
|
||||||
MaxMetaNodeID uint64
|
MaxMetaNodeID uint64
|
||||||
MaxMetaPartitionID uint64
|
MaxMetaPartitionID uint64
|
||||||
VolDeletionDelayTimeHour int64
|
VolDeletionDelayTimeHour int64
|
||||||
MarkDiskBrokenThreshold float64
|
MarkDiskBrokenThreshold float64
|
||||||
EnableAutoDpMetaRepair bool
|
EnableAutoDpMetaRepair bool
|
||||||
EnableAutoDecommission bool
|
AutoDpMetaRepairParallelCnt int
|
||||||
DecommissionDiskLimit uint32
|
EnableAutoDecommission bool
|
||||||
DpRepairTimeout time.Duration
|
AutoDecommissionDiskInterval time.Duration
|
||||||
DpTimeout time.Duration
|
DecommissionDiskLimit uint32
|
||||||
DataNodeStatInfo *NodeStatInfo
|
DpRepairTimeout time.Duration
|
||||||
MetaNodeStatInfo *NodeStatInfo
|
DpTimeout time.Duration
|
||||||
VolStatInfo []*VolStatInfo
|
DataNodeStatInfo *NodeStatInfo
|
||||||
BadPartitionIDs []BadPartitionView
|
MetaNodeStatInfo *NodeStatInfo
|
||||||
BadMetaPartitionIDs []BadPartitionView
|
VolStatInfo []*VolStatInfo
|
||||||
MasterNodes []NodeView
|
BadPartitionIDs []BadPartitionView
|
||||||
MetaNodes []NodeView
|
BadMetaPartitionIDs []BadPartitionView
|
||||||
DataNodes []NodeView
|
MasterNodes []NodeView
|
||||||
|
MetaNodes []NodeView
|
||||||
|
DataNodes []NodeView
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClusterNode defines the structure of a cluster node
|
// ClusterNode defines the structure of a cluster node
|
||||||
|
|||||||
@ -517,7 +517,9 @@ func (api *AdminAPI) SetMasterVolDeletionDelayTime(volDeletionDelayTimeHour int)
|
|||||||
|
|
||||||
func (api *AdminAPI) SetClusterParas(batchCount, markDeleteRate, deleteWorkerSleepMs, autoRepairRate, loadFactor, maxDpCntLimit, maxMpCntLimit, clientIDKey string,
|
func (api *AdminAPI) SetClusterParas(batchCount, markDeleteRate, deleteWorkerSleepMs, autoRepairRate, loadFactor, maxDpCntLimit, maxMpCntLimit, clientIDKey string,
|
||||||
dataNodesetSelector, metaNodesetSelector, dataNodeSelector, metaNodeSelector string, markDiskBrokenThreshold string,
|
dataNodesetSelector, metaNodesetSelector, dataNodeSelector, metaNodeSelector string, markDiskBrokenThreshold string,
|
||||||
enableAutoDpMetaRepair string, dpRepairTimeout string, dpTimeout string,
|
enableAutoDecommissionDisk string, autoDecommissionDiskInterval string,
|
||||||
|
enableAutoDpMetaRepair string, autoDpMetaRepairParallelCnt string,
|
||||||
|
dpRepairTimeout string, dpTimeout string,
|
||||||
) (err error) {
|
) (err error) {
|
||||||
request := newRequest(get, proto.AdminSetNodeInfo).Header(api.h)
|
request := newRequest(get, proto.AdminSetNodeInfo).Header(api.h)
|
||||||
request.addParam("batchCount", batchCount)
|
request.addParam("batchCount", batchCount)
|
||||||
@ -536,9 +538,18 @@ func (api *AdminAPI) SetClusterParas(batchCount, markDeleteRate, deleteWorkerSle
|
|||||||
if markDiskBrokenThreshold != "" {
|
if markDiskBrokenThreshold != "" {
|
||||||
request.addParam("markDiskBrokenThreshold", markDiskBrokenThreshold)
|
request.addParam("markDiskBrokenThreshold", markDiskBrokenThreshold)
|
||||||
}
|
}
|
||||||
|
if enableAutoDecommissionDisk != "" {
|
||||||
|
request.addParam("autoDecommissionDisk", enableAutoDecommissionDisk)
|
||||||
|
}
|
||||||
|
if autoDecommissionDiskInterval != "" {
|
||||||
|
request.addParam("autoDecommissionDiskInterval", autoDecommissionDiskInterval)
|
||||||
|
}
|
||||||
if enableAutoDpMetaRepair != "" {
|
if enableAutoDpMetaRepair != "" {
|
||||||
request.addParam("autoDpMetaRepair", enableAutoDpMetaRepair)
|
request.addParam("autoDpMetaRepair", enableAutoDpMetaRepair)
|
||||||
}
|
}
|
||||||
|
if autoDpMetaRepairParallelCnt != "" {
|
||||||
|
request.addParam("autoDpMetaRepairParallelCnt", autoDpMetaRepairParallelCnt)
|
||||||
|
}
|
||||||
if dpRepairTimeout != "" {
|
if dpRepairTimeout != "" {
|
||||||
request.addParam("dpRepairTimeOut", dpRepairTimeout)
|
request.addParam("dpRepairTimeOut", dpRepairTimeout)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,3 +45,12 @@ func (b *Bool) CompareAndSwap(old bool, newVal bool) (swaped bool) {
|
|||||||
swaped = atomic.CompareAndSwapUint32(&b.val, oldVal, val)
|
swaped = atomic.CompareAndSwapUint32(&b.val, oldVal, val)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Bool) Swap(new bool) (old bool) {
|
||||||
|
tmp := uint32(0)
|
||||||
|
if new {
|
||||||
|
tmp = 1
|
||||||
|
}
|
||||||
|
old = atomic.SwapUint32(&b.val, tmp) == 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@ -27,4 +27,6 @@ func TestAtomicBool(t *testing.T) {
|
|||||||
require.True(t, b.Load())
|
require.True(t, b.Load())
|
||||||
require.True(t, b.CompareAndSwap(true, false))
|
require.True(t, b.CompareAndSwap(true, false))
|
||||||
require.False(t, b.Load())
|
require.False(t, b.Load())
|
||||||
|
require.False(t, b.Swap(true))
|
||||||
|
require.True(t, b.Load())
|
||||||
}
|
}
|
||||||
|
|||||||
42
util/atomicutil/float32.go
Normal file
42
util/atomicutil/float32.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2023 The CubeFS Authors.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
package atomicutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"sync/atomic"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Float32 struct {
|
||||||
|
val uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Float32) Load() float32 {
|
||||||
|
return math.Float32frombits(atomic.LoadUint32(&f.val))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Float32) Store(val float32) {
|
||||||
|
atomic.StoreUint32(&f.val, math.Float32bits(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Float32) CompareAndSwap(old float32, new float32) (swaped bool) {
|
||||||
|
swaped = atomic.CompareAndSwapUint32(&f.val, math.Float32bits(old), math.Float32bits(new))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Float32) Swap(new float32) (old float32) {
|
||||||
|
old = math.Float32frombits(atomic.SwapUint32(&f.val, math.Float32bits(new)))
|
||||||
|
return
|
||||||
|
}
|
||||||
32
util/atomicutil/float32_test.go
Normal file
32
util/atomicutil/float32_test.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2023 The CubeFS Authors.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
package atomicutil_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/cubefs/cubefs/util/atomicutil"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAtomicFloat32(t *testing.T) {
|
||||||
|
f := atomicutil.Float32{}
|
||||||
|
testVal := float32(1.0)
|
||||||
|
f.Store(testVal)
|
||||||
|
require.Equal(t, testVal, f.Load())
|
||||||
|
require.True(t, f.CompareAndSwap(testVal, 0))
|
||||||
|
require.EqualValues(t, 0, f.Swap(testVal))
|
||||||
|
require.EqualValues(t, testVal, f.Load())
|
||||||
|
}
|
||||||
@ -30,3 +30,13 @@ func (f *Float64) Load() float64 {
|
|||||||
func (f *Float64) Store(val float64) {
|
func (f *Float64) Store(val float64) {
|
||||||
atomic.StoreUint64(&f.val, math.Float64bits(val))
|
atomic.StoreUint64(&f.val, math.Float64bits(val))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *Float64) CompareAndSwap(old float64, new float64) (swaped bool) {
|
||||||
|
swaped = atomic.CompareAndSwapUint64(&f.val, math.Float64bits(old), math.Float64bits(new))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Float64) Swap(new float64) (old float64) {
|
||||||
|
old = math.Float64frombits(atomic.SwapUint64(&f.val, math.Float64bits(new)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@ -26,4 +26,7 @@ func TestAtomicFloat64(t *testing.T) {
|
|||||||
testVal := float64(1.0)
|
testVal := float64(1.0)
|
||||||
f.Store(testVal)
|
f.Store(testVal)
|
||||||
require.Equal(t, testVal, f.Load())
|
require.Equal(t, testVal, f.Load())
|
||||||
|
require.True(t, f.CompareAndSwap(testVal, 0))
|
||||||
|
require.EqualValues(t, 0, f.Swap(testVal))
|
||||||
|
require.EqualValues(t, testVal, f.Load())
|
||||||
}
|
}
|
||||||
|
|||||||
50
util/atomicutil/int32.go
Normal file
50
util/atomicutil/int32.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright 2024 The CubeFS Authors.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
package atomicutil
|
||||||
|
|
||||||
|
import "sync/atomic"
|
||||||
|
|
||||||
|
type Int32 struct {
|
||||||
|
v int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Int32) Load() (v int32) {
|
||||||
|
v = atomic.LoadInt32(&i.v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Int32) Store(v int32) {
|
||||||
|
atomic.StoreInt32(&i.v, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Int32) CompareAndSwap(old int32, new int32) (swaped bool) {
|
||||||
|
swaped = atomic.CompareAndSwapInt32(&i.v, old, new)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Int32) Add(v int32) (new int32) {
|
||||||
|
new = atomic.AddInt32(&i.v, v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Int32) Sub(v int32) (new int32) {
|
||||||
|
new = atomic.AddInt32(&i.v, -v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Int32) Swap(v int32) (old int32) {
|
||||||
|
old = atomic.SwapInt32(&i.v, v)
|
||||||
|
return
|
||||||
|
}
|
||||||
33
util/atomicutil/int32_test.go
Normal file
33
util/atomicutil/int32_test.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2024 The CubeFS Authors.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
package atomicutil_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/cubefs/cubefs/util/atomicutil"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestInt32(t *testing.T) {
|
||||||
|
i := atomicutil.Int32{}
|
||||||
|
i.Store(1)
|
||||||
|
require.EqualValues(t, 1, i.Load())
|
||||||
|
require.EqualValues(t, 2, i.Add(1))
|
||||||
|
require.EqualValues(t, 2, i.Swap(1))
|
||||||
|
require.True(t, i.CompareAndSwap(1, 2))
|
||||||
|
require.EqualValues(t, 2, i.Load())
|
||||||
|
require.EqualValues(t, 1, i.Sub(1))
|
||||||
|
}
|
||||||
50
util/atomicutil/int64.go
Normal file
50
util/atomicutil/int64.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright 2024 The CubeFS Authors.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
package atomicutil
|
||||||
|
|
||||||
|
import "sync/atomic"
|
||||||
|
|
||||||
|
type Int64 struct {
|
||||||
|
v int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Int64) Load() (v int64) {
|
||||||
|
v = atomic.LoadInt64(&i.v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Int64) Store(v int64) {
|
||||||
|
atomic.StoreInt64(&i.v, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Int64) CompareAndSwap(old int64, new int64) (swaped bool) {
|
||||||
|
swaped = atomic.CompareAndSwapInt64(&i.v, old, new)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Int64) Add(v int64) (new int64) {
|
||||||
|
new = atomic.AddInt64(&i.v, v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Int64) Sub(v int64) (new int64) {
|
||||||
|
new = atomic.AddInt64(&i.v, -v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Int64) Swap(v int64) (old int64) {
|
||||||
|
old = atomic.SwapInt64(&i.v, v)
|
||||||
|
return
|
||||||
|
}
|
||||||
33
util/atomicutil/int64_test.go
Normal file
33
util/atomicutil/int64_test.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2024 The CubeFS Authors.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
package atomicutil_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/cubefs/cubefs/util/atomicutil"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestInt64(t *testing.T) {
|
||||||
|
i := atomicutil.Int64{}
|
||||||
|
i.Store(1)
|
||||||
|
require.EqualValues(t, 1, i.Load())
|
||||||
|
require.EqualValues(t, 2, i.Add(1))
|
||||||
|
require.EqualValues(t, 2, i.Swap(1))
|
||||||
|
require.True(t, i.CompareAndSwap(1, 2))
|
||||||
|
require.EqualValues(t, 2, i.Load())
|
||||||
|
require.EqualValues(t, 1, i.Sub(1))
|
||||||
|
}
|
||||||
50
util/atomicutil/uint32.go
Normal file
50
util/atomicutil/uint32.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright 2024 The CubeFS Authors.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
package atomicutil
|
||||||
|
|
||||||
|
import "sync/atomic"
|
||||||
|
|
||||||
|
type Uint32 struct {
|
||||||
|
v uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Uint32) Load() (v uint32) {
|
||||||
|
v = atomic.LoadUint32(&i.v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Uint32) Store(v uint32) {
|
||||||
|
atomic.StoreUint32(&i.v, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Uint32) CompareAndSwap(old uint32, new uint32) (swaped bool) {
|
||||||
|
swaped = atomic.CompareAndSwapUint32(&i.v, old, new)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Uint32) Add(v uint32) (new uint32) {
|
||||||
|
new = atomic.AddUint32(&i.v, v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Uint32) Sub(v int32) (new uint32) {
|
||||||
|
new = atomic.AddUint32(&i.v, ^uint32(v-1))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Uint32) Swap(v uint32) (old uint32) {
|
||||||
|
old = atomic.SwapUint32(&i.v, v)
|
||||||
|
return
|
||||||
|
}
|
||||||
33
util/atomicutil/uint32_test.go
Normal file
33
util/atomicutil/uint32_test.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2024 The CubeFS Authors.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
package atomicutil_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/cubefs/cubefs/util/atomicutil"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUint64(t *testing.T) {
|
||||||
|
i := atomicutil.Uint32{}
|
||||||
|
i.Store(1)
|
||||||
|
require.EqualValues(t, 1, i.Load())
|
||||||
|
require.EqualValues(t, 2, i.Add(1))
|
||||||
|
require.EqualValues(t, 2, i.Swap(1))
|
||||||
|
require.True(t, i.CompareAndSwap(1, 2))
|
||||||
|
require.EqualValues(t, 2, i.Load())
|
||||||
|
require.EqualValues(t, 1, i.Sub(1))
|
||||||
|
}
|
||||||
50
util/atomicutil/uint64.go
Normal file
50
util/atomicutil/uint64.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright 2024 The CubeFS Authors.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
package atomicutil
|
||||||
|
|
||||||
|
import "sync/atomic"
|
||||||
|
|
||||||
|
type Uint64 struct {
|
||||||
|
v uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Uint64) Load() (v uint64) {
|
||||||
|
v = atomic.LoadUint64(&i.v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Uint64) Store(v uint64) {
|
||||||
|
atomic.StoreUint64(&i.v, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Uint64) CompareAndSwap(old uint64, new uint64) (swaped bool) {
|
||||||
|
swaped = atomic.CompareAndSwapUint64(&i.v, old, new)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Uint64) Add(v uint64) (new uint64) {
|
||||||
|
new = atomic.AddUint64(&i.v, v)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Uint64) Sub(v int64) (new uint64) {
|
||||||
|
new = atomic.AddUint64(&i.v, ^uint64(v-1))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Uint64) Swap(v uint64) (old uint64) {
|
||||||
|
old = atomic.SwapUint64(&i.v, v)
|
||||||
|
return
|
||||||
|
}
|
||||||
33
util/atomicutil/uint64_test.go
Normal file
33
util/atomicutil/uint64_test.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2024 The CubeFS Authors.
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
package atomicutil_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/cubefs/cubefs/util/atomicutil"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUint32(t *testing.T) {
|
||||||
|
i := atomicutil.Uint32{}
|
||||||
|
i.Store(1)
|
||||||
|
require.EqualValues(t, 1, i.Load())
|
||||||
|
require.EqualValues(t, 2, i.Add(1))
|
||||||
|
require.EqualValues(t, 2, i.Swap(1))
|
||||||
|
require.True(t, i.CompareAndSwap(1, 2))
|
||||||
|
require.EqualValues(t, 2, i.Load())
|
||||||
|
require.EqualValues(t, 1, i.Sub(1))
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user