mirror of
https://github.com/cubefs/cubefs.git
synced 2026-08-02 02:00:56 +00:00
feat(master): hybrid cloud support cross zone when creating volume
Signed-off-by: true1064 <tangjingyu@oppo.com>
This commit is contained in:
parent
3b9ef65dbe
commit
d7503fb7b5
@ -1553,7 +1553,7 @@ func (m *Server) createDataPartition(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
lastTotalDataPartitions = len(vol.dataPartitions.partitions)
|
||||
clusterTotalDataPartitions = m.cluster.getDataPartitionCount()
|
||||
// TODO:tangjingyu need to support requester to specify volStorageClass?
|
||||
// TODO:tangjingyu to support assign mediaType
|
||||
err = m.cluster.batchCreateDataPartition(vol, reqCreateCount, false, proto.GetMediaTypeByStorageClass(vol.volStorageClass))
|
||||
rstMsg = fmt.Sprintf(" createDataPartition succeeeds. "+
|
||||
"clusterLastTotalDataPartitions[%v],vol[%v] has %v data partitions previously and %v data partitions now",
|
||||
|
||||
@ -2043,7 +2043,7 @@ func (c *Cluster) getSpecificZoneList(specifiedZone string) (zones []*Zone, err
|
||||
|
||||
func (c *Cluster) getHostFromNormalZone(nodeType uint32, excludeZones []string, excludeNodeSets []uint64,
|
||||
excludeHosts []string, replicaNum int, zoneNumNeed int,
|
||||
specifiedZoneName string, mediaType uint32) (hosts []string, peers []proto.Peer, err error,
|
||||
specifiedZoneName string, dataMediaType uint32) (hosts []string, peers []proto.Peer, err error,
|
||||
) {
|
||||
var zonesQualified []*Zone
|
||||
if replicaNum <= zoneNumNeed {
|
||||
@ -2053,7 +2053,6 @@ func (c *Cluster) getHostFromNormalZone(nodeType uint32, excludeZones []string,
|
||||
var specifiedZones []*Zone
|
||||
var rsMgr *rsManager
|
||||
if specifiedZoneName != "" {
|
||||
// TODO:tangjngyu mediaType
|
||||
if specifiedZones, err = c.getSpecificZoneList(specifiedZoneName); err != nil {
|
||||
return
|
||||
}
|
||||
@ -2065,7 +2064,7 @@ func (c *Cluster) getHostFromNormalZone(nodeType uint32, excludeZones []string,
|
||||
}
|
||||
|
||||
// get all zones that qualified
|
||||
if zonesQualified, err = c.t.allocZonesForNode(rsMgr, zoneNumNeed, replicaNum, excludeZones, specifiedZones, mediaType); err != nil {
|
||||
if zonesQualified, err = c.t.allocZonesForNode(rsMgr, zoneNumNeed, replicaNum, excludeZones, specifiedZones, dataMediaType); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -389,23 +389,21 @@ func TestCreateVolWithDpCount(t *testing.T) {
|
||||
|
||||
t.Run("dpCount != default count", func(t *testing.T) {
|
||||
req := &createVolReq{
|
||||
name: commonVolName + "001",
|
||||
owner: "cfs",
|
||||
dpSize: 11,
|
||||
mpCount: 30,
|
||||
dpCount: 30,
|
||||
dpReplicaNum: 3,
|
||||
capacity: 100,
|
||||
followerRead: false,
|
||||
authenticate: false,
|
||||
// crossZone: true, //TODO: tangjingyu: hybrid cloud support crossZone
|
||||
crossZone: false,
|
||||
name: commonVolName + "001",
|
||||
owner: "cfs",
|
||||
dpSize: 11,
|
||||
mpCount: 30,
|
||||
dpCount: 30,
|
||||
dpReplicaNum: 3,
|
||||
capacity: 100,
|
||||
followerRead: false,
|
||||
authenticate: false,
|
||||
crossZone: true,
|
||||
normalZonesFirst: false,
|
||||
// zoneName: testZone1 + "," + testZone2, //TODO: tangjingyu: hybrid cloud support crossZone
|
||||
zoneName: testZone2,
|
||||
description: "",
|
||||
qosLimitArgs: &qosArgs{},
|
||||
volStorageClass: defaultVolStorageClass,
|
||||
zoneName: testZone1 + "," + testZone2,
|
||||
description: "",
|
||||
qosLimitArgs: &qosArgs{},
|
||||
volStorageClass: defaultVolStorageClass,
|
||||
}
|
||||
|
||||
// auto set allowedStorageClass[] in createVolReq
|
||||
|
||||
@ -1379,6 +1379,24 @@ func calculateDemandWriteNodes(zoneNum int, replicaNum int, isSpecialZoneName bo
|
||||
return
|
||||
}
|
||||
|
||||
func (t *topology) pickUpZonesByMediaType(zones []*Zone, dataMediaType uint32) (zonesOfMediaType []*Zone) {
|
||||
if dataMediaType == proto.MediaType_Unspecified {
|
||||
log.LogDebugf("[pickUpZonesByMediaType] not require dataMediaType, zoneLen(%v)", len(zones))
|
||||
zonesOfMediaType = zones
|
||||
return
|
||||
}
|
||||
|
||||
zonesOfMediaType = make([]*Zone, 0)
|
||||
for _, zone := range zones {
|
||||
if zone.dataMediaType == dataMediaType {
|
||||
log.LogDebugf("[pickUpZonesByMediaType] pick up zone(%v), dataMediaType(%v)", zone.name, dataMediaType)
|
||||
zonesOfMediaType = append(zonesOfMediaType, zone)
|
||||
}
|
||||
}
|
||||
|
||||
return zonesOfMediaType
|
||||
}
|
||||
|
||||
// Choose the zone if it is writable and adapt to the rules for classifying zones
|
||||
func (t *topology) allocZonesForNode(rsMgr *rsManager, zoneNumNeed, replicaNum int, excludeZone []string,
|
||||
specialZones []*Zone, dataMediaType uint32) (zones []*Zone, err error) {
|
||||
@ -1389,8 +1407,7 @@ func (t *topology) allocZonesForNode(rsMgr *rsManager, zoneNumNeed, replicaNum i
|
||||
zones = t.getDomainExcludeZones()
|
||||
log.LogInfof("action[allocZonesForNode] getDomainExcludeZones zones [%v]", t.domainExcludeZones)
|
||||
} else if specialZones != nil && len(specialZones) > 0 {
|
||||
// TODO:tangjingyu: mediaType
|
||||
zones = specialZones
|
||||
zones = t.pickUpZonesByMediaType(specialZones, dataMediaType)
|
||||
zoneNumNeed = len(specialZones)
|
||||
} else {
|
||||
// if domain enable, will not enter here
|
||||
@ -1421,9 +1438,15 @@ func (t *topology) allocZonesForNode(rsMgr *rsManager, zoneNumNeed, replicaNum i
|
||||
|
||||
// if across zone,candidateZones must be larger than or equal with 2,otherwise,must have a candidate zone
|
||||
if (zoneNumNeed >= 2 && len(candidateZones) < 2) || len(candidateZones) < 1 {
|
||||
log.LogError(fmt.Sprintf("action[allocZonesForNode],reqZoneNum[%v],candidateZones[%v],demandWriteNodes[%v],err:%v",
|
||||
zoneNumNeed, len(candidateZones), demandWriteNodesCntPerZone, proto.ErrNoZoneToCreateMetaPartition))
|
||||
return nil, proto.ErrNoZoneToCreateMetaPartition
|
||||
if rsMgr.nodeType == DataNodeType {
|
||||
err = proto.ErrNoZoneToCreateDataPartition
|
||||
} else {
|
||||
err = proto.ErrNoZoneToCreateMetaPartition
|
||||
}
|
||||
|
||||
log.LogErrorf("action[allocZonesForNode],reqZoneNum[%v],candidateZones[%v],demandWriteNodes[%v],err:%v",
|
||||
zoneNumNeed, len(candidateZones), demandWriteNodesCntPerZone, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
zones = candidateZones
|
||||
err = nil
|
||||
@ -1854,7 +1877,6 @@ func (zone *Zone) getDataNodeMaxTotal() (maxTotal uint64) {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO:tangjingyu mediaType
|
||||
func (zone *Zone) getAvailNodeHosts(nodeType uint32, excludeNodeSets []uint64, excludeHosts []string, replicaNum int) (newHosts []string, peers []proto.Peer, err error) {
|
||||
if replicaNum == 0 {
|
||||
return
|
||||
|
||||
Loading…
Reference in New Issue
Block a user