// RULES FOR DERIVING THE PG NUM // if no of osds <= 5 then // no of PGs = 128 // if no of osds > 5 and <= 10 then // no of PGs = 512 // if no of osds > 10 and <= 50 then // no of PGs = 4096 // if no of osds > 50 then // no of PGs = (Avg Target PGs per OSD * No of OSDs * Data Percentage) / Replica Count // -- where // Data Percentage = Target Allocation Size / Max Allocation Size // -- where // Target Allocation Size - provided in request // Max Allocation Size = ((Average OSD Size * No of OSDs) / Replica Count) * Max Utilization Factor // -- where Max Utilization Factor is set as 0.8 // Finally round this value of next 2's power func DerivePgNum(clusterId uuid.UUID, size string, replicaCount int, profile string) uint { // Get the no of OSDs in the cluster sessionCopy := db.GetDatastore().Copy() defer sessionCopy.Close() coll := sessionCopy.DB(conf.SystemConfig.DBConfig.Database).C(models.COLL_NAME_STORAGE_LOGICAL_UNITS) var slus []models.StorageLogicalUnit if err := coll.Find(bson.M{"clusterid": clusterId, "type": models.CEPH_OSD, "storageprofile": profile}).All(&slus); err != nil { return uint(DEFAULT_PG_NUM) } osdsNum := len(slus) // Calculate the pgnum value if osdsNum <= 5 { return uint(DEFAULT_PG_NUM) } if osdsNum <= 10 { return uint(512) } if osdsNum <= 50 { return uint(4096) } avgOsdSize := avg_osd_size(slus) / 1024 maxAllocSize := (avgOsdSize * float64(len(slus)) / float64(replicaCount)) * float64(MAX_UTILIZATION_PCNT) / 100 pcntData := float64(utils.SizeFromStr(size)) / float64(maxAllocSize) pgnum := float64(float64(TARGET_PGS_PER_OSD)*float64(len(slus))*pcntData) / float64(replicaCount) derivedPgNum := utils.NextTwosPower(uint(pgnum)) if derivedPgNum < uint(osdsNum) { // Consider next 2's power value newPgNum := osdsNum / replicaCount derivedPgNum = utils.NextTwosPower(uint(newPgNum)) } return derivedPgNum }
func (s *CephProvider) GetDiskHierarchy(req models.RpcRequest, resp *models.RpcResponse) error { var request models.DiskHierarchyRequest ctxt := req.RpcRequestContext if err := json.Unmarshal(req.RpcRequestData, &request); err != nil { logger.Get().Error(fmt.Sprintf("%s-Unbale to parse the disk hierarchy request. error: %v", ctxt, err)) *resp = utils.WriteResponse(http.StatusBadRequest, fmt.Sprintf("Unbale to parse the request. error: %v", err)) return err } if request.JournalSize == "" { request.JournalSize = fmt.Sprintf("%dMB", JOURNALSIZE) } nodes, err := util.GetNodes(request.ClusterNodes) if err != nil { logger.Get().Error( "%s-Error getting nodes list from DB for cluster %s. error: %v", ctxt, request.ClusterName, err) return err } hierarchy := make(map[string]map[string]string) var storageSize float64 for _, requestNode := range request.ClusterNodes { disksMap := make(map[string]string) uuid, err := uuid.Parse(requestNode.NodeId) if err != nil { logger.Get().Error( "%s-Error parsing node id: %s for cluster: %s. error: %v", ctxt, requestNode.NodeId, request.ClusterName, err) continue } devices := make(map[string]models.Disk) storageNode := nodes[*uuid] // Form a map of storage node disks var nodeDisksMap map[string]models.Disk = make(map[string]models.Disk) for _, storageDisk := range storageNode.StorageDisks { nodeDisksMap[storageDisk.Name] = storageDisk } for diskName, storageDisk := range nodeDisksMap { for idx := 0; idx < len(requestNode.Devices); idx++ { if diskName == requestNode.Devices[idx].Name { devices[requestNode.Devices[idx].Name] = storageDisk } } } // Utility function returns value in MB so multiply by 1024 to make is bytes jSize := utils.SizeFromStr(request.JournalSize) * float64(1024) diskWithJournalMapped := getDiskWithJournalMapped(devices, jSize) for disk, journal := range diskWithJournalMapped { disksMap[disk] = journal.JournalDisk for _, storageDisk := range storageNode.StorageDisks { if storageDisk.Name == disk { storageSize += storageDisk.Size } } } hierarchy[requestNode.NodeId] = disksMap } retVal := models.DiskHierarchyDetails{ ClusterName: request.ClusterName, Hierarchy: hierarchy, StorageSize: storageSize, } result, err := json.Marshal(retVal) if err != nil { logger.Get().Error( "%s-Error forming the output for get disk hierarchy of cluster: %s. error: %v", ctxt, request.ClusterName, err) *resp = utils.WriteResponse( http.StatusInternalServerError, fmt.Sprintf( "Error forming the output. error: %v", err)) return err } *resp = utils.WriteResponseWithData(http.StatusOK, "", result) return nil }