mirror of
https://github.com/cubefs/cubefs.git
synced 2026-08-02 02:00:56 +00:00
feat(flashnode): make slot with user defined
. #22200518 Signed-off-by: slasher <mcq.sejust@gmail.com>
This commit is contained in:
parent
d30f8cae5b
commit
44e56bb610
@ -61,6 +61,10 @@ func newCmdFlashGroupCreate(client *master.MasterClient) *cobra.Command {
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var err error
|
||||
defer func() { errout(err) }()
|
||||
if optSlots == "" {
|
||||
err = fmt.Errorf("pls set --slots")
|
||||
return
|
||||
}
|
||||
fgView, err := client.AdminAPI().CreateFlashGroup(optSlots)
|
||||
if err != nil {
|
||||
return
|
||||
@ -339,6 +343,7 @@ func newCmdFlashGroupSearch(client *master.MasterClient) *cobra.Command {
|
||||
return
|
||||
}
|
||||
}
|
||||
stdoutlnf("Not found (%s %d %d) -> %d", volume, inode, offset, slotKey)
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -378,13 +383,19 @@ func newCmdFlashGroupGraph(client *master.MasterClient) *cobra.Command {
|
||||
return slots[i].slot < slots[j].slot
|
||||
})
|
||||
|
||||
const _fgView = "%-10v %-10v %-18v %-6v %-6v"
|
||||
stdoutln("[Flash Groups]")
|
||||
stdoutlnf(_fgView, "SLOT", "ID", "STATUS", "Count", "Ref")
|
||||
for _, slot := range slots {
|
||||
tbl := table{arow("Slot", "ID", "Status", "Count", "Ref", "Proportion")}
|
||||
for idx, slot := range slots {
|
||||
g := groups[slot.fgID]
|
||||
stdoutlnf(_fgView, slot.slot, g.ID, g.Status.String(), g.FlashNodeCount, groupn[g.ID])
|
||||
var p string
|
||||
if idx == len(slots)-1 {
|
||||
p = proportion(slot.slot, math.MaxUint32)
|
||||
} else {
|
||||
p = proportion(slot.slot, slots[idx+1].slot)
|
||||
}
|
||||
tbl = tbl.append(arow(slot.slot, g.ID, g.Status.String(), g.FlashNodeCount, groupn[g.ID], p))
|
||||
}
|
||||
stdoutln(alignTable(tbl...))
|
||||
|
||||
fnView, err := client.AdminAPI().ListFlashNodes(true)
|
||||
if err != nil {
|
||||
@ -402,7 +413,7 @@ func newCmdFlashGroupGraph(client *master.MasterClient) *cobra.Command {
|
||||
}
|
||||
}
|
||||
stdoutln("[FlashNodes Busy]")
|
||||
tbl := showFlashNodesView(busyNodes, true, table{formatFlashNodeViewTableTitle})
|
||||
tbl = showFlashNodesView(busyNodes, true, table{formatFlashNodeViewTableTitle})
|
||||
stdoutln(alignTable(tbl...))
|
||||
stdoutln("[FlashNodes Idle]")
|
||||
tbl = showFlashNodesView(idleNodes, true, table{formatFlashNodeViewTableTitle})
|
||||
@ -414,3 +425,13 @@ func newCmdFlashGroupGraph(client *master.MasterClient) *cobra.Command {
|
||||
func parseFlashGroupID(id string) (uint64, error) {
|
||||
return strconv.ParseUint(id, 10, 64)
|
||||
}
|
||||
|
||||
const fullDot = ".................................................."
|
||||
|
||||
func proportion(s, e uint32) string {
|
||||
p := "."
|
||||
if n := int(float64(e-s) * float64(len(fullDot)) / float64(math.MaxUint32)); n > 0 {
|
||||
p = fullDot[:n]
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/cubefs/cubefs/proto"
|
||||
"github.com/cubefs/cubefs/sdk/httpclient"
|
||||
@ -130,7 +131,7 @@ func showFlashNodesView(flashNodeViewInfos []*proto.FlashNodeViewInfo, showStat
|
||||
|
||||
hitRate, evicts, limit := "N/A", "N/A", "N/A"
|
||||
if fn.IsActive && fn.IsEnable {
|
||||
if stat, e := client.WithAddr(fn.Addr).FlashNode().Stat(); e == nil {
|
||||
if stat, e := client.WithAddr(addr2Prof(fn.Addr)).FlashNode().Stat(); e == nil {
|
||||
hitRate = fmt.Sprintf("%.2f%%", stat.CacheStatus.HitRate*100)
|
||||
evicts = strconv.Itoa(stat.CacheStatus.Evicts)
|
||||
limit = strconv.FormatUint(stat.NodeLimit, 10)
|
||||
@ -143,3 +144,10 @@ func showFlashNodesView(flashNodeViewInfos []*proto.FlashNodeViewInfo, showStat
|
||||
}
|
||||
return tbl
|
||||
}
|
||||
|
||||
// TODO: mandatory design prof http port is service port+1
|
||||
func addr2Prof(addr string) string {
|
||||
arr := strings.SplitN(addr, ":", 2)
|
||||
p, _ := strconv.ParseUint(arr[1], 10, 64)
|
||||
return fmt.Sprintf("%s:%d", arr[0], p+1)
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ func (f *FlashNode) handleEvictVolume(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
volume := r.FormValue("volume")
|
||||
if volume == "" {
|
||||
replyErr(w, r, http.StatusBadRequest, "volume name can not be empty", nil)
|
||||
replyErr(w, r, proto.ErrCodeParamError, "volume name can not be empty", nil)
|
||||
return
|
||||
}
|
||||
replyOK(w, r, f.cacheEngine.EvictCacheByVolume(volume))
|
||||
@ -53,7 +53,7 @@ func (f *FlashNode) handleEvictAll(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func replyOK(w http.ResponseWriter, r *http.Request, data interface{}) {
|
||||
replyErr(w, r, http.StatusOK, "OK", data)
|
||||
replyErr(w, r, proto.ErrCodeSuccess, "OK", data)
|
||||
}
|
||||
|
||||
func replyErr(w http.ResponseWriter, r *http.Request, code int32, msg string, data interface{}) {
|
||||
|
||||
@ -246,7 +246,7 @@ const (
|
||||
dataNodesUnAvailable = 3
|
||||
|
||||
unusedFlashNodeFlashGroupID = 0
|
||||
defaultFlashGroupSlotsCount = 128
|
||||
defaultFlashGroupSlotsCount = 32
|
||||
)
|
||||
|
||||
const (
|
||||
@ -317,13 +317,6 @@ const (
|
||||
opSyncAddLcResult uint32 = 0x3a
|
||||
opSyncDeleteLcResult uint32 = 0x3b
|
||||
|
||||
opSyncAddFlashNode uint32 = 0x3A
|
||||
opSyncDeleteFlashNode uint32 = 0x3B
|
||||
opSyncUpdateFlashNode uint32 = 0x3C
|
||||
opSyncAddFlashGroup uint32 = 0x3D
|
||||
opSyncDeleteFlashGroup uint32 = 0x3E
|
||||
opSyncUpdateFlashGroup uint32 = 0x3F
|
||||
|
||||
opSyncAllocQuotaID uint32 = 0x40
|
||||
opSyncSetQuota uint32 = 0x41
|
||||
opSyncDeleteQuota uint32 = 0x42
|
||||
@ -331,6 +324,13 @@ const (
|
||||
|
||||
opSyncS3QosSet uint32 = 0x60
|
||||
opSyncS3QosDelete uint32 = 0x61
|
||||
|
||||
opSyncAddFlashNode uint32 = 0x6A
|
||||
opSyncDeleteFlashNode uint32 = 0x6B
|
||||
opSyncUpdateFlashNode uint32 = 0x6C
|
||||
opSyncAddFlashGroup uint32 = 0x6D
|
||||
opSyncDeleteFlashGroup uint32 = 0x6E
|
||||
opSyncUpdateFlashGroup uint32 = 0x6F
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@ -18,6 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/cubefs/cubefs/proto"
|
||||
@ -136,17 +137,22 @@ func (t *flashNodeTopology) deleteFlashNode(flashNode *FlashNode) {
|
||||
|
||||
// the function caller should use createFlashGroupLock
|
||||
func (t *flashNodeTopology) allocateNewSlotsForCreateFlashGroup(fgID uint64, setSlots []uint32) (slots []uint32) {
|
||||
slots = make([]uint32, 0, defaultFlashGroupSlotsCount)
|
||||
if len(setSlots) != 0 {
|
||||
slots = append(slots, setSlots...)
|
||||
slots = make([]uint32, 0, len(setSlots))
|
||||
for _, slot := range setSlots {
|
||||
if _, ok := t.slotsMap[slot]; !ok {
|
||||
slots = append(slots, slot)
|
||||
}
|
||||
}
|
||||
if len(slots) > 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for len(slots) < defaultFlashGroupSlotsCount {
|
||||
slot := allocateNewSlot()
|
||||
if _, ok := t.slotsMap[slot]; ok {
|
||||
continue
|
||||
}
|
||||
slots = append(slots, slot)
|
||||
t.slotsMap[slot] = fgID
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -161,19 +167,22 @@ func (t *flashNodeTopology) removeSlots(slots []uint32) {
|
||||
for _, slot := range slots {
|
||||
delete(t.slotsMap, slot)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (t *flashNodeTopology) createFlashGroup(fgID uint64, c *Cluster, setSlots []uint32) (flashGroup *FlashGroup, err error) {
|
||||
t.createFlashGroupLock.Lock()
|
||||
defer t.createFlashGroupLock.Unlock()
|
||||
slots := t.allocateNewSlotsForCreateFlashGroup(fgID, setSlots)
|
||||
sort.Slice(slots, func(i, j int) bool { return slots[i] < slots[j] })
|
||||
flashGroup = newFlashGroup(fgID, slots, proto.FlashGroupStatus_Inactive)
|
||||
if err = c.syncAddFlashGroup(flashGroup); err != nil {
|
||||
t.removeSlots(slots)
|
||||
return
|
||||
}
|
||||
t.flashGroupMap.Store(flashGroup.ID, flashGroup)
|
||||
for _, slot := range slots {
|
||||
t.slotsMap[slot] = flashGroup.ID
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -219,19 +228,9 @@ func (t *flashNodeTopology) getFlashGroupView() (fgv *proto.FlashGroupView) {
|
||||
Slot: fg.Slots,
|
||||
Hosts: hosts,
|
||||
})
|
||||
//for _, slot := range fg.Slots {
|
||||
// fgv.FlashGroups = append(fgv.FlashGroups, proto.FlashGroupInfo{
|
||||
// ID: fg.ID,
|
||||
// Slot: slot,
|
||||
// Hosts: hosts,
|
||||
// })
|
||||
//}
|
||||
}
|
||||
return true
|
||||
})
|
||||
//sort.Slice(fgv.FlashGroups, func(i, j int) bool {
|
||||
// return fgv.FlashGroups[i].Slot < fgv.FlashGroups[j].Slot
|
||||
//})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -155,7 +155,8 @@ func (mf *MetadataFsm) Apply(command []byte, index uint64) (resp interface{}, er
|
||||
switch cmd.Op {
|
||||
case opSyncDeleteDataNode, opSyncDeleteMetaNode, opSyncDeleteVol, opSyncDeleteDataPartition, opSyncDeleteMetaPartition,
|
||||
opSyncDeleteUserInfo, opSyncDeleteAKUser, opSyncDeleteVolUser, opSyncDeleteQuota, opSyncDeleteLcNode,
|
||||
opSyncDeleteLcConf, opSyncDeleteLcTask, opSyncDeleteLcResult, opSyncS3QosDelete, opSyncDeleteDecommissionDisk:
|
||||
opSyncDeleteLcConf, opSyncDeleteLcTask, opSyncDeleteLcResult, opSyncS3QosDelete, opSyncDeleteDecommissionDisk,
|
||||
opSyncDeleteFlashNode, opSyncDeleteFlashGroup:
|
||||
if err = mf.delKeyAndPutIndex(cmd.K, cmdMap); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ func (api *NodeAPI) AddFlashNode(serverAddr, zoneName, version string) (id uint6
|
||||
}
|
||||
|
||||
func (api *NodeAPI) SetFlashNode(addr, state string) (err error) {
|
||||
return api.mc.request(newRequest(get, proto.FlashNodeSet).Header(api.h).
|
||||
return api.mc.request(newRequest(post, proto.FlashNodeSet).Header(api.h).
|
||||
addParam("addr", addr).addParam("state", state))
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user