From 2c59c6b69c5047825d9507c37f1859cf28f6736b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lazar=20Cvetkovi=C4=87?= Date: Fri, 6 Dec 2024 14:38:05 +0100 Subject: [PATCH] RPS data size feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lazar Cvetković --- .github/configs/wordlist.txt | 3 ++- cmd/config_dirigent_dandelion_rps.json | 1 + cmd/config_dirigent_rps.json | 1 + cmd/config_knative_rps.json | 1 + docs/configuration.md | 4 +++- pkg/config/parser.go | 1 + pkg/driver/clients/http_client.go | 30 +++++++++++++++++++++++--- pkg/driver/deployment/dirigent.go | 2 ++ 8 files changed, 38 insertions(+), 5 deletions(-) diff --git a/.github/configs/wordlist.txt b/.github/configs/wordlist.txt index 55c9e748d..39b149be5 100644 --- a/.github/configs/wordlist.txt +++ b/.github/configs/wordlist.txt @@ -778,4 +778,5 @@ async AsyncMode AsyncResponseURL AsyncWaitToCollectMin -Knative's \ No newline at end of file +Knative's +RpsDataSizeMB \ No newline at end of file diff --git a/cmd/config_dirigent_dandelion_rps.json b/cmd/config_dirigent_dandelion_rps.json index d4b32e216..964580e1d 100644 --- a/cmd/config_dirigent_dandelion_rps.json +++ b/cmd/config_dirigent_dandelion_rps.json @@ -19,6 +19,7 @@ "RpsRuntimeMs": 10, "RpsMemoryMB": 2048, "RpsIterationMultiplier": 80, + "RpsDataSizeMB": 0.00, "TracePath": "data/traces/example", "Granularity": "minute", diff --git a/cmd/config_dirigent_rps.json b/cmd/config_dirigent_rps.json index cf2952022..c61608d1a 100644 --- a/cmd/config_dirigent_rps.json +++ b/cmd/config_dirigent_rps.json @@ -19,6 +19,7 @@ "RpsRuntimeMs": 10, "RpsMemoryMB": 2048, "RpsIterationMultiplier": 80, + "RpsDataSizeMB": 0.00, "TracePath": "data/traces/example", "Granularity": "minute", diff --git a/cmd/config_knative_rps.json b/cmd/config_knative_rps.json index 3a72fd7d3..cf1d9325b 100644 --- a/cmd/config_knative_rps.json +++ b/cmd/config_knative_rps.json @@ -15,6 +15,7 @@ "RpsRuntimeMs": 10, "RpsMemoryMB": 2048, "RpsIterationMultiplier": 80, + "RpsDataSizeMB": 0.00, "TracePath": "data/traces/example", "Granularity": "minute", diff --git a/docs/configuration.md b/docs/configuration.md index 7382484a8..f920be5f1 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -19,6 +19,7 @@ | RpsRuntimeMs | int | >=0 | 0 | Requested execution time | | RpsMemoryMB | int | >=0 | 0 | Requested memory | | RpsIterationMultiplier | int | >=0 | 0 | Iteration multiplier for RPS mode | +| RpsDataSizeMB | float64 | >= 0 | 0 | Amount of random data (same for all requests) to embed into each request | | TracePath | string | string | data/traces | Folder with Azure trace dimensions (invocations.csv, durations.csv, memory.csv) | | Granularity | string | minute, second | minute | Granularity for trace interpretation[^2] | | OutputPathPrefix | string | any | data/out/experiment | Results file(s) output path prefix | @@ -55,7 +56,8 @@ Lambda; https://aws.amazon.com/about-aws/whats-new/2018/10/aws-lambda-supports-f [^6]: Dirigent specific -[^7] It is recommended that the first 10% of cold starts are discarded from the experiment results for low cold start RPS. +[^7] It is recommended that the first 10% of cold starts are discarded from the experiment results for low cold start +RPS. --- diff --git a/pkg/config/parser.go b/pkg/config/parser.go index c6015d671..6cbb40ebd 100644 --- a/pkg/config/parser.go +++ b/pkg/config/parser.go @@ -61,6 +61,7 @@ type LoaderConfiguration struct { RpsRuntimeMs int `json:"RpsRuntimeMs"` RpsMemoryMB int `json:"RpsMemoryMB"` RpsIterationMultiplier int `json:"RpsIterationMultiplier"` + RpsDataSizeMB float64 `json:"RpsDataSizeMB"` TracePath string `json:"TracePath"` Granularity string `json:"Granularity"` diff --git a/pkg/driver/clients/http_client.go b/pkg/driver/clients/http_client.go index 5d6cd0518..6fdec5e1f 100644 --- a/pkg/driver/clients/http_client.go +++ b/pkg/driver/clients/http_client.go @@ -2,6 +2,7 @@ package clients import ( "bytes" + "crypto/rand" "encoding/json" log "github.com/sirupsen/logrus" "github.com/vhive-serverless/loader/pkg/common" @@ -33,6 +34,23 @@ func newHTTPInvoker(cfg *config.LoaderConfiguration) *httpInvoker { } } +var payload []byte = nil + +func CreateRequestPayload(sizeInMB float64) *bytes.Buffer { + byteCount := int(sizeInMB * 1024.0 * 1024.0) // MB -> B + + if payload == nil { + payload = make([]byte, byteCount) + + n, err := rand.Read(payload) + if err != nil || n != byteCount { + log.Errorf("Failed to generate random %d bytes.", byteCount) + } + } + + return bytes.NewBuffer(payload) +} + func (i *httpInvoker) Invoke(function *common.Function, runtimeSpec *common.RuntimeSpecification) (bool, *mc.ExecutionRecord) { isDandelion := strings.Contains(strings.ToLower(i.cfg.Platform), "dandelion") isKnative := strings.Contains(strings.ToLower(i.cfg.Platform), "knative") @@ -48,8 +66,6 @@ func (i *httpInvoker) Invoke(function *common.Function, runtimeSpec *common.Runt //////////////////////////////////// // INVOKE FUNCTION //////////////////////////////////// - start := time.Now() - record.StartTime = start.UnixMicro() requestBody := &bytes.Buffer{} /*if body := composeDandelionMatMulBody(function.Name); isDandelion && body != nil { @@ -58,8 +74,16 @@ func (i *httpInvoker) Invoke(function *common.Function, runtimeSpec *common.Runt if body := composeBusyLoopBody(function.Name, function.DirigentMetadata.Image, runtimeSpec.Runtime, function.DirigentMetadata.IterationMultiplier); isDandelion && body != nil { requestBody = body } + if i.cfg.RpsTarget != 0 { + ts := time.Now() + requestBody = CreateRequestPayload(i.cfg.RpsDataSizeMB) + log.Debugf("Took %v to generate request body.", time.Since(ts)) + } + + start := time.Now() + record.StartTime = start.UnixMicro() - req, err := http.NewRequest("GET", "http://"+function.Endpoint, requestBody) + req, err := http.NewRequest("POST", "http://"+function.Endpoint, requestBody) if err != nil { log.Errorf("Failed to create a HTTP request - %v\n", err) diff --git a/pkg/driver/deployment/dirigent.go b/pkg/driver/deployment/dirigent.go index fd0682839..3c55297dd 100644 --- a/pkg/driver/deployment/dirigent.go +++ b/pkg/driver/deployment/dirigent.go @@ -130,6 +130,8 @@ func deployDirigent(function *common.Function, controlPlaneAddress string, busyL log.Error("Function registration returned no data plane(s).") return } + + log.Debugf("Got the following endpoints: %v", endpoints) function.Endpoint = endpoints[rand.Intn(len(endpoints))] checkForRegistration(controlPlaneAddress, function.Name, prepullMode)