mirror of
https://github.com/cubefs/cubefs.git
synced 2026-08-02 02:00:56 +00:00
feat(dp): set dpCount when create volume
Signed-off-by: lily-lee <lilylee88756@gmail.com>
This commit is contained in:
parent
5a4727d7a4
commit
f45b4cd606
@ -69,6 +69,7 @@ const (
|
||||
CliFlagCapacity = "capacity"
|
||||
CliFlagBusiness = "description"
|
||||
CliFlagMPCount = "mp-count"
|
||||
CliFlagDPCount = "dp-count"
|
||||
CliFlagReplicaNum = "replica-num"
|
||||
CliFlagSize = "size"
|
||||
CliFlagVolType = "vol-type"
|
||||
|
||||
@ -87,6 +87,7 @@ const (
|
||||
cmdVolCreateUse = "create [VOLUME NAME] [USER ID]"
|
||||
cmdVolCreateShort = "Create a new volume"
|
||||
cmdVolDefaultMPCount = 3
|
||||
cmdVolDefaultDPCount = 10
|
||||
cmdVolDefaultDPSize = 120
|
||||
cmdVolDefaultCapacity = 10 // 100GB
|
||||
cmdVolDefaultZoneName = ""
|
||||
@ -111,6 +112,7 @@ func newVolCreateCmd(client *master.MasterClient) *cobra.Command {
|
||||
var optNormalZonesFirst string
|
||||
var optBusiness string
|
||||
var optMPCount int
|
||||
var optDPCount int
|
||||
var optReplicaNum string
|
||||
var optDPSize int
|
||||
var optVolType int
|
||||
@ -176,6 +178,7 @@ func newVolCreateCmd(client *master.MasterClient) *cobra.Command {
|
||||
stdout(" DefaultPriority : %v\n", normalZonesFirst)
|
||||
stdout(" description : %v\n", optBusiness)
|
||||
stdout(" mpCount : %v\n", optMPCount)
|
||||
stdout(" dpCount : %v\n", optDPCount)
|
||||
stdout(" replicaNum : %v\n", optReplicaNum)
|
||||
stdout(" dpSize : %v G\n", optDPSize)
|
||||
stdout(" volType : %v\n", optVolType)
|
||||
@ -206,7 +209,7 @@ func newVolCreateCmd(client *master.MasterClient) *cobra.Command {
|
||||
|
||||
err = client.AdminAPI().CreateVolName(
|
||||
volumeName, userID, optCapacity, optDeleteLockTime, crossZone, normalZonesFirst, optBusiness,
|
||||
optMPCount, int(replicaNum), optDPSize, optVolType, followerRead,
|
||||
optMPCount, optDPCount, int(replicaNum), optDPSize, optVolType, followerRead,
|
||||
optZoneName, optCacheRuleKey, optEbsBlkSize, optCacheCap,
|
||||
optCacheAction, optCacheThreshold, optCacheTTL, optCacheHighWater,
|
||||
optCacheLowWater, optCacheLRUInterval, dpReadOnlyWhenVolFull,
|
||||
@ -223,6 +226,7 @@ func newVolCreateCmd(client *master.MasterClient) *cobra.Command {
|
||||
cmd.Flags().StringVar(&optNormalZonesFirst, CliNormalZonesFirst, cmdVolDefaultCrossZone, "Write to normal zone first")
|
||||
cmd.Flags().StringVar(&optBusiness, CliFlagBusiness, cmdVolDefaultBusiness, "Description")
|
||||
cmd.Flags().IntVar(&optMPCount, CliFlagMPCount, cmdVolDefaultMPCount, "Specify init meta partition count")
|
||||
cmd.Flags().IntVar(&optDPCount, CliFlagDPCount, cmdVolDefaultDPCount, "Specify init data partition count")
|
||||
cmd.Flags().StringVar(&optReplicaNum, CliFlagReplicaNum, "", "Specify data partition replicas number(default 3 for normal volume,1 for low volume)")
|
||||
cmd.Flags().IntVar(&optDPSize, CliFlagDataPartitionSize, cmdVolDefaultDPSize, "Specify data partition size[Unit: GB]")
|
||||
cmd.Flags().IntVar(&optVolType, CliFlagVolType, cmdVolDefaultVolType, "Type of volume (default 0)")
|
||||
|
||||
@ -24,6 +24,7 @@ CubeFS以 **Owner**参数作为用户ID。
|
||||
| capacity | int | 卷的配额,单位是GB | 是 | 无 |
|
||||
| owner | string | 卷的所有者,同时也是用户ID | 是 | 无 |
|
||||
| mpCount | int | 初始化元数据分片个数 | 否 | 3 |
|
||||
| dpCount | int | 初始化数据分片个数 | 否 | 默认10, 最大值200 |
|
||||
| replicaNum | int | 副本数 | 否 | 副本卷默认3(支持1,3),纠删码卷默认1(支持1-16个) |
|
||||
| dpSize | int | 数据分片大小上限,单位GB | 否 | 120 |
|
||||
| enablePosixAcl | bool | 是否配置posix权限限制 | 否 | false |
|
||||
|
||||
@ -23,8 +23,9 @@ Parameter List
|
||||
| capacity | int | Volume quota, in GB | Yes | None |
|
||||
| owner | string | Volume owner, also the user ID | Yes | None |
|
||||
| mpCount | int | Number of initialized metadata shards | No | 3 |
|
||||
| dpCount | int | Number of initialized data shards | No | default 10, maximum limit 200 |
|
||||
| replicaNum | int | Number of replicas | No | 3 for replica volume (supports 1, 3), 1 for erasure-coded volume (supports 1-16) |
|
||||
| dpSize | int | Maximum data shard size, in GB | No | 120 |
|
||||
| dpSize | int | Maximum data shard size, in GB | No | 120 |
|
||||
| enablePosixAcl | bool | Whether to configure POSIX permission restrictions | No | false |
|
||||
| followerRead | bool | Whether to allow reading data from followers, true by default for erasure-coded volume | No | false |
|
||||
| crossZone | bool | Whether to cross regions. If set to true, the zoneName parameter cannot be set | No | false |
|
||||
@ -56,7 +57,7 @@ When deleting a volume, all permission information related to the volume will be
|
||||
|
||||
Parameter List
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| Parameter | Type | Description |
|
||||
|-----------|--------|----------------------------------------------------------------------------------------|
|
||||
| name | string | Volume name |
|
||||
| authKey | string | Calculate the 32-bit MD5 value of the owner field of vol as authentication information |
|
||||
@ -325,9 +326,9 @@ Enable/Disable trash feature for the specified volume.
|
||||
|
||||
Parameter List
|
||||
|
||||
| Parameter | Type | Description | Required |
|
||||
|----------|--------|---------------------------|-----|
|
||||
| name | string | Volume name | Yes |
|
||||
| Parameter | Type | Description | Required |
|
||||
|-----------|--------|----------------------------------------------------------------------------------------|----------|
|
||||
| name | string | Volume name | Yes |
|
||||
| authKey | string | Calculate the 32-bit MD5 value of the owner field of vol as authentication information | Yes |
|
||||
| trashInterval | int | The time interval for cleaning expired data in the trash is specified in minutes. A value of 0 indicates that the trash is disabled, while any other positive value indicates that the trash is enabled. | Yes
|
||||
|
||||
|
||||
@ -654,6 +654,7 @@ type createVolReq struct {
|
||||
owner string
|
||||
dpSize int
|
||||
mpCount int
|
||||
dpCount int
|
||||
dpReplicaNum uint8
|
||||
capacity int
|
||||
deleteLockTime int64
|
||||
@ -747,6 +748,10 @@ func parseRequestToCreateVol(r *http.Request, req *createVolReq) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
if req.dpCount, err = extractUintWithDefault(r, dataPartitionCountKey, defaultInitDataPartitionCnt); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var parsedDpReplicaNum int
|
||||
if parsedDpReplicaNum, err = extractUint(r, replicaNumKey); err != nil {
|
||||
return
|
||||
|
||||
@ -2228,6 +2228,10 @@ func (m *Server) checkCreateReq(req *createVolReq) (err error) {
|
||||
return fmt.Errorf("datapartition dpSize must be bigger than 10 G")
|
||||
}
|
||||
|
||||
if req.dpCount > maxInitDataPartitionCnt {
|
||||
return fmt.Errorf("dpCount[%d] exceeds maximum limit[%d]", req.dpCount, maxInitDataPartitionCnt)
|
||||
}
|
||||
|
||||
if proto.IsHot(req.volType) {
|
||||
if req.dpReplicaNum == 0 {
|
||||
req.dpReplicaNum = defaultReplicaNum
|
||||
|
||||
@ -1491,7 +1491,6 @@ func (c *Cluster) createDataPartition(volName string, preload *DataPartitionPreL
|
||||
if partitionID, err = c.idAlloc.allocateDataPartitionID(); err != nil {
|
||||
goto errHandler
|
||||
}
|
||||
|
||||
dp = newDataPartition(partitionID, dpReplicaNum, volName, vol.ID, proto.GetDpType(vol.VolType, isPreload), partitionTTL)
|
||||
dp.Hosts = targetHosts
|
||||
dp.Peers = targetPeers
|
||||
@ -3186,8 +3185,13 @@ func (c *Cluster) createVol(req *createVolReq) (vol *Vol, err error) {
|
||||
}
|
||||
|
||||
if vol.CacheCapacity > 0 || (proto.IsHot(vol.VolType) && vol.Capacity > 0) {
|
||||
if req.dpCount > maxInitDataPartitionCnt {
|
||||
err = fmt.Errorf("action[createVol] initDataPartitions failed, vol[%v], dpCount[%d] exceeds maximum limit[%d]",
|
||||
req.name, req.dpCount, maxInitDataPartitionCnt)
|
||||
goto errHandler
|
||||
}
|
||||
for retryCount := 0; readWriteDataPartitions < defaultInitMetaPartitionCount && retryCount < 3; retryCount++ {
|
||||
err = vol.initDataPartitions(c)
|
||||
err = vol.initDataPartitions(c, req.dpCount)
|
||||
if err != nil {
|
||||
log.LogError("action[createVol] init dataPartition error ",
|
||||
err.Error(), retryCount, len(vol.dataPartitions.partitionMap))
|
||||
|
||||
@ -362,3 +362,56 @@ func TestBalanceMetaPartition(t *testing.T) {
|
||||
|
||||
sortNodes.balanceLeader()
|
||||
}
|
||||
|
||||
func TestCreateVolWithDpCount(t *testing.T) {
|
||||
// create volume and metaNode will create mp,sleep some time to wait cluster get latest meteNode info
|
||||
// cluster normal volume has 3 mps , total 3*3 =9 mp in metaNode
|
||||
|
||||
t.Run("dpCount != default count", func(t *testing.T) {
|
||||
req := &createVolReq{
|
||||
name: commonVolName + "001",
|
||||
owner: "cfs",
|
||||
dpSize: 3,
|
||||
mpCount: 30,
|
||||
dpCount: 30,
|
||||
dpReplicaNum: 3,
|
||||
capacity: 100,
|
||||
followerRead: false,
|
||||
authenticate: false,
|
||||
crossZone: true,
|
||||
normalZonesFirst: false,
|
||||
zoneName: testZone1 + "," + testZone2,
|
||||
description: "",
|
||||
qosLimitArgs: &qosArgs{},
|
||||
}
|
||||
_, err := server.cluster.createVol(req)
|
||||
require.NoError(t, err)
|
||||
|
||||
vol, err := server.cluster.getVol(req.name)
|
||||
require.NoError(t, err)
|
||||
|
||||
dpCount := len(vol.dataPartitions.partitions)
|
||||
require.Equal(t, req.dpCount, dpCount)
|
||||
})
|
||||
|
||||
t.Run("dpCount > max count", func(t *testing.T) {
|
||||
req := &createVolReq{
|
||||
name: commonVolName + "002",
|
||||
owner: "cfs",
|
||||
dpSize: 3,
|
||||
mpCount: 30,
|
||||
dpCount: 300,
|
||||
dpReplicaNum: 3,
|
||||
capacity: 100,
|
||||
followerRead: false,
|
||||
authenticate: false,
|
||||
crossZone: true,
|
||||
normalZonesFirst: false,
|
||||
zoneName: testZone1 + "," + testZone2,
|
||||
description: "",
|
||||
qosLimitArgs: &qosArgs{},
|
||||
}
|
||||
_, err := server.cluster.createVol(req)
|
||||
require.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
@ -35,6 +35,7 @@ const (
|
||||
dirLimitKey = "dirSizeLimit"
|
||||
dataPartitionSizeKey = "dpSize"
|
||||
metaPartitionCountKey = "mpCount"
|
||||
dataPartitionCountKey = "dpCount"
|
||||
volCapacityKey = "capacity"
|
||||
volDeleteLockTimeKey = "deleteLockTime"
|
||||
volTypeKey = "volType"
|
||||
@ -182,6 +183,7 @@ const (
|
||||
intervalToWarnDataPartition = 600
|
||||
intervalToLoadDataPartition = 12 * 60 * 60
|
||||
defaultInitDataPartitionCnt = 10
|
||||
maxInitDataPartitionCnt = 200
|
||||
volExpansionRatio = 0.1
|
||||
maxNumberOfDataPartitionsForExpansion = 100
|
||||
EmptyCrcValue uint32 = 4045511210
|
||||
|
||||
@ -174,10 +174,10 @@ func (s *VolumeService) volPermission(ctx context.Context, args struct {
|
||||
}
|
||||
|
||||
func (s *VolumeService) createVolume(ctx context.Context, args struct {
|
||||
Name, Owner, ZoneName, Description string
|
||||
Capacity, DataPartitionSize, MpCount, DpReplicaNum uint64
|
||||
FollowerRead, Authenticate, CrossZone, DefaultPriority bool
|
||||
iopsRLimit, iopsWLimit, flowRlimit, flowWlimit uint64
|
||||
Name, Owner, ZoneName, Description string
|
||||
Capacity, DataPartitionSize, MpCount, DpCount, DpReplicaNum uint64
|
||||
FollowerRead, Authenticate, CrossZone, DefaultPriority bool
|
||||
iopsRLimit, iopsWLimit, flowRlimit, flowWlimit uint64
|
||||
}) (*Vol, error) {
|
||||
uid, per, err := permissions(ctx, ADMIN|USER)
|
||||
if err != nil {
|
||||
@ -196,11 +196,16 @@ func (s *VolumeService) createVolume(ctx context.Context, args struct {
|
||||
return nil, fmt.Errorf("invalid arg dpReplicaNum: %v", args.DpReplicaNum)
|
||||
}
|
||||
|
||||
if args.DpCount > maxInitDataPartitionCnt {
|
||||
return nil, fmt.Errorf("invalid arg dpCount[%v], exceeds maximum limit[%d]", args.DpCount, maxInitDataPartitionCnt)
|
||||
}
|
||||
|
||||
req := &createVolReq{
|
||||
name: args.Name,
|
||||
owner: args.Owner,
|
||||
dpSize: int(args.DataPartitionSize),
|
||||
mpCount: int(args.MpCount),
|
||||
dpCount: int(args.DpCount),
|
||||
dpReplicaNum: uint8(args.DpReplicaNum),
|
||||
capacity: int(args.Capacity),
|
||||
followerRead: args.FollowerRead,
|
||||
|
||||
@ -494,9 +494,12 @@ func (vol *Vol) initMetaPartitions(c *Cluster, count int) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (vol *Vol) initDataPartitions(c *Cluster) (err error) {
|
||||
func (vol *Vol) initDataPartitions(c *Cluster, dpCount int) (err error) {
|
||||
if dpCount == 0 {
|
||||
dpCount = defaultInitDataPartitionCnt
|
||||
}
|
||||
// initialize k data partitionMap at a time
|
||||
err = c.batchCreateDataPartition(vol, defaultInitDataPartitionCnt, true)
|
||||
err = c.batchCreateDataPartition(vol, dpCount, true)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -74,10 +74,10 @@ type SimpleVolView struct {
|
||||
}
|
||||
|
||||
//function begin .....
|
||||
func (c *VolumeClient) CreateVolume(ctx context.Context, authenticate bool, capacity uint64, crossZone bool, dataPartitionSize uint64, description string, dpReplicaNum uint64, enableToken bool, followerRead bool, mpCount uint64, name string, owner string, zoneName string) (*Vol, error) {
|
||||
func (c *VolumeClient) CreateVolume(ctx context.Context, authenticate bool, capacity uint64, crossZone bool, dataPartitionSize uint64, description string, dpReplicaNum uint64, enableToken bool, followerRead bool, mpCount uint64, dpCount uint64, name string, owner string, zoneName string) (*Vol, error) {
|
||||
|
||||
req := client.NewRequest(ctx, `mutation($authenticate: bool, $capacity: uint64, $crossZone: bool, $dataPartitionSize: uint64, $description: string, $dpReplicaNum: uint64, $enableToken: bool, $followerRead: bool, $mpCount: uint64, $name: string, $owner: string, $zoneName: string){
|
||||
createVolume(authenticate: $authenticate, capacity: $capacity, crossZone: $crossZone, dataPartitionSize: $dataPartitionSize, description: $description, dpReplicaNum: $dpReplicaNum, enableToken: $enableToken, followerRead: $followerRead, mpCount: $mpCount, name: $name, owner: $owner, zoneName: $zoneName){
|
||||
req := client.NewRequest(ctx, `mutation($authenticate: bool, $capacity: uint64, $crossZone: bool, $dataPartitionSize: uint64, $description: string, $dpReplicaNum: uint64, $enableToken: bool, $followerRead: bool, $mpCount: uint64, $dpCount: uint64, $name: string, $owner: string, $zoneName: string){
|
||||
createVolume(authenticate: $authenticate, capacity: $capacity, crossZone: $crossZone, dataPartitionSize: $dataPartitionSize, description: $description, dpReplicaNum: $dpReplicaNum, enableToken: $enableToken, followerRead: $followerRead, mpCount: $mpCount, dpCount: $dpCount, name: $name, owner: $owner, zoneName: $zoneName){
|
||||
capacity
|
||||
createTime
|
||||
dpReplicaNum
|
||||
@ -130,6 +130,7 @@ func (c *VolumeClient) CreateVolume(ctx context.Context, authenticate bool, capa
|
||||
req.Var("enableToken", enableToken)
|
||||
req.Var("followerRead", followerRead)
|
||||
req.Var("mpCount", mpCount)
|
||||
req.Var("dpCount", dpCount)
|
||||
req.Var("name", name)
|
||||
req.Var("owner", owner)
|
||||
req.Var("zoneName", zoneName)
|
||||
|
||||
@ -429,7 +429,7 @@ func (api *AdminAPI) VolExpand(volName string, capacity uint64, authKey, clientI
|
||||
}
|
||||
|
||||
func (api *AdminAPI) CreateVolName(volName, owner string, capacity uint64, deleteLockTime int64, crossZone, normalZonesFirst bool, business string,
|
||||
mpCount, replicaNum, dpSize, volType int, followerRead bool, zoneName, cacheRuleKey string, ebsBlkSize,
|
||||
mpCount, dpCount, replicaNum, dpSize, volType int, followerRead bool, zoneName, cacheRuleKey string, ebsBlkSize,
|
||||
cacheCapacity, cacheAction, cacheThreshold, cacheTTL, cacheHighWater, cacheLowWater, cacheLRUInterval int,
|
||||
dpReadOnlyWhenVolFull bool, txMask string, txTimeout uint32, txConflictRetryNum int64, txConflictRetryInterval int64, optEnableQuota string,
|
||||
clientIDKey string) (err error) {
|
||||
@ -442,6 +442,7 @@ func (api *AdminAPI) CreateVolName(volName, owner string, capacity uint64, delet
|
||||
request.addParam("normalZonesFirst", strconv.FormatBool(normalZonesFirst))
|
||||
request.addParam("description", business)
|
||||
request.addParam("mpCount", strconv.Itoa(mpCount))
|
||||
request.addParam("dpCount", strconv.Itoa(dpCount))
|
||||
request.addParam("replicaNum", strconv.Itoa(replicaNum))
|
||||
request.addParam("dpSize", strconv.Itoa(dpSize))
|
||||
request.addParam("volType", strconv.Itoa(volType))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user