mirror of
https://github.com/cubefs/cubefs.git
synced 2026-08-02 02:00:56 +00:00
feat(master): hybrid cloud add mediaType property to zone
(1) zone mediaType is set as the first add-in datanode's mediaType (2) once zone mediaType is set, all datanodes in the zone must be the same mediaType. (3) the cmd 'cfs-cli zone info' shows zone mediaType. Signed-off-by: true1064 <tangjingyu@oppo.com>
This commit is contained in:
parent
029d1b359e
commit
3081a30168
@ -875,6 +875,7 @@ func formatZoneView(zv *proto.ZoneView) string {
|
||||
sb := strings.Builder{}
|
||||
sb.WriteString(fmt.Sprintf("Zone Name: %v\n", zv.Name))
|
||||
sb.WriteString(fmt.Sprintf("Status: %v\n", zv.Status))
|
||||
sb.WriteString(fmt.Sprintf("MediaType: %v\n", zv.MediaType))
|
||||
sb.WriteString("Nodeset Selector:\n")
|
||||
sb.WriteString(fmt.Sprintf(" Data:%v\n", zv.DataNodesetSelector))
|
||||
sb.WriteString(fmt.Sprintf(" Meta:%v\n", zv.MetaNodesetSelector))
|
||||
|
||||
@ -18,6 +18,8 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
syslog "log"
|
||||
"math"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
@ -31,8 +33,6 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
syslog "log"
|
||||
|
||||
"github.com/cubefs/cubefs/cmd/common"
|
||||
"github.com/cubefs/cubefs/proto"
|
||||
"github.com/cubefs/cubefs/raftstore"
|
||||
@ -418,14 +418,9 @@ func (s *DataNode) parseConfig(cfg *config.Config) (err error) {
|
||||
s.diskUnavailablePartitionErrorCount = uint64(diskUnavailablePartitionErrorCount)
|
||||
log.LogDebugf("action[parseConfig] load diskUnavailablePartitionErrorCount(%v)", s.diskUnavailablePartitionErrorCount)
|
||||
|
||||
mediaType := cfg.GetInt64(ConfigMediaType)
|
||||
switch uint32(mediaType) {
|
||||
case proto.MediaType_SSD:
|
||||
s.mediaType = proto.MediaType_SSD
|
||||
case proto.MediaType_HDD:
|
||||
s.mediaType = proto.MediaType_HDD
|
||||
default:
|
||||
s.mediaType = proto.MediaType_Unspecified
|
||||
var mediaType uint32
|
||||
mediaTypeInt64 := cfg.GetInt64(ConfigMediaType)
|
||||
if mediaTypeInt64 < 0 || mediaTypeInt64 > math.MaxUint32 {
|
||||
err = fmt.Errorf("parseConfig: invalid mediaType[%v]", mediaType)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -103,6 +103,7 @@ type ZoneView struct {
|
||||
DataNodesetSelector string
|
||||
MetaNodesetSelector string
|
||||
NodeSet map[uint64]*NodeSetView
|
||||
MediaType string
|
||||
}
|
||||
|
||||
func newZoneView(name string) *ZoneView {
|
||||
@ -360,6 +361,7 @@ func (m *Server) getTopology(w http.ResponseWriter, r *http.Request) {
|
||||
cv.Status = zone.getStatusToString()
|
||||
cv.DataNodesetSelector = zone.GetDataNodesetSelector()
|
||||
cv.MetaNodesetSelector = zone.GetMetaNodesetSelector()
|
||||
cv.MediaType = zone.GetMediaTypeString()
|
||||
tv.Zones = append(tv.Zones, cv)
|
||||
nsc := zone.getAllNodeSet()
|
||||
for _, ns := range nsc {
|
||||
|
||||
@ -461,8 +461,8 @@ func (c *Cluster) scheduleToUpdateStatInfo() {
|
||||
|
||||
func (c *Cluster) addNodeSetGrp(ns *nodeSet, load bool) (err error) {
|
||||
log.LogWarnf("addNodeSetGrp nodeSet id[%v] zonename[%v] load[%v] grpManager init[%v]",
|
||||
|
||||
ns.ID, ns.zoneName, load, c.domainManager.init)
|
||||
|
||||
if c.domainManager.init {
|
||||
err = c.domainManager.putNodeSet(ns, load)
|
||||
c.putZoneDomain(false)
|
||||
@ -1135,7 +1135,7 @@ func (c *Cluster) addMetaNode(nodeAddr, zoneName string, nodesetId uint64) (id u
|
||||
metaNode.MpCntLimit = newLimitCounter(&c.cfg.MaxMpCntLimit, defaultMaxMpCntLimit)
|
||||
zone, err := c.t.getZone(zoneName)
|
||||
if err != nil {
|
||||
zone = c.t.putZoneIfAbsent(newZone(zoneName))
|
||||
zone = c.t.putZoneIfAbsent(newZone(zoneName, proto.MediaType_Unspecified))
|
||||
}
|
||||
|
||||
var ns *nodeSet
|
||||
@ -1187,23 +1187,77 @@ func (c *Cluster) addDataNode(nodeAddr, zoneName string, nodesetId uint64, media
|
||||
c.dnMutex.Lock()
|
||||
defer c.dnMutex.Unlock()
|
||||
var dataNode *DataNode
|
||||
var needPersistZone bool
|
||||
log.LogInfof("[addDataNode] to add: datanode(%v) zone(%v) nodesetId(%v) mediaType(%v)",
|
||||
nodeAddr, zoneName, nodesetId, mediaType)
|
||||
|
||||
if node, ok := c.dataNodes.Load(nodeAddr); ok {
|
||||
dataNode = node.(*DataNode)
|
||||
if nodesetId > 0 && nodesetId != dataNode.NodeSetID {
|
||||
return dataNode.ID, fmt.Errorf("addr already in nodeset [%v]", nodeAddr)
|
||||
msg := fmt.Sprintf("datanode(%v) already in cluster, but nodesetId not match, existNodeSetID(%v) toAdd(%v)",
|
||||
nodeAddr, dataNode.NodeSetID, nodesetId)
|
||||
log.LogErrorf("[addDataNode] %v", msg)
|
||||
return dataNode.ID, fmt.Errorf(msg)
|
||||
}
|
||||
|
||||
if dataNode.MediaType != mediaType {
|
||||
msg := fmt.Sprintf("datanode(%v) already in cluster, but datanode mediaType not match, existMediaType(%v) toAdd(%v)",
|
||||
nodeAddr, proto.MediaTypeString(dataNode.MediaType), proto.MediaTypeString(mediaType))
|
||||
log.LogErrorf("[addDataNode] %v", msg)
|
||||
return dataNode.ID, fmt.Errorf(msg)
|
||||
}
|
||||
|
||||
log.LogInfof("[addDataNode] already exist: datanode(%v) zone(%v) nodesetId(%v) mediaType(%v)",
|
||||
nodeAddr, zoneName, nodesetId, mediaType)
|
||||
return dataNode.ID, nil
|
||||
}
|
||||
|
||||
if !proto.IsValidMediaType(mediaType) {
|
||||
msg := fmt.Sprintf("invalid mediaType(%v) when adding datanode(%v)", mediaType, nodeAddr)
|
||||
log.LogErrorf("[addDataNode] %v", msg)
|
||||
return dataNode.ID, fmt.Errorf(msg)
|
||||
}
|
||||
|
||||
dataNode = newDataNode(nodeAddr, zoneName, c.Name, mediaType)
|
||||
dataNode.DpCntLimit = newLimitCounter(&c.cfg.MaxDpCntLimit, defaultMaxDpCntLimit)
|
||||
zone, err := c.t.getZone(zoneName)
|
||||
if err != nil {
|
||||
zone = c.t.putZoneIfAbsent(newZone(zoneName))
|
||||
log.LogInfof("[addDataNode] create zone(%v) by datanode(%v)", zoneName, nodeAddr)
|
||||
zone = newZone(zoneName, mediaType)
|
||||
needPersistZone = true
|
||||
}
|
||||
|
||||
zoneMediaType := zone.GetMediaType()
|
||||
if zoneMediaType != mediaType {
|
||||
if zoneMediaType != proto.MediaType_Unspecified {
|
||||
// if zone.mediaType is proto.MediaType_Unspecified, means has no datanode added into the zone yet
|
||||
|
||||
msg := fmt.Sprintf("datanode(%v) already in zone(%v) mediaType not match, existMediaType(%v) toAdd(%v)",
|
||||
nodeAddr, zoneName, proto.MediaTypeString(zoneMediaType), proto.MediaTypeString(mediaType))
|
||||
log.LogErrorf("[addDataNode] %v", msg)
|
||||
return dataNode.ID, fmt.Errorf(msg)
|
||||
} else {
|
||||
zone.SetMediaType(mediaType)
|
||||
log.LogInfof("[addDataNode] set zone(%v) mediaType(%v) by datanode(%v)",
|
||||
zoneName, proto.MediaTypeString(mediaType), nodeAddr)
|
||||
needPersistZone = true
|
||||
}
|
||||
}
|
||||
|
||||
if needPersistZone {
|
||||
persistErr := c.sycnPutZoneInfo(zone)
|
||||
if persistErr != nil {
|
||||
msg := fmt.Sprintf("persist zone(%v) failed when adding datanode(%v)", zoneName, nodeAddr)
|
||||
log.LogErrorf("[addDataNode] %v", msg)
|
||||
return dataNode.ID, fmt.Errorf(msg)
|
||||
}
|
||||
}
|
||||
c.t.putZoneIfAbsent(zone) // put if the above code creates zone
|
||||
|
||||
var ns *nodeSet
|
||||
if nodesetId > 0 {
|
||||
if ns, err = zone.getNodeSet(nodesetId); err != nil {
|
||||
log.LogErrorf("[addDataNode] %v", err.Error())
|
||||
return nodesetId, err
|
||||
}
|
||||
} else {
|
||||
@ -1237,11 +1291,11 @@ func (c *Cluster) addDataNode(nodeAddr, zoneName string, nodesetId uint64, media
|
||||
c.addNodeSetGrp(ns, false)
|
||||
|
||||
c.dataNodes.Store(nodeAddr, dataNode)
|
||||
log.LogInfof("action[addDataNode],clusterID[%v] dataNodeAddr:%v,nodeSetId[%v],capacity[%v]",
|
||||
log.LogInfof("action[addDataNode] clusterID[%v] dataNodeAddr:%v, nodeSetId[%v], capacity[%v]",
|
||||
c.Name, nodeAddr, ns.ID, ns.Capacity)
|
||||
return
|
||||
errHandler:
|
||||
err = fmt.Errorf("action[addDataNode],clusterID[%v] dataNodeAddr:%v err:%v ", c.Name, nodeAddr, err.Error())
|
||||
err = fmt.Errorf("action[addDataNode] clusterID[%v] dataNodeAddr:%v err:%v", c.Name, nodeAddr, err.Error())
|
||||
log.LogError(errors.Stack(err))
|
||||
Warn(c.Name, err.Error())
|
||||
return
|
||||
|
||||
@ -863,7 +863,7 @@ func (c *Cluster) adjustMetaNode(metaNode *MetaNode) {
|
||||
var zone *Zone
|
||||
zone, err = c.t.getZone(metaNode.ZoneName)
|
||||
if err != nil {
|
||||
zone = newZone(metaNode.ZoneName)
|
||||
zone = newZone(metaNode.ZoneName, proto.MediaType_Unspecified)
|
||||
c.t.putZone(zone)
|
||||
}
|
||||
c.nsMutex.Lock()
|
||||
@ -1045,7 +1045,7 @@ func (c *Cluster) adjustDataNode(dataNode *DataNode) {
|
||||
var zone *Zone
|
||||
zone, err = c.t.getZone(dataNode.ZoneName)
|
||||
if err != nil {
|
||||
zone = newZone(dataNode.ZoneName)
|
||||
zone = newZone(dataNode.ZoneName, dataNode.MediaType)
|
||||
c.t.putZone(zone)
|
||||
}
|
||||
|
||||
|
||||
@ -64,14 +64,14 @@ const (
|
||||
// default value
|
||||
const (
|
||||
defaultTobeFreedDataPartitionCount = 1000
|
||||
defaultSecondsToFreeDataPartitionAfterLoad = 5 * 60 // a data partition can only be freed after loading 5 mins
|
||||
defaultIntervalToFreeDataPartition = 10 // in terms of seconds
|
||||
defaultSecondsToFreeDataPartitionAfterLoad = 5 * 60 // a data partition can only be freed after loading 5 mins
|
||||
defaultIntervalToFreeDataPartition = 10 // in terms of seconds
|
||||
defaultIntervalToCheck = 60
|
||||
defaultIntervalToCheckHeartbeat = 6
|
||||
defaultIntervalToCheckDataPartition = 5
|
||||
defaultIntervalToCheckQos = 1
|
||||
defaultIntervalToCheckCrc = 20 * defaultIntervalToCheck // in terms of seconds
|
||||
noHeartBeatTimes = 3 // number of times that no heartbeat reported
|
||||
defaultIntervalToCheckCrc = 20 * defaultIntervalToCheck // in terms of seconds
|
||||
noHeartBeatTimes = 3 // number of times that no heartbeat reported
|
||||
defaultNodeTimeOutSec = noHeartBeatTimes * defaultIntervalToCheckHeartbeat
|
||||
defaultDataPartitionTimeOutSec = 200 * defaultIntervalToCheckHeartbeat // datanode with massive amount of dp may cost 10-min
|
||||
defaultMissingDataPartitionInterval = 24 * 3600
|
||||
|
||||
@ -24,8 +24,8 @@ import (
|
||||
|
||||
"golang.org/x/time/rate"
|
||||
|
||||
"github.com/cubefs/cubefs/depends/tiglabs/raft/proto"
|
||||
bsProto "github.com/cubefs/cubefs/proto"
|
||||
raftProto "github.com/cubefs/cubefs/depends/tiglabs/raft/proto"
|
||||
"github.com/cubefs/cubefs/proto"
|
||||
"github.com/cubefs/cubefs/util/errors"
|
||||
"github.com/cubefs/cubefs/util/log"
|
||||
)
|
||||
@ -121,7 +121,7 @@ type metaPartitionValue struct {
|
||||
VolName string
|
||||
Hosts string
|
||||
OfflinePeerID uint64
|
||||
Peers []bsProto.Peer
|
||||
Peers []proto.Peer
|
||||
IsRecover bool
|
||||
}
|
||||
|
||||
@ -146,7 +146,7 @@ type dataPartitionValue struct {
|
||||
PartitionID uint64
|
||||
ReplicaNum uint8
|
||||
Hosts string
|
||||
Peers []bsProto.Peer
|
||||
Peers []proto.Peer
|
||||
Status int8
|
||||
VolID uint64
|
||||
VolName string
|
||||
@ -309,7 +309,7 @@ type volValue struct {
|
||||
EnablePosixAcl bool
|
||||
EnableQuota bool
|
||||
|
||||
EnableTransaction bsProto.TxOpMask
|
||||
EnableTransaction proto.TxOpMask
|
||||
TxTimeout int64
|
||||
TxConflictRetryNum int64
|
||||
TxConflictRetryInterval int64
|
||||
@ -377,14 +377,14 @@ func newVolValue(vol *Vol) (vv *volValue) {
|
||||
CacheLRUInterval: vol.CacheLRUInterval,
|
||||
CacheRule: vol.CacheRule,
|
||||
VolQosEnable: vol.qosManager.qosEnable,
|
||||
IopsRLimit: vol.qosManager.getQosLimit(bsProto.IopsReadType),
|
||||
IopsWLimit: vol.qosManager.getQosLimit(bsProto.IopsWriteType),
|
||||
FlowRlimit: vol.qosManager.getQosLimit(bsProto.FlowReadType),
|
||||
FlowWlimit: vol.qosManager.getQosLimit(bsProto.FlowWriteType),
|
||||
IopsRMagnify: vol.qosManager.getQosMagnify(bsProto.IopsReadType),
|
||||
IopsWMagnify: vol.qosManager.getQosMagnify(bsProto.IopsWriteType),
|
||||
FlowRMagnify: vol.qosManager.getQosMagnify(bsProto.FlowReadType),
|
||||
FlowWMagnify: vol.qosManager.getQosMagnify(bsProto.FlowWriteType),
|
||||
IopsRLimit: vol.qosManager.getQosLimit(proto.IopsReadType),
|
||||
IopsWLimit: vol.qosManager.getQosLimit(proto.IopsWriteType),
|
||||
FlowRlimit: vol.qosManager.getQosLimit(proto.FlowReadType),
|
||||
FlowWlimit: vol.qosManager.getQosLimit(proto.FlowWriteType),
|
||||
IopsRMagnify: vol.qosManager.getQosMagnify(proto.IopsReadType),
|
||||
IopsWMagnify: vol.qosManager.getQosMagnify(proto.IopsWriteType),
|
||||
FlowRMagnify: vol.qosManager.getQosMagnify(proto.FlowReadType),
|
||||
FlowWMagnify: vol.qosManager.getQosMagnify(proto.FlowWriteType),
|
||||
ClientReqPeriod: vol.qosManager.ClientReqPeriod,
|
||||
ClientHitTriggerCnt: vol.qosManager.ClientHitTriggerCnt,
|
||||
|
||||
@ -994,8 +994,8 @@ func (c *Cluster) syncPutDataNode(opType uint32, dataNode *DataNode) (err error)
|
||||
func (c *Cluster) addRaftNode(nodeID uint64, addr string) (err error) {
|
||||
log.LogInfof("action[addRaftNode] nodeID: %v, addr: %v:", nodeID, addr)
|
||||
|
||||
peer := proto.Peer{ID: nodeID}
|
||||
_, err = c.partition.ChangeMember(proto.ConfAddNode, peer, []byte(addr))
|
||||
peer := raftProto.Peer{ID: nodeID}
|
||||
_, err = c.partition.ChangeMember(raftProto.ConfAddNode, peer, []byte(addr))
|
||||
if err != nil {
|
||||
return errors.New("action[addRaftNode] error: " + err.Error())
|
||||
}
|
||||
@ -1005,8 +1005,8 @@ func (c *Cluster) addRaftNode(nodeID uint64, addr string) (err error) {
|
||||
func (c *Cluster) removeRaftNode(nodeID uint64, addr string) (err error) {
|
||||
log.LogInfof("action[removeRaftNode] nodeID: %v, addr: %v:", nodeID, addr)
|
||||
|
||||
peer := proto.Peer{ID: nodeID}
|
||||
_, err = c.partition.ChangeMember(proto.ConfRemoveNode, peer, []byte(addr))
|
||||
peer := raftProto.Peer{ID: nodeID}
|
||||
_, err = c.partition.ChangeMember(raftProto.ConfRemoveNode, peer, []byte(addr))
|
||||
if err != nil {
|
||||
return errors.New("action[removeRaftNode] error: " + err.Error())
|
||||
}
|
||||
@ -1014,8 +1014,8 @@ func (c *Cluster) removeRaftNode(nodeID uint64, addr string) (err error) {
|
||||
}
|
||||
|
||||
func (c *Cluster) updateDirChildrenNumLimit(val uint32) {
|
||||
if val < bsProto.MinDirChildrenNumLimit {
|
||||
val = bsProto.DefaultDirChildrenNumLimit
|
||||
if val < proto.MinDirChildrenNumLimit {
|
||||
val = proto.DefaultDirChildrenNumLimit
|
||||
}
|
||||
atomic.StoreUint32(&c.cfg.DirChildrenNumLimit, val)
|
||||
}
|
||||
@ -1119,9 +1119,10 @@ func (c *Cluster) loadZoneValue() (err error) {
|
||||
if zone.GetMetaNodesetSelector() != cv.MetaNodesetSelector {
|
||||
zone.metaNodesetSelector = NewNodesetSelector(cv.MetaNodesetSelector, MetaNodeType)
|
||||
}
|
||||
log.LogInfof("action[loadZoneValue] load zonename[%v] with limit [%v,%v,%v,%v]",
|
||||
zone.name, cv.QosFlowRLimit, cv.QosIopsWLimit, cv.QosFlowWLimit, cv.QosIopsRLimit)
|
||||
log.LogInfof("action[loadZoneValue] load zoneName[%v] with limit [%v,%v,%v,%v], mediaType:%v",
|
||||
zone.name, cv.QosFlowRLimit, cv.QosIopsWLimit, cv.QosFlowWLimit, cv.QosIopsRLimit, proto.MediaTypeString(cv.MediaType))
|
||||
zone.loadDataNodeQosLimit()
|
||||
zone.SetMediaType(cv.MediaType)
|
||||
}
|
||||
|
||||
return
|
||||
@ -1278,7 +1279,7 @@ func (c *Cluster) loadNodeSets() (err error) {
|
||||
zone, err := c.t.getZone(nsv.ZoneName)
|
||||
if err != nil {
|
||||
log.LogErrorf("action[loadNodeSets], getZone err:%v", err)
|
||||
zone = newZone(nsv.ZoneName)
|
||||
zone = newZone(nsv.ZoneName, proto.MediaType_Unspecified)
|
||||
c.t.putZoneIfAbsent(zone)
|
||||
}
|
||||
ns.UpdateMaxParallel(int32(c.DecommissionLimit))
|
||||
@ -1579,7 +1580,7 @@ func (c *Cluster) loadVols() (err error) {
|
||||
}
|
||||
|
||||
log.LogInfof("action[loadVols],vol[%v]", vol.Name)
|
||||
if vol.Forbidden && vol.Status == bsProto.VolStatusMarkDelete {
|
||||
if vol.Forbidden && vol.Status == proto.VolStatusMarkDelete {
|
||||
c.delayDeleteVolsInfo = append(c.delayDeleteVolsInfo, &delayDeleteVolInfo{volName: vol.Name, authKey: vol.authKey, execTime: vol.DeleteExecTime, user: vol.user})
|
||||
log.LogInfof("action[loadDelayDeleteVols],vol[%v]", vol.Name)
|
||||
}
|
||||
@ -1746,8 +1747,8 @@ type decommissionDiskValue struct {
|
||||
Type uint32
|
||||
DecommissionCompleteTime int64
|
||||
DecommissionLimit int
|
||||
IgnoreDecommissionDps []bsProto.IgnoreDecommissionDP
|
||||
ResidualDecommissionDps []bsProto.IgnoreDecommissionDP
|
||||
IgnoreDecommissionDps []proto.IgnoreDecommissionDP
|
||||
ResidualDecommissionDps []proto.IgnoreDecommissionDP
|
||||
DiskDisable bool
|
||||
}
|
||||
|
||||
@ -1878,19 +1879,19 @@ func (c *Cluster) loadLcNodes() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Cluster) syncAddLcConf(lcConf *bsProto.LcConfiguration) (err error) {
|
||||
func (c *Cluster) syncAddLcConf(lcConf *proto.LcConfiguration) (err error) {
|
||||
return c.syncPutLcConfInfo(opSyncAddLcConf, lcConf)
|
||||
}
|
||||
|
||||
func (c *Cluster) syncDeleteLcConf(lcConf *bsProto.LcConfiguration) (err error) {
|
||||
func (c *Cluster) syncDeleteLcConf(lcConf *proto.LcConfiguration) (err error) {
|
||||
return c.syncPutLcConfInfo(opSyncDeleteLcConf, lcConf)
|
||||
}
|
||||
|
||||
func (c *Cluster) syncUpdateLcConf(lcConf *bsProto.LcConfiguration) (err error) {
|
||||
func (c *Cluster) syncUpdateLcConf(lcConf *proto.LcConfiguration) (err error) {
|
||||
return c.syncPutLcConfInfo(opSyncUpdateLcConf, lcConf)
|
||||
}
|
||||
|
||||
func (c *Cluster) syncPutLcConfInfo(opType uint32, lcConf *bsProto.LcConfiguration) (err error) {
|
||||
func (c *Cluster) syncPutLcConfInfo(opType uint32, lcConf *proto.LcConfiguration) (err error) {
|
||||
metadata := new(RaftCmd)
|
||||
metadata.Op = opType
|
||||
metadata.K = lcConfPrefix + lcConf.VolName
|
||||
@ -1909,7 +1910,7 @@ func (c *Cluster) loadLcConfs() (err error) {
|
||||
}
|
||||
|
||||
for _, value := range result {
|
||||
lcConf := &bsProto.LcConfiguration{}
|
||||
lcConf := &proto.LcConfiguration{}
|
||||
if err = json.Unmarshal(value, lcConf); err != nil {
|
||||
err = fmt.Errorf("action[loadLcConfs],value:%v,unmarshal err:%v", string(value), err)
|
||||
return
|
||||
|
||||
@ -1390,6 +1390,7 @@ type Zone struct {
|
||||
QosIopsWLimit uint64
|
||||
QosFlowRLimit uint64
|
||||
QosFlowWLimit uint64
|
||||
mediaType uint32
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
@ -1401,9 +1402,10 @@ type zoneValue struct {
|
||||
QosFlowWLimit uint64
|
||||
DataNodesetSelector string
|
||||
MetaNodesetSelector string
|
||||
MediaType uint32
|
||||
}
|
||||
|
||||
func newZone(name string) (zone *Zone) {
|
||||
func newZone(name string, mediaType uint32) (zone *Zone) {
|
||||
zone = &Zone{name: name}
|
||||
zone.setStatus(normalZone)
|
||||
zone.dataNodes = new(sync.Map)
|
||||
@ -1411,6 +1413,7 @@ func newZone(name string) (zone *Zone) {
|
||||
zone.nodeSetMap = make(map[uint64]*nodeSet)
|
||||
zone.dataNodesetSelector = NewNodesetSelector(DefaultNodesetSelectorName, DataNodeType)
|
||||
zone.metaNodesetSelector = NewNodesetSelector(DefaultNodesetSelectorName, MetaNodeType)
|
||||
zone.SetMediaType(mediaType)
|
||||
return
|
||||
}
|
||||
|
||||
@ -1460,6 +1463,7 @@ func (zone *Zone) getFsmValue() *zoneValue {
|
||||
QosFlowWLimit: zone.QosFlowWLimit,
|
||||
DataNodesetSelector: zone.GetDataNodesetSelector(),
|
||||
MetaNodesetSelector: zone.GetMetaNodesetSelector(),
|
||||
MediaType: zone.GetMediaType(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1484,7 +1488,7 @@ func (zone *Zone) getNodeSet(setID uint64) (ns *nodeSet, err error) {
|
||||
defer zone.nsLock.RUnlock()
|
||||
ns, ok := zone.nodeSetMap[setID]
|
||||
if !ok {
|
||||
return nil, errors.NewErrorf("set %v not found", setID)
|
||||
return nil, errors.NewErrorf("nodeset %v not found", setID)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -1944,6 +1948,18 @@ func (zone *Zone) startDecommissionListTraverse(c *Cluster) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (zone *Zone) GetMediaType() uint32 {
|
||||
return atomic.LoadUint32(&zone.mediaType)
|
||||
}
|
||||
|
||||
func (zone *Zone) GetMediaTypeString() string {
|
||||
return proto.MediaTypeString(atomic.LoadUint32(&zone.mediaType))
|
||||
}
|
||||
|
||||
func (zone *Zone) SetMediaType(newMediaType uint32) {
|
||||
atomic.StoreUint32(&zone.mediaType, newMediaType)
|
||||
}
|
||||
|
||||
type DecommissionDataPartitionList struct {
|
||||
mu sync.Mutex
|
||||
cacheMap map[uint64]*list.Element
|
||||
|
||||
@ -25,7 +25,7 @@ func createDataNodeForTopo(addr, zoneName string, ns *nodeSet) (dn *DataNode) {
|
||||
func TestSingleZone(t *testing.T) {
|
||||
topo := newTopology()
|
||||
zoneName := "test"
|
||||
zone := newZone(zoneName)
|
||||
zone := newZone(zoneName, proto.MediaType_Unspecified)
|
||||
topo.putZone(zone)
|
||||
c := new(Cluster)
|
||||
nodeSet := newNodeSet(c, 1, 6, zoneName)
|
||||
@ -93,7 +93,7 @@ func TestAllocZones(t *testing.T) {
|
||||
|
||||
// add three zones
|
||||
zoneName1 := testZone1
|
||||
zone1 := newZone(zoneName1)
|
||||
zone1 := newZone(zoneName1, proto.MediaType_Unspecified)
|
||||
nodeSet1 := newNodeSet(c, 1, 6, zoneName1)
|
||||
|
||||
zone1.putNodeSet(nodeSet1)
|
||||
@ -102,7 +102,7 @@ func TestAllocZones(t *testing.T) {
|
||||
topo.putDataNode(createDataNodeForTopo(mds2Addr, zoneName1, nodeSet1))
|
||||
|
||||
zoneName2 := testZone2
|
||||
zone2 := newZone(zoneName2)
|
||||
zone2 := newZone(zoneName2, proto.MediaType_Unspecified)
|
||||
nodeSet2 := newNodeSet(c, 2, 6, zoneName2)
|
||||
|
||||
zone2.putNodeSet(nodeSet2)
|
||||
@ -111,7 +111,7 @@ func TestAllocZones(t *testing.T) {
|
||||
topo.putDataNode(createDataNodeForTopo(mds4Addr, zoneName2, nodeSet2))
|
||||
|
||||
zoneName3 := "zone3"
|
||||
zone3 := newZone(zoneName3)
|
||||
zone3 := newZone(zoneName3, proto.MediaType_Unspecified)
|
||||
nodeSet3 := newNodeSet(c, 3, 6, zoneName3)
|
||||
|
||||
zone3.putNodeSet(nodeSet3)
|
||||
|
||||
@ -1280,6 +1280,7 @@ type ZoneView struct {
|
||||
DataNodesetSelector string
|
||||
MetaNodesetSelector string
|
||||
NodeSet map[uint64]*NodeSetView
|
||||
MediaType string
|
||||
}
|
||||
|
||||
type NodeSetView struct {
|
||||
@ -1404,3 +1405,39 @@ func MediaTypeString(mediaType uint32) (value string) {
|
||||
}
|
||||
|
||||
const ForbiddenMigrationRenewalPeriod = 2 * time.Minute
|
||||
|
||||
func IsValidMediaType(mediaType uint32) bool {
|
||||
if mediaType >= MediaType_SSD && mediaType <= MediaType_HDD {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
type StorageClass uint32
|
||||
|
||||
const (
|
||||
StorageClass_Unspecified uint32 = 0
|
||||
StorageClass_Replica_SSD uint32 = 1
|
||||
StorageClass_Replica_HDD uint32 = 2
|
||||
StorageClass_Blobtore uint32 = 3
|
||||
|
||||
//Types may be added later:
|
||||
//StorageClass_S3
|
||||
//StorageClass_ARCHIV
|
||||
//StorageClass_HDFS
|
||||
)
|
||||
|
||||
var storageClassStringMap = map[uint32]string{
|
||||
StorageClass_Unspecified: "Unspecified",
|
||||
StorageClass_Replica_SSD: "ReplicaSSD",
|
||||
StorageClass_Replica_HDD: "ReplicaHDD",
|
||||
}
|
||||
|
||||
func StorageClassStringMap(storageClass uint32) (value string) {
|
||||
value, ok := storageClassStringMap[storageClass]
|
||||
if !ok {
|
||||
value = "InvalidValue"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user