Skip to content

Commit

Permalink
Load Test and Results
Browse files Browse the repository at this point in the history
  • Loading branch information
Justin Jones committed Feb 12, 2024
1 parent 968c923 commit bfbaa66
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 1 deletion.
7 changes: 7 additions & 0 deletions OrleansShardedStorage.sln
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests", "TestApplicatio
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZDataFinder", "ZDataFinder\ZDataFinder.csproj", "{472CC87D-88D3-4B87-861C-98303964306C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClientLoadTest", "TestApplication\ClientLoadTest\ClientLoadTest.csproj", "{A50A0A45-0739-498D-8140-F272A178D1F9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -55,6 +57,10 @@ Global
{472CC87D-88D3-4B87-861C-98303964306C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{472CC87D-88D3-4B87-861C-98303964306C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{472CC87D-88D3-4B87-861C-98303964306C}.Release|Any CPU.Build.0 = Release|Any CPU
{A50A0A45-0739-498D-8140-F272A178D1F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A50A0A45-0739-498D-8140-F272A178D1F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A50A0A45-0739-498D-8140-F272A178D1F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A50A0A45-0739-498D-8140-F272A178D1F9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -67,6 +73,7 @@ Global
{62FEC839-F350-4F24-921B-AA18BC516013} = {DCD6C532-ADC2-4A49-A7DF-2D559934912C}
{EE88F5E1-EEFE-4D80-97B7-EA6E5DF36908} = {139B6E56-2FD9-4313-BC10-BF974F391AF0}
{472CC87D-88D3-4B87-861C-98303964306C} = {139B6E56-2FD9-4313-BC10-BF974F391AF0}
{A50A0A45-0739-498D-8140-F272A178D1F9} = {139B6E56-2FD9-4313-BC10-BF974F391AF0}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B78AD82C-DEA2-4C5F-AF2C-1D9F3CABEE3D}
Expand Down
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,52 @@ Each Provider must be of one type. i.e. You can have many Table Storage Provider
----
----

## Example Load Test Results

Remember many factors such as machines, network, storage types and more can affect performance.

Running `ClientLoadTest` and `Silo`.

Using Standard D8s v5 VM (8vCPU's, 32Gib RAM)

5 Silo's, localhost cluster.

Grains warmed up for clarity as to the actual fastest save time. To call the grains without any save would take 100K -> 528ms on this setup (189K/s).

Values in milliseconds.

### 1 Standard Storage Account

| Size | Save to Blob |
| -------- | ------- |
| 100K | 12986 |

Struggles around 100K

### 2 Standard Storage Accounts

| Size | Save to Blob |
| -------- | ------- |
| 100K | 4848 |

Slows around 150K

### 1 Premium Storage Account (Block Blobs)

| Size | Save to Blob |
| -------- | ------- |
| 100K | 5824 |

Note this is significantly faster than standard storage.

### 2 Premium Storage Accounts (Block Blobs)

| Size | Save to Blob |
| -------- | ------- |
| 100K | 4877 |

*Reached over 300K without complaints.


## How to Set up the Test Application

Expand Down
20 changes: 20 additions & 0 deletions TestApplication/ClientLoadTest/ClientLoadTest.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
<PackageReference Include="Microsoft.Orleans.Client" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\GrainInterfaces\GrainInterfaces.csproj" />
</ItemGroup>

</Project>
143 changes: 143 additions & 0 deletions TestApplication/ClientLoadTest/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
using Orleans.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using GrainInterfaces;
using Orleans.Serialization.Invocation;
using System.Text;
using static System.Net.Mime.MediaTypeNames;
using OrleansCodeGen.Orleans.Core.Internal;
using GrainInterfaces.Models;
using GrainInterfaces.Aggregate;
using System.Diagnostics;
using System;

try
{
var host = await StartClientAsync();
var client = host.Services.GetRequiredService<IClusterClient>();

await DoClientWorkAsync(client);
Console.ReadKey();

return 0;
}
catch (Exception e)
{
Console.WriteLine($"\nException while trying to run client: {e.Message}");
Console.WriteLine("Make sure the silo the client is trying to connect to is running.");
Console.WriteLine("\nPress any key to exit.");
Console.ReadKey();
return 1;
}

static async Task<IHost> StartClientAsync()
{
var builder = new HostBuilder()
.UseOrleansClient(client =>
{
client.UseLocalhostClustering()
.Configure<ClusterOptions>(options =>
{
options.ClusterId = "dev";
options.ServiceId = "OrleansBasics";
});
})
.ConfigureLogging(logging => logging.AddConsole());

var host = builder.Build();
await host.StartAsync();

Console.WriteLine("Client successfully connected to silo host \n");

return host;
}

static async Task DoClientWorkAsync(IClusterClient client)
{
Console.WriteLine($"NOTE: This is a load test.");
Console.WriteLine("It is NOT using the Reduce Pattern to find breaking points directly.");
Console.WriteLine("See standard client for reduce tests.");

Console.WriteLine();
Console.WriteLine("Enter the number of grains to create and hit enter.");
var numberString = Console.ReadLine();
Console.WriteLine();

if (!String.IsNullOrWhiteSpace(numberString))
{
int number = int.Parse(numberString); // It's a test console. No input checking.

Console.WriteLine("Start Test Prep");

List<JoinGameMessage> messagesForPeople = new List<JoinGameMessage>();

var game1 = Guid.NewGuid();

for (int i = 0; i < number; i++)
{
messagesForPeople.Add(new JoinGameMessage()
{
PersonGuid = Guid.NewGuid(),
GameGuid = game1,
Name = $"Game 1, Person {i}"
});
}

Console.WriteLine("Warm Up Grains");
Stopwatch st = new Stopwatch();
st.Start();

var warmUpTask = async (JoinGameMessage msg) =>
{
var grain = client.GetGrain<IPersonGrain>(msg.PersonGuid);
await grain.WarmUp();
};

List<Task> warmUpTasks = new List<Task>();
foreach (var pMsg in messagesForPeople)
{
warmUpTasks.Add(warmUpTask(pMsg));
}

//await Task.WhenAll(warmUpTasks);
Task.WaitAll(warmUpTasks.ToArray());

st.Stop();
Console.WriteLine($"Warmed up {number} grains in {st.ElapsedMilliseconds}ms");
Console.WriteLine($"Start main test");
st.Reset();
st.Start();

List<Task<string>> sendTasks = new List<Task<string>>();

var sendPersonDataTask = async (JoinGameMessage msg) =>
{
var grain = client.GetGrain<IPersonGrain>(msg.PersonGuid);
var result = await grain.ConfirmGameJoined(msg);
return result;
};

foreach (var pMsg in messagesForPeople)
{
sendTasks.Add(sendPersonDataTask(pMsg));
}

var results = await Task.WhenAll(sendTasks);

st.Stop();

Console.WriteLine($"{results.Count()} sends/saves in {st.ElapsedMilliseconds}ms");

Console.WriteLine();
Console.WriteLine("Done");

}
else
{
Console.WriteLine("No input. Press enter again to exit the console.");
}

Console.ReadLine();

}
2 changes: 2 additions & 0 deletions TestApplication/GrainInterfaces/Aggregate/IPersonGrain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace GrainInterfaces.Aggregate
{
public interface IPersonGrain : Orleans.IGrainWithGuidKey
{
Task WarmUp();

Task<string> ConfirmGameJoined(JoinGameMessage joinGameMessage);

Task<List<Guid>> GetJoinedGames();
Expand Down
6 changes: 5 additions & 1 deletion TestApplication/Grains/Aggregate/PersonGrain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ public override Task OnActivateAsync(CancellationToken cancellationToken)
return base.OnActivateAsync(cancellationToken);
}

Task IPersonGrain.WarmUp()
{
return Task.CompletedTask;
}

async Task<string> IPersonGrain.ConfirmGameJoined(JoinGameMessage joinGameMessage)
async Task<string> IPersonGrain.ConfirmGameJoined(JoinGameMessage joinGameMessage)
{
this._state.State.Name = joinGameMessage.Name;
this._state.State.GameGuids.Add(joinGameMessage.GameGuid);
Expand Down

0 comments on commit bfbaa66

Please sign in to comment.