-
Notifications
You must be signed in to change notification settings - Fork 945
Go Workloads for Testing #25414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
tvaron3
wants to merge
27
commits into
Azure:main
Choose a base branch
from
tvaron3:tvaron3/workloads
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Go Workloads for Testing #25414
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
e081983
initial changes for workloads
tvaron3 fe85531
create initial read write query workload
tvaron3 0b463cb
remove unnecessary print statement
tvaron3 54b06be
add changes to perform reads,writes,queries
tvaron3 6ceccc4
increase time workload runs
tvaron3 80da224
refactor and react to comments
tvaron3 1dd267e
react to comments and add vector search queries
tvaron3 4e7463c
refactor configs
tvaron3 318a88c
add client engine to workloads
tvaron3 502a13a
fix vector policy
tvaron3 b07d714
fix vector policy
tvaron3 399c0dd
update instructions
tvaron3 872c341
update instructions
tvaron3 b8756fb
change permissions on setup script
tvaron3 15558fe
change to log to a file
tvaron3 43b3dcf
additional logging for debugging preferred locations
tvaron3 b2e85d8
more logging
tvaron3 28fd089
comment out logs
tvaron3 8b35f4b
react to comments and add useragent
tvaron3 8500f77
add aad to workload
tvaron3 492698b
remove ctx timer, run point reads on other thread
tvaron3 7a21cde
skip setup with aad
tvaron3 0c009ab
fix pkfield
tvaron3 9a3d2b8
revert pkField change
tvaron3 ee2f36f
fix pkfield
tvaron3 3cf9d50
Add Allow Tentative Writes Header (#25127)
tvaron3 f627ed1
Merge branch 'main' of https://github.com/Azure/azure-sdk-for-go into…
tvaron3 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
analogrelay marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| ## SDK Scale Testing | ||
| This directory contains the scale testing workloads for the SDK. The workloads are designed to test the performance | ||
| and scalability of the SDK under various conditions. | ||
|
|
||
| ### Setup Scale Testing | ||
| 1. Create a VM in Azure with the following configuration: | ||
| - 8 vCPUs | ||
| - 32 GB RAM | ||
| - Ubuntu | ||
| - Accelerated networking | ||
| 1. Give the VM necessary [permissions](https://learn.microsoft.com/azure/cosmos-db/nosql/how-to-grant-data-plane-access?tabs=built-in-definition%2Ccsharp&pivots=azure-interface-cli) to access the Cosmos DB account if using AAD (Optional). | ||
| 1. Fork and clone this repository | ||
| 1. Go to azcosmos folder | ||
| - `cd azure-sdk-for-go/sdk/data/azcosmos/workloads` | ||
| 1. Checkout the branch with the changes to test. | ||
| 1. Run `./setup_env.sh` | ||
| 1. Fill out relevant configs in `workload_configs.go`: key, host, etc using env variables | ||
tvaron3 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - `COSMOS_URI` - required | ||
| - `COSMOS_KEY` - required | ||
| - `COSMOS_DATABASE` | ||
| - `COSMOS_CONTAINER` | ||
| - `PARTITION_KEY` | ||
| - `NUMBER_OF_LOGICAL_PARTITIONS` | ||
| - `THROUGHPUT` | ||
| - `PREFERRED_LOCATIONS` | ||
| 1. Set `AZURE_SDK_GO_LOGGING` env variable to "all" for detailed logs | ||
| 1. Run the scale workload | ||
| - `go run ./main/main.go` | ||
|
|
||
| ### Monitor Run | ||
| - `ps -eaf | grep "go"` to see the running processes | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| package workloads | ||
|
|
||
| import ( | ||
| "context" | ||
| "errors" | ||
| "fmt" | ||
| "log" | ||
|
|
||
| "github.com/Azure/azure-sdk-for-go/sdk/azcore" | ||
| "github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos" | ||
| ) | ||
|
|
||
| // createDatabaseIfNotExists attempts to create the database, tolerating conflicts. | ||
| func createDatabaseIfNotExists(ctx context.Context, client *azcosmos.Client, dbID string) (*azcosmos.DatabaseClient, error) { | ||
| dbClient, err := client.NewDatabase(dbID) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| props := azcosmos.DatabaseProperties{ID: dbID} | ||
| _, err = client.CreateDatabase(ctx, props, nil) | ||
| if err != nil { | ||
| var azErr *azcore.ResponseError | ||
| if errors.As(err, &azErr) { | ||
| if azErr.StatusCode == 409 { | ||
| return dbClient, nil // already exists | ||
| } | ||
| } | ||
| return nil, err | ||
| } | ||
| return dbClient, nil | ||
| } | ||
|
|
||
| func createContainerIfNotExists(ctx context.Context, db *azcosmos.DatabaseClient, containerID, pkField string, desiredThroughput int32) (*azcosmos.ContainerClient, error) { | ||
| containerClient, err := db.NewContainer(containerID) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| // Build container properties with vector indexing policy | ||
| props := azcosmos.ContainerProperties{ | ||
| ID: containerID, | ||
| PartitionKeyDefinition: azcosmos.PartitionKeyDefinition{ | ||
| Paths: []string{"/" + pkField}, | ||
| Kind: azcosmos.PartitionKeyKindHash, | ||
| }, | ||
| VectorEmbeddingPolicy: &azcosmos.VectorEmbeddingPolicy{ | ||
| VectorEmbeddings: []azcosmos.VectorEmbedding{ | ||
| { | ||
| Path: "/embedding", | ||
| DataType: azcosmos.VectorDataTypeFloat32, | ||
| DistanceFunction: azcosmos.VectorDistanceFunctionCosine, | ||
| Dimensions: 10, | ||
| }, | ||
| }, | ||
| }, | ||
| IndexingPolicy: &azcosmos.IndexingPolicy{ | ||
| Automatic: true, | ||
| IndexingMode: azcosmos.IndexingModeConsistent, | ||
| IncludedPaths: []azcosmos.IncludedPath{ | ||
| {Path: "/*"}, | ||
| }, | ||
| ExcludedPaths: []azcosmos.ExcludedPath{ | ||
| {Path: "/\"_etag\"/?"}, | ||
| {Path: "/embedding/*"}, // Exclude vector path from standard indexing | ||
| }, | ||
| VectorIndexes: []azcosmos.VectorIndex{ | ||
| { | ||
| Path: "/embedding", | ||
| Type: azcosmos.VectorIndexTypeDiskANN, | ||
| }, | ||
| }, | ||
| }, | ||
| } | ||
|
|
||
| throughput := azcosmos.NewManualThroughputProperties(desiredThroughput) | ||
| // Try create | ||
| _, err = db.CreateContainer(ctx, props, &azcosmos.CreateContainerOptions{ | ||
| ThroughputProperties: &throughput, | ||
| }) | ||
| if err != nil { | ||
| var azErr *azcore.ResponseError | ||
| if errors.As(err, &azErr) { | ||
| if azErr.StatusCode == 409 { | ||
| return containerClient, nil // already exists | ||
| } | ||
| } | ||
| return nil, err | ||
| } | ||
|
|
||
| return containerClient, nil | ||
| } | ||
|
|
||
| // RunSetup creates the database/container and performs the concurrent upserts. | ||
| func RunSetup(ctx context.Context, client *azcosmos.Client, cfg workloadConfig) error { | ||
|
|
||
| dbClient, err := createDatabaseIfNotExists(ctx, client, cfg.DatabaseID) | ||
| if err != nil { | ||
| return fmt.Errorf("ensure database: %w", err) | ||
| } | ||
|
|
||
| container, err := createContainerIfNotExists(ctx, dbClient, cfg.ContainerID, cfg.PartitionKeyFieldName, int32(cfg.Throughput)) | ||
| if err != nil { | ||
| return fmt.Errorf("ensure container: %w", err) | ||
| } | ||
|
|
||
| var count = cfg.LogicalPartitions | ||
|
|
||
| log.Printf("Starting %d concurrent upserts...", count) | ||
|
|
||
| if err := upsertItemsConcurrently(ctx, container, count, cfg.PartitionKeyFieldName); err != nil { | ||
| return fmt.Errorf("upserts failed: %w", err) | ||
| } | ||
|
|
||
| log.Printf("Completed %d upserts.", count) | ||
| return nil | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| package main | ||
|
|
||
| import ( | ||
| "context" | ||
| "log" | ||
| "os" | ||
|
|
||
| "github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos/workloads" | ||
| ) | ||
|
|
||
| func main() { | ||
| // setup logger | ||
| f, err := os.OpenFile("workloads.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644) | ||
| if err != nil { | ||
| log.Fatalf("failed to open log file: %v", err) | ||
| } | ||
| defer f.Close() | ||
|
|
||
| // Send the default logger output to the file | ||
| log.SetOutput(f) | ||
| // Optional: set flags to include date/time/file info | ||
| log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Lshortfile) | ||
|
|
||
| ctx := context.Background() | ||
|
|
||
| cfg, err := workloads.LoadConfig() | ||
| if err != nil { | ||
| log.Fatalf("failed to load config: %v", err) | ||
| } | ||
|
|
||
| client, err := workloads.CreateClient(cfg) | ||
| if err != nil { | ||
| log.Fatalf("creating client: %v", err) | ||
| } | ||
|
|
||
| if cfg.Key != "" { | ||
| if err := workloads.RunSetup(ctx, client, cfg); err != nil { | ||
| log.Fatalf("setup failed: %v", err) | ||
| } | ||
| } else { | ||
| log.Printf("Setup skipped as AAD is enabled.") | ||
| } | ||
| log.Println("setup completed") | ||
| if err := workloads.RunWorkload(ctx, client, cfg); err != nil { | ||
| log.Fatalf("workload failed: %v", err) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT License. | ||
|
|
||
| package workloads | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| "log" | ||
| "runtime" | ||
| "sync" | ||
| "time" | ||
|
|
||
| "github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos" | ||
| ) | ||
|
|
||
| func RunWorkload(ctx context.Context, client *azcosmos.Client, cfg workloadConfig) error { | ||
|
|
||
| dbClient, err := client.NewDatabase(cfg.DatabaseID) | ||
| if err != nil { | ||
| return fmt.Errorf("ensure database: %w", err) | ||
| } | ||
|
|
||
| container, err := dbClient.NewContainer(cfg.ContainerID) | ||
| if err != nil { | ||
| return fmt.Errorf("ensure container: %w", err) | ||
| } | ||
|
|
||
| var count = cfg.LogicalPartitions | ||
|
|
||
| log.Printf("Starting %d concurrent read/write/queries ...", count) | ||
|
|
||
| // Use two goroutines each locked to their own OS thread. | ||
| var wg sync.WaitGroup | ||
| wg.Add(2) | ||
|
|
||
| // Goroutine 1: random read/write/queries | ||
| go func() { | ||
| // Pin this goroutine to its own OS thread | ||
| runtime.LockOSThread() | ||
| defer runtime.UnlockOSThread() | ||
| defer wg.Done() | ||
|
|
||
| for { | ||
| select { | ||
| case <-ctx.Done(): | ||
| return | ||
| default: | ||
| } | ||
|
|
||
| if err := randomReadWriteQueries(ctx, container, count, cfg.PartitionKeyFieldName); err != nil { | ||
| log.Printf("read/write/queries failed: %v", err) | ||
| } | ||
|
|
||
| // small jitter to avoid tight loop in case of immediate errors | ||
| time.Sleep(10 * time.Millisecond) | ||
| } | ||
| }() | ||
|
|
||
| // Goroutine 2: vector search queries | ||
| go func() { | ||
| runtime.LockOSThread() | ||
| defer runtime.UnlockOSThread() | ||
| defer wg.Done() | ||
|
|
||
| for { | ||
| select { | ||
| case <-ctx.Done(): | ||
| return | ||
| default: | ||
| } | ||
|
|
||
| if err := vectorSearchQueries(ctx, container, count, cfg.PartitionKeyFieldName); err != nil { | ||
| log.Printf("vector search queries failed: %v", err) | ||
| } | ||
|
|
||
| time.Sleep(10 * time.Millisecond) | ||
| } | ||
| }() | ||
|
|
||
| // Wait until context is cancelled, then wait for goroutines to finish | ||
| <-ctx.Done() | ||
| // Give goroutines a moment to observe ctx.Done and exit; they will return promptly | ||
| wg.Wait() | ||
| return nil | ||
|
|
||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| #!/bin/bash | ||
| # cspell:disable | ||
| # setup_env.sh - Automates Azure Cosmos SDK scale testing environment setup | ||
| # Usage: bash setup_env.sh | ||
|
|
||
| set -e | ||
|
|
||
| # 1. System update and install dependencies | ||
| echo "[Step 1] System update and install dependencies: started." | ||
| sudo apt update | ||
| sudo apt install golang-go | ||
| sudo apt install neovim | ||
| curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash | ||
| echo "[Step 1] System update and install dependencies: completed." |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's either remove these altogether or switch them to use the core logging facility. (Basically, I just don't like committing commented-out code ;))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I will remove these. :)