Example #1
0
// 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
}
Example #2
0
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
}