Browse Source

增加调度时的下载量统计

master
Sydonian 2 months ago
parent
commit
3d1047c55b
9 changed files with 103 additions and 45 deletions
  1. +26
    -0
      client/internal/services/user_space.go
  2. +11
    -7
      common/pkgs/ioswitch/plan/compile.go
  3. +39
    -28
      common/pkgs/ioswitch/plan/ops/send.go
  4. +2
    -0
      common/pkgs/ioswitch2/fromto.go
  5. +14
    -2
      common/pkgs/ioswitch2/ops2/base_store.go
  6. +2
    -2
      common/pkgs/ioswitch2/parser/gen/generator.go
  7. +3
    -1
      common/pkgs/ioswitch2/parser/parser.go
  8. +2
    -2
      common/pkgs/ioswitch2/plans/complete_multipart.go
  9. +4
    -3
      common/pkgs/ioswitchlrc/parser/generator.go

+ 26
- 0
client/internal/services/user_space.go View File

@@ -3,13 +3,16 @@ package services
import (
"context"
"fmt"
"strconv"
"time"

"github.com/samber/lo"
"gitlink.org.cn/cloudream/common/pkgs/logger"
"gitlink.org.cn/cloudream/common/utils/math2"
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch/exec"
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch/plan/ops"
jcstypes "gitlink.org.cn/cloudream/jcs-pub/common/types"
"gitlink.org.cn/cloudream/jcs-pub/common/types/datamap"
"gorm.io/gorm"

"gitlink.org.cn/cloudream/jcs-pub/client/internal/db"
@@ -277,6 +280,9 @@ func (svc *UserSpaceService) DownloadPackage(req cliapi.UserSpaceDownloadPackage
})
}

// 单独统计每一个对象的下载速度信息
ft.StatsCtx = fmt.Sprintf("%v", dIndex)

err = parser.Parse(ft, plans)
if err != nil {
return fmt.Errorf("parse plan: %w", err)
@@ -288,6 +294,7 @@ func (svc *UserSpaceService) DownloadPackage(req cliapi.UserSpaceDownloadPackage
for _, obj := range details {
svc.AccessStat.AddAccessCounter(obj.Object.ObjectID, req.PackageID, req.UserSpaceID, 1)
}

exeCtx := exec.NewExecContext()
exec.SetValueByType(exeCtx, svc.StgPool)
drv := plans.Execute(exeCtx)
@@ -296,9 +303,28 @@ func (svc *UserSpaceService) DownloadPackage(req cliapi.UserSpaceDownloadPackage
return err
}

// 统计下载速度
trans := make(map[int]int64)
elapseds := make(map[int]time.Duration)
for _, v := range ret.GetArray(ops2.BaseReadStatsStoreKey) {
v2 := v.(*ops2.BaseReadStatsValue)
svc.SpeedStats.Record(v2.Length, v2.ElapsedTime, v2.Location.IsDriver)
idx, _ := strconv.Atoi(v2.StatsCtx)
trans[idx] += v2.Length
elapseds[idx] = v2.ElapsedTime
}
for _, v := range ret.GetArray(ops.SendStreamStatsStoreKey) {
v2 := v.(*ops.SendStreamStatsValue)
idx, _ := strconv.Atoi(v2.StatsCtx)
trans[idx] += v2.Length
}
for idx, len := range trans {
svc.EvtPub.Publish(&datamap.BodyObjectAccessStats{
ObjectID: details[idx].Object.ObjectID,
RequestSize: details[idx].Object.Size,
TransferAmount: len,
ElapsedTime: elapseds[idx],
})
}

err = svc.DB.DoTx(func(tx db.SQLContext) error {


+ 11
- 7
common/pkgs/ioswitch/plan/compile.go View File

@@ -6,14 +6,18 @@ import (
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/ioswitch/plan/ops"
)

func Compile(graph *dag.Graph, planBld *exec.PlanBuilder) error {
type CompileOption struct {
StatsCtx string
}

func Compile(graph *dag.Graph, planBld *exec.PlanBuilder, opt CompileOption) error {
myGraph := &ops.GraphNodeBuilder{graph}
generateSend(myGraph)
return buildPlan(graph, planBld)
generateSend(myGraph, opt)
return buildPlan(graph, planBld, opt)
}

// 生成Send指令
func generateSend(graph *ops.GraphNodeBuilder) {
func generateSend(graph *ops.GraphNodeBuilder, opt CompileOption) {
graph.Walk(func(node dag.Node) bool {
switch node.(type) {
case *ops.SendStreamNode:
@@ -41,7 +45,7 @@ func generateSend(graph *ops.GraphNodeBuilder) {
// // 如果是要送到Driver,则只能由Driver主动去拉取
dstNode := out.Dst.Get(0)

getNode := graph.NewGetStream(node.Env().Worker)
getNode := graph.NewGetStream(node.Env().Worker, opt.StatsCtx)
getNode.Env().ToEnvDriver(true)

// // 同时需要对此变量生成HoldUntil指令,避免Plan结束时Get指令还未到达
@@ -61,7 +65,7 @@ func generateSend(graph *ops.GraphNodeBuilder) {
case dag.EnvWorker:
// 如果是要送到Agent,则可以直接发送
dstNode := out.Dst.Get(0)
n := graph.NewSendStream(to.Env().Worker)
n := graph.NewSendStream(to.Env().Worker, opt.StatsCtx)
*n.Env() = *node.Env()

out.Dst.RemoveAt(0)
@@ -119,7 +123,7 @@ func generateSend(graph *ops.GraphNodeBuilder) {
}

// 生成Plan
func buildPlan(graph *dag.Graph, blder *exec.PlanBuilder) error {
func buildPlan(graph *dag.Graph, blder *exec.PlanBuilder, opt CompileOption) error {
var retErr error
graph.Walk(func(node dag.Node) bool {
for i := 0; i < node.OutputStreams().Len(); i++ {


+ 39
- 28
common/pkgs/ioswitch/plan/ops/send.go View File

@@ -23,11 +23,12 @@ func init() {
}

type SendStreamStatsValue struct {
IsSend bool
Length int64
Time time.Duration
Src exec.Location
Dst exec.Location
StatsCtx string
IsSend bool
Length int64
Time time.Duration
Src exec.Location
Dst exec.Location
}

func (v *SendStreamStatsValue) Clone() exec.VarValue {
@@ -36,9 +37,10 @@ func (v *SendStreamStatsValue) Clone() exec.VarValue {
}

type SendStream struct {
Input exec.VarID
Send exec.VarID
Worker exec.WorkerInfo
Input exec.VarID
Send exec.VarID
Worker exec.WorkerInfo
StatsCtx string
}

func (o *SendStream) Execute(ctx *exec.ExecContext, e *exec.Executor) error {
@@ -65,10 +67,11 @@ func (o *SendStream) Execute(ctx *exec.ExecContext, e *exec.Executor) error {
}

e.Store(SendStreamStatsStoreKey, &SendStreamStatsValue{
IsSend: true,
Length: counter.Count(),
Time: time.Since(startTime),
Src: e.Location(),
StatsCtx: o.StatsCtx,
IsSend: true,
Length: counter.Count(),
Time: time.Since(startTime),
Src: e.Location(),
Dst: exec.Location{
IsDriver: false,
WorkerName: o.Worker.Name(),
@@ -83,10 +86,11 @@ func (o *SendStream) String() string {
}

type GetStream struct {
Signal exec.SignalVar `json:"signal"`
Target exec.VarID `json:"target"`
Output exec.VarID `json:"output"`
Worker exec.WorkerInfo `json:"worker"`
Signal exec.SignalVar
Target exec.VarID
Output exec.VarID
Worker exec.WorkerInfo
StatsCtx string
}

func (o *GetStream) Execute(ctx *exec.ExecContext, e *exec.Executor) error {
@@ -113,9 +117,10 @@ func (o *GetStream) Execute(ctx *exec.ExecContext, e *exec.Executor) error {

err = fut.Wait(ctx.Context)
e.Store(SendStreamStatsStoreKey, &SendStreamStatsValue{
IsSend: false,
Length: counter.Count(),
Time: time.Since(startTime),
StatsCtx: o.StatsCtx,
IsSend: false,
Length: counter.Count(),
Time: time.Since(startTime),
Src: exec.Location{
IsDriver: false,
WorkerName: o.Worker.Name(),
@@ -191,11 +196,13 @@ func (o *GetVar) String() string {
type SendStreamNode struct {
dag.NodeBase
ToWorker exec.WorkerInfo
StatsCtx string
}

func (b *GraphNodeBuilder) NewSendStream(to exec.WorkerInfo) *SendStreamNode {
func (b *GraphNodeBuilder) NewSendStream(to exec.WorkerInfo, statsCtx string) *SendStreamNode {
node := &SendStreamNode{
ToWorker: to,
StatsCtx: statsCtx,
}
b.AddNode(node)

@@ -211,9 +218,10 @@ func (t *SendStreamNode) Send(v *dag.StreamVar) *dag.StreamVar {

func (t *SendStreamNode) GenerateOp() (exec.Op, error) {
return &SendStream{
Input: t.InputStreams().Get(0).VarID,
Send: t.OutputStreams().Get(0).VarID,
Worker: t.ToWorker,
Input: t.InputStreams().Get(0).VarID,
Send: t.OutputStreams().Get(0).VarID,
Worker: t.ToWorker,
StatsCtx: t.StatsCtx,
}, nil
}

@@ -257,11 +265,13 @@ func (t *SendValueNode) GenerateOp() (exec.Op, error) {
type GetStreamNode struct {
dag.NodeBase
FromWorker exec.WorkerInfo
StatsCtx string
}

func (b *GraphNodeBuilder) NewGetStream(from exec.WorkerInfo) *GetStreamNode {
func (b *GraphNodeBuilder) NewGetStream(from exec.WorkerInfo, statsCtx string) *GetStreamNode {
node := &GetStreamNode{
FromWorker: from,
StatsCtx: statsCtx,
}
b.AddNode(node)

@@ -282,10 +292,11 @@ func (t *GetStreamNode) SignalVar() *dag.ValueVar {

func (t *GetStreamNode) GenerateOp() (exec.Op, error) {
return &GetStream{
Signal: exec.NewSignalVar(t.OutputValues().Get(0).VarID),
Output: t.OutputStreams().Get(0).VarID,
Target: t.InputStreams().Get(0).VarID,
Worker: t.FromWorker,
Signal: exec.NewSignalVar(t.OutputValues().Get(0).VarID),
Output: t.OutputStreams().Get(0).VarID,
Target: t.InputStreams().Get(0).VarID,
Worker: t.FromWorker,
StatsCtx: t.StatsCtx,
}, nil
}



+ 2
- 0
common/pkgs/ioswitch2/fromto.go View File

@@ -74,6 +74,8 @@ type FromTo struct {
SegmentParam *jcstypes.SegmentRedundancy
Froms []From
Toes []To
// 用于识别不同的统计信息对应的上下文
StatsCtx string
}

func NewFromTo() FromTo {


+ 14
- 2
common/pkgs/ioswitch2/ops2/base_store.go View File

@@ -28,6 +28,7 @@ func init() {
}

type BaseReadStatsValue struct {
StatsCtx string
Length int64
ElapsedTime time.Duration
Location exec.Location
@@ -35,6 +36,7 @@ type BaseReadStatsValue struct {

func (v *BaseReadStatsValue) Clone() exec.VarValue {
return &BaseReadStatsValue{
StatsCtx: v.StatsCtx,
Length: v.Length,
ElapsedTime: v.ElapsedTime,
Location: v.Location,
@@ -46,6 +48,7 @@ type BaseRead struct {
UserSpace jcstypes.UserSpaceDetail
Path jcstypes.JPath
Option stgtypes.OpenOption
StatsCtx string
}

func (o *BaseRead) Execute(ctx *exec.ExecContext, e *exec.Executor) error {
@@ -84,6 +87,7 @@ func (o *BaseRead) Execute(ctx *exec.ExecContext, e *exec.Executor) error {
e.PutVar(o.Output, output)
err = fut.Wait(ctx.Context)
e.Store(BaseReadStatsStoreKey, &BaseReadStatsValue{
StatsCtx: o.StatsCtx,
Length: counter.Count(),
ElapsedTime: time.Since(startTime),
Location: e.Location(),
@@ -100,6 +104,7 @@ type BaseReadDyn struct {
Output exec.VarID
FileInfo exec.VarID
Option stgtypes.OpenOption
StatsCtx string
}

func (o *BaseReadDyn) Execute(ctx *exec.ExecContext, e *exec.Executor) error {
@@ -147,6 +152,7 @@ func (o *BaseReadDyn) Execute(ctx *exec.ExecContext, e *exec.Executor) error {
Length: counter.Count(),
ElapsedTime: time.Since(startTime),
Location: e.Location(),
StatsCtx: o.StatsCtx,
})
return err
}
@@ -206,14 +212,16 @@ type BaseReadNode struct {
UserSpace jcstypes.UserSpaceDetail
Path jcstypes.JPath
Option stgtypes.OpenOption
StatsCtx string
}

func (b *GraphNodeBuilder) NewBaseRead(from ioswitch2.From, userSpace jcstypes.UserSpaceDetail, path jcstypes.JPath, opt stgtypes.OpenOption) *BaseReadNode {
func (b *GraphNodeBuilder) NewBaseRead(from ioswitch2.From, userSpace jcstypes.UserSpaceDetail, path jcstypes.JPath, opt stgtypes.OpenOption, statsCtx string) *BaseReadNode {
node := &BaseReadNode{
From: from,
UserSpace: userSpace,
Path: path,
Option: opt,
StatsCtx: statsCtx,
}
b.AddNode(node)

@@ -238,6 +246,7 @@ func (t *BaseReadNode) GenerateOp() (exec.Op, error) {
UserSpace: t.UserSpace,
Path: t.Path,
Option: t.Option,
StatsCtx: t.StatsCtx,
}, nil
}

@@ -246,13 +255,15 @@ type BaseReadDynNode struct {
From ioswitch2.From
UserSpace jcstypes.UserSpaceDetail
Option stgtypes.OpenOption
StatsCtx string
}

func (b *GraphNodeBuilder) NewBaseReadDyn(from ioswitch2.From, userSpace jcstypes.UserSpaceDetail, opt stgtypes.OpenOption) *BaseReadDynNode {
func (b *GraphNodeBuilder) NewBaseReadDyn(from ioswitch2.From, userSpace jcstypes.UserSpaceDetail, opt stgtypes.OpenOption, statsCtx string) *BaseReadDynNode {
node := &BaseReadDynNode{
From: from,
UserSpace: userSpace,
Option: opt,
StatsCtx: statsCtx,
}
b.AddNode(node)

@@ -285,6 +296,7 @@ func (t *BaseReadDynNode) GenerateOp() (exec.Op, error) {
Output: t.Output().Var().VarID,
FileInfo: t.FileInfoSlot().Var().VarID,
Option: t.Option,
StatsCtx: t.StatsCtx,
}, nil
}



+ 2
- 2
common/pkgs/ioswitch2/parser/gen/generator.go View File

@@ -261,7 +261,7 @@ func buildFromNode(ctx *state.GenerateState, f ioswitch2.From) (ops2.FromNode, e
getShard := ctx.DAG.NewGetShardInfo(f.UserSpace, f.FileHash)
getShard.Env().ToEnvDriver(true)

read := ctx.DAG.NewBaseReadDyn(f, f.UserSpace, stgtypes.DefaultOpen())
read := ctx.DAG.NewBaseReadDyn(f, f.UserSpace, stgtypes.DefaultOpen(), ctx.Ft.StatsCtx)

getShard.FileInfoVar().ToSlot(read.FileInfoSlot())

@@ -332,7 +332,7 @@ func buildFromNode(ctx *state.GenerateState, f ioswitch2.From) (ops2.FromNode, e

case *ioswitch2.FromBaseStore:
// TODO 可以考虑支持设置读取范围
n := ctx.DAG.NewBaseRead(f, f.UserSpace, f.Path, stgtypes.DefaultOpen())
n := ctx.DAG.NewBaseRead(f, f.UserSpace, f.Path, stgtypes.DefaultOpen(), ctx.Ft.StatsCtx)
if err := setEnvBySpace(n, &f.UserSpace); err != nil {
return nil, fmt.Errorf("set node env by user space: %w", err)
}


+ 3
- 1
common/pkgs/ioswitch2/parser/parser.go View File

@@ -85,5 +85,7 @@ func Parse(ft ioswitch2.FromTo, blder *exec.PlanBuilder) error {
opt.GenerateRange(state)
opt.GenerateClone(state)

return plan.Compile(state.DAG.Graph, blder)
return plan.Compile(state.DAG.Graph, blder, plan.CompileOption{
StatsCtx: ft.StatsCtx,
})
}

+ 2
- 2
common/pkgs/ioswitch2/plans/complete_multipart.go View File

@@ -27,7 +27,7 @@ func CompleteMultipart(blocks []jcstypes.ObjectBlock, blockSpaces []jcstypes.Use
gs := da.NewGetShardInfo(blockSpaces[i], blk.FileHash)
gs.Env().ToEnvDriver(true)

br := da.NewBaseReadDyn(nil, blockSpaces[i], stgtypes.DefaultOpen())
br := da.NewBaseReadDyn(nil, blockSpaces[i], stgtypes.DefaultOpen(), "")
if err := setEnvBySpace(br, &blockSpaces[i]); err != nil {
return fmt.Errorf("set node env by user space: %w", err)
}
@@ -54,7 +54,7 @@ func CompleteMultipart(blocks []jcstypes.ObjectBlock, blockSpaces []jcstypes.Use
store.Store(shardInfoKey, as.ShardInfoVar().Var())
}

err := plan.Compile(da.Graph, blder)
err := plan.Compile(da.Graph, blder, plan.CompileOption{})
if err != nil {
return err
}


+ 4
- 3
common/pkgs/ioswitchlrc/parser/generator.go View File

@@ -49,7 +49,8 @@ func Encode(fr ioswitchlrc.From, toes []ioswitchlrc.To, blder *exec.PlanBuilder)
generateClone(&ctx)
generateRange(&ctx)

return plan.Compile(ctx.DAG.Graph, blder)
// TODO 设置StatsCtx
return plan.Compile(ctx.DAG.Graph, blder, plan.CompileOption{})
}

func buildDAGEncode(ctx *GenerateContext, fr ioswitchlrc.From, toes []ioswitchlrc.To) error {
@@ -146,7 +147,7 @@ func ReconstructAny(frs []ioswitchlrc.From, toes []ioswitchlrc.To, blder *exec.P
generateClone(&ctx)
generateRange(&ctx)

return plan.Compile(ctx.DAG.Graph, blder)
return plan.Compile(ctx.DAG.Graph, blder, plan.CompileOption{})
}

func buildDAGReconstructAny(ctx *GenerateContext, frs []ioswitchlrc.From, toes []ioswitchlrc.To) error {
@@ -267,7 +268,7 @@ func ReconstructGroup(frs []ioswitchlrc.From, toes []ioswitchlrc.To, blder *exec
generateClone(&ctx)
generateRange(&ctx)

return plan.Compile(ctx.DAG.Graph, blder)
return plan.Compile(ctx.DAG.Graph, blder, plan.CompileOption{})
}

func buildDAGReconstructGroup(ctx *GenerateContext, frs []ioswitchlrc.From, toes []ioswitchlrc.To) error {


Loading…
Cancel
Save