From 820ca0fbae009817c2946a8205465b6f1de08b52 Mon Sep 17 00:00:00 2001 From: Badrish Chandramouli Date: Thu, 19 Dec 2024 00:06:41 -0800 Subject: [PATCH] Add BDN that includes embedded network stack (#889) * Initial checkin on BDN that includes network path - handles non-TLS only * cleanup * ensure dispose * cleanup * merge from main * Update ci-bdnbenchmark.yml --- .github/workflows/ci-bdnbenchmark.yml | 15 +- benchmark/BDN.benchmark/BDN.benchmark.csproj | 2 - .../BDN.benchmark/Cluster/ClusterContext.cs | 2 +- .../Embedded/EmbeddedNetworkHandler.cs | 38 +++++ .../Embedded/EmbeddedNetworkSender.cs | 6 +- .../Embedded}/EmbeddedRespServer.cs | 19 ++- .../Embedded/GarnetServerEmbedded.cs | 101 +++++++++++++ .../BDN.benchmark/Lua/LuaRunnerOperations.cs | 2 +- .../Lua/LuaScriptCacheOperations.cs | 2 +- .../BDN.benchmark/Network/BasicOperations.cs | 30 ++++ .../BDN.benchmark/Network/NetworkBase.cs | 93 ++++++++++++ .../BDN.benchmark/Network/NetworkParams.cs | 38 +++++ .../Network/RawStringOperations.cs | 136 ++++++++++++++++++ .../Operations/BasicOperations.cs | 2 +- .../Operations/OperationsBase.cs | 12 +- .../Operations/RawStringOperations.cs | 20 +-- .../Embedded.perftest.csproj | 7 + .../EmbeddedPerformanceTest.cs | 1 + playground/Embedded.perftest/Program.cs | 1 + test/Garnet.test/Garnet.test.csproj | 2 +- test/Garnet.test/RespSortedSetTests.cs | 4 +- 21 files changed, 502 insertions(+), 31 deletions(-) create mode 100644 benchmark/BDN.benchmark/Embedded/EmbeddedNetworkHandler.cs rename playground/Embedded.perftest/DummyNetworkSender.cs => benchmark/BDN.benchmark/Embedded/EmbeddedNetworkSender.cs (95%) rename {playground/Embedded.perftest => benchmark/BDN.benchmark/Embedded}/EmbeddedRespServer.cs (60%) create mode 100644 benchmark/BDN.benchmark/Embedded/GarnetServerEmbedded.cs create mode 100644 benchmark/BDN.benchmark/Network/BasicOperations.cs create mode 100644 benchmark/BDN.benchmark/Network/NetworkBase.cs create mode 100644 benchmark/BDN.benchmark/Network/NetworkParams.cs create mode 100644 benchmark/BDN.benchmark/Network/RawStringOperations.cs diff --git a/.github/workflows/ci-bdnbenchmark.yml b/.github/workflows/ci-bdnbenchmark.yml index 25f435b288..82274a6f6f 100644 --- a/.github/workflows/ci-bdnbenchmark.yml +++ b/.github/workflows/ci-bdnbenchmark.yml @@ -88,4 +88,17 @@ jobs: benchmark-data-dir-path: 'website/static/charts' auto-push: true max-items-in-chart: 50 - + + # Run `github-action-benchmark` action for the Continuous Benchmarking Summary + - name: Generate summary for benchmark result + if: github.ref != 'refs/heads/main' + uses: benchmark-action/github-action-benchmark@v1 + with: + name: ${{matrix.test}} (${{matrix.os}} ${{matrix.framework}} ${{matrix.configuration}}) + tool: 'benchmarkdotnet' + output-file-path: ./test/BDNPerfTests/BenchmarkDotNet.Artifacts/results/BDN.benchmark.${{ matrix.test }}-report-full-compressed.json + github-token: ${{ secrets.GITHUB_TOKEN }} + summary-always: true + save-data-file: false + gh-pages-branch: 'continuousbenchmark' + benchmark-data-dir-path: 'website/static/charts' diff --git a/benchmark/BDN.benchmark/BDN.benchmark.csproj b/benchmark/BDN.benchmark/BDN.benchmark.csproj index 525b4edc72..c58c394724 100644 --- a/benchmark/BDN.benchmark/BDN.benchmark.csproj +++ b/benchmark/BDN.benchmark/BDN.benchmark.csproj @@ -21,8 +21,6 @@ - - diff --git a/benchmark/BDN.benchmark/Cluster/ClusterContext.cs b/benchmark/BDN.benchmark/Cluster/ClusterContext.cs index 1ae7fc4540..c6a375ff5c 100644 --- a/benchmark/BDN.benchmark/Cluster/ClusterContext.cs +++ b/benchmark/BDN.benchmark/Cluster/ClusterContext.cs @@ -4,7 +4,7 @@ using System.Runtime.InteropServices; using System.Text; using BDN.benchmark.CustomProcs; -using Embedded.perftest; +using Embedded.server; using Garnet.common; using Garnet.server; diff --git a/benchmark/BDN.benchmark/Embedded/EmbeddedNetworkHandler.cs b/benchmark/BDN.benchmark/Embedded/EmbeddedNetworkHandler.cs new file mode 100644 index 0000000000..e4c7ff866c --- /dev/null +++ b/benchmark/BDN.benchmark/Embedded/EmbeddedNetworkHandler.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +using System; +using System.Diagnostics; +using Garnet.common; +using Garnet.networking; +using Microsoft.Extensions.Logging; + +namespace Embedded.server +{ + internal class EmbeddedNetworkHandler : NetworkHandler + { + public EmbeddedNetworkHandler(GarnetServerEmbedded serverHook, EmbeddedNetworkSender networkSender, NetworkBufferSettings networkBufferSettings, LimitedFixedBufferPool networkPool, bool useTLS, IMessageConsumer messageConsumer = null, ILogger logger = null) : base(serverHook, networkSender, networkBufferSettings, networkPool, useTLS, messageConsumer, logger) + { + } + + public override string RemoteEndpointName => throw new NotImplementedException(); + public override string LocalEndpointName => throw new NotImplementedException(); + public override void Dispose() + { + DisposeImpl(); + } + + public override bool TryClose() => throw new NotImplementedException(); + + public unsafe void Send(byte[] buffer, byte* bufferPtr, int length) + { + networkReceiveBuffer = buffer; + networkReceiveBufferPtr = bufferPtr; + OnNetworkReceive(length); + + // We should have consumed the entire buffer + Debug.Assert(networkBytesRead == 0); + Debug.Assert(networkReadHead == 0); + } + } +} \ No newline at end of file diff --git a/playground/Embedded.perftest/DummyNetworkSender.cs b/benchmark/BDN.benchmark/Embedded/EmbeddedNetworkSender.cs similarity index 95% rename from playground/Embedded.perftest/DummyNetworkSender.cs rename to benchmark/BDN.benchmark/Embedded/EmbeddedNetworkSender.cs index 049f979a39..f6037dd4d3 100644 --- a/playground/Embedded.perftest/DummyNetworkSender.cs +++ b/benchmark/BDN.benchmark/Embedded/EmbeddedNetworkSender.cs @@ -4,12 +4,12 @@ using System.Runtime.CompilerServices; using Garnet.networking; -namespace Embedded.perftest +namespace Embedded.server { /// /// Dummy network sender that reads from a fixed in-memory buffer /// - unsafe class DummyNetworkSender : INetworkSender + internal unsafe class EmbeddedNetworkSender : INetworkSender { /// /// Max size settings of the in-memory sender buffer @@ -34,7 +34,7 @@ unsafe class DummyNetworkSender : INetworkSender /// /// Create a new dummy network sender with a simple in-memory buffer /// - public DummyNetworkSender() + public EmbeddedNetworkSender() { maxSizeSettings = new MaxSizeSettings(); serverBufferSize = BufferSizeUtils.ServerBufferSize(maxSizeSettings); diff --git a/playground/Embedded.perftest/EmbeddedRespServer.cs b/benchmark/BDN.benchmark/Embedded/EmbeddedRespServer.cs similarity index 60% rename from playground/Embedded.perftest/EmbeddedRespServer.cs rename to benchmark/BDN.benchmark/Embedded/EmbeddedRespServer.cs index 2506fd9df7..c94867b102 100644 --- a/playground/Embedded.perftest/EmbeddedRespServer.cs +++ b/benchmark/BDN.benchmark/Embedded/EmbeddedRespServer.cs @@ -5,22 +5,24 @@ using Garnet.server; using Microsoft.Extensions.Logging; -namespace Embedded.perftest +namespace Embedded.server { /// /// Implements an embedded Garnet RESP server /// - public sealed class EmbeddedRespServer : GarnetServer + internal sealed class EmbeddedRespServer : GarnetServer { + readonly GarnetServerEmbedded garnetServerEmbedded; /// /// Creates an EmbeddedRespServer instance /// /// Server options to configure the base GarnetServer instance /// Logger factory to configure the base GarnetServer instance - public EmbeddedRespServer(GarnetServerOptions opts, ILoggerFactory loggerFactory = null) : base(opts, loggerFactory) + /// Server network + public EmbeddedRespServer(GarnetServerOptions opts, ILoggerFactory loggerFactory = null, GarnetServerEmbedded server = null) : base(opts, loggerFactory, server) { - // Nothing... + this.garnetServerEmbedded = server; } /// @@ -31,12 +33,17 @@ public EmbeddedRespServer(GarnetServerOptions opts, ILoggerFactory loggerFactory public StoreWrapper StoreWrapper => storeWrapper; /// - /// Return a RESP session to this server + /// Return a direct RESP session to this server /// /// A new RESP server session internal RespServerSession GetRespSession() { - return new RespServerSession(0, new DummyNetworkSender(), storeWrapper, null, null, true); + return new RespServerSession(0, new EmbeddedNetworkSender(), storeWrapper, null, null, true); + } + + internal EmbeddedNetworkHandler GetNetworkHandler() + { + return garnetServerEmbedded.CreateNetworkHandler(); } } } \ No newline at end of file diff --git a/benchmark/BDN.benchmark/Embedded/GarnetServerEmbedded.cs b/benchmark/BDN.benchmark/Embedded/GarnetServerEmbedded.cs new file mode 100644 index 0000000000..63fe7d90ec --- /dev/null +++ b/benchmark/BDN.benchmark/Embedded/GarnetServerEmbedded.cs @@ -0,0 +1,101 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +using System; +using System.Net.Security; +using System.Threading; +using Garnet.common; +using Garnet.networking; +using Garnet.server; +using Microsoft.Extensions.Logging; + +namespace Embedded.server +{ + internal class GarnetServerEmbedded : GarnetServerBase, IServerHook + { + public GarnetServerEmbedded() : base("0.0.0.0", 0, 1 << 10) + { + } + + public EmbeddedNetworkHandler CreateNetworkHandler(SslClientAuthenticationOptions tlsOptions = null, string remoteEndpointName = null) + { + var networkSender = new EmbeddedNetworkSender(); + var networkSettings = new NetworkBufferSettings(); + var networkPool = networkSettings.CreateBufferPool(); + EmbeddedNetworkHandler handler = null; + + if (activeHandlerCount >= 0) + { + var currentActiveHandlerCount = Interlocked.Increment(ref activeHandlerCount); + if (currentActiveHandlerCount > 0) + { + try + { + handler = new EmbeddedNetworkHandler(this, networkSender, networkSettings, networkPool, tlsOptions != null); + if (!activeHandlers.TryAdd(handler, default)) + throw new Exception("Unable to add handler to dictionary"); + + handler.Start(tlsOptions, remoteEndpointName); + incr_conn_recv(); + return handler; + } + catch (Exception ex) + { + logger?.LogError(ex, "Error starting network handler"); + Interlocked.Decrement(ref activeHandlerCount); + handler?.Dispose(); + } + } + else + { + Interlocked.Decrement(ref activeHandlerCount); + } + } + return handler; + } + + public void DisposeMessageConsumer(INetworkHandler session) + { + if (activeHandlers.TryRemove(session, out _)) + { + Interlocked.Decrement(ref activeHandlerCount); + incr_conn_disp(); + try + { + session.Session?.Dispose(); + } + catch (Exception ex) + { + logger?.LogError(ex, "Error disposing RespServerSession"); + } + } + } + + public override void Start() + { + } + + public bool TryCreateMessageConsumer(Span bytes, INetworkSender networkSender, out IMessageConsumer session) + { + session = null; + + // We need at least 4 bytes to determine session + if (bytes.Length < 4) + return false; + + WireFormat protocol = WireFormat.ASCII; + + if (!GetSessionProviders().TryGetValue(protocol, out var provider)) + { + var input = System.Text.Encoding.ASCII.GetString(bytes); + logger?.LogError("Cannot identify wire protocol {bytes}", input); + throw new Exception($"Unsupported incoming wire format {protocol} {input}"); + } + + if (!AddSession(protocol, ref provider, networkSender, out session)) + throw new Exception($"Unable to add session"); + + return true; + } + } +} \ No newline at end of file diff --git a/benchmark/BDN.benchmark/Lua/LuaRunnerOperations.cs b/benchmark/BDN.benchmark/Lua/LuaRunnerOperations.cs index ecd5002bfb..07d28e641b 100644 --- a/benchmark/BDN.benchmark/Lua/LuaRunnerOperations.cs +++ b/benchmark/BDN.benchmark/Lua/LuaRunnerOperations.cs @@ -2,7 +2,7 @@ // Licensed under the MIT license. using BenchmarkDotNet.Attributes; -using Embedded.perftest; +using Embedded.server; using Garnet.server; namespace BDN.benchmark.Lua diff --git a/benchmark/BDN.benchmark/Lua/LuaScriptCacheOperations.cs b/benchmark/BDN.benchmark/Lua/LuaScriptCacheOperations.cs index c804e0d9ac..a996e45469 100644 --- a/benchmark/BDN.benchmark/Lua/LuaScriptCacheOperations.cs +++ b/benchmark/BDN.benchmark/Lua/LuaScriptCacheOperations.cs @@ -2,7 +2,7 @@ // Licensed under the MIT license. using BenchmarkDotNet.Attributes; -using Embedded.perftest; +using Embedded.server; using Garnet.common; using Garnet.server; using Garnet.server.Auth; diff --git a/benchmark/BDN.benchmark/Network/BasicOperations.cs b/benchmark/BDN.benchmark/Network/BasicOperations.cs new file mode 100644 index 0000000000..f2bbd98b5e --- /dev/null +++ b/benchmark/BDN.benchmark/Network/BasicOperations.cs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +using BenchmarkDotNet.Attributes; + +namespace BDN.benchmark.Network +{ + /// + /// Benchmark for BasicOperations + /// + [MemoryDiagnoser] + public unsafe class BasicOperations : NetworkBase + { + static ReadOnlySpan INLINE_PING => "PING\r\n"u8; + byte[] pingRequestBuffer; + byte* pingRequestBufferPointer; + + public override void GlobalSetup() + { + base.GlobalSetup(); + SetupOperation(ref pingRequestBuffer, ref pingRequestBufferPointer, INLINE_PING); + } + + [Benchmark] + public void InlinePing() + { + Send(pingRequestBuffer, pingRequestBufferPointer, pingRequestBuffer.Length); + } + } +} \ No newline at end of file diff --git a/benchmark/BDN.benchmark/Network/NetworkBase.cs b/benchmark/BDN.benchmark/Network/NetworkBase.cs new file mode 100644 index 0000000000..ee0648ec3e --- /dev/null +++ b/benchmark/BDN.benchmark/Network/NetworkBase.cs @@ -0,0 +1,93 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +using System.Runtime.CompilerServices; +using BenchmarkDotNet.Attributes; +using Embedded.server; +using Garnet.server; + +namespace BDN.benchmark.Network +{ + /// + /// Base class for network benchmarks + /// + public abstract unsafe class NetworkBase + { + /// + /// Parameters + /// + [ParamsSource(nameof(NetworkParamsProvider))] + public NetworkParams Params { get; set; } + + /// + /// Operation parameters provider + /// + public IEnumerable NetworkParamsProvider() + { + yield return new(false); + } + + /// + /// Batch size per method invocation + /// With a batchSize of 100, we have a convenient conversion of latency to throughput: + /// 5 us = 20 Mops/sec + /// 10 us = 10 Mops/sec + /// 20 us = 5 Mops/sec + /// 25 us = 4 Mops/sec + /// 100 us = 1 Mops/sec + /// + const int batchSize = 100; + EmbeddedRespServer server; + EmbeddedNetworkHandler networkHandler; + + /// + /// Setup + /// + [GlobalSetup] + public virtual void GlobalSetup() + { + var opts = new GarnetServerOptions + { + QuietMode = true, + DisablePubSub = true, + }; + + server = new EmbeddedRespServer(opts, null, new GarnetServerEmbedded()); + networkHandler = server.GetNetworkHandler(); + + // Send a PING message to warm up the session + SlowConsumeMessage("PING\r\n"u8); + } + + /// + /// Cleanup + /// + [GlobalCleanup] + public virtual void GlobalCleanup() + { + networkHandler.Dispose(); + server.Dispose(); + } + + protected void Send(byte[] requestBuffer, byte* requestBufferPointer, int length) + { + networkHandler.Send(requestBuffer, requestBufferPointer, length); + } + + protected void SetupOperation(ref byte[] requestBuffer, ref byte* requestBufferPointer, ReadOnlySpan operation) + { + requestBuffer = GC.AllocateArray(operation.Length * batchSize, pinned: true); + requestBufferPointer = (byte*)Unsafe.AsPointer(ref requestBuffer[0]); + for (int i = 0; i < batchSize; i++) + operation.CopyTo(new Span(requestBuffer).Slice(i * operation.Length)); + } + + protected void SlowConsumeMessage(ReadOnlySpan message) + { + var buffer = GC.AllocateArray(message.Length, pinned: true); + var bufferPointer = (byte*)Unsafe.AsPointer(ref buffer[0]); + message.CopyTo(new Span(buffer)); + Send(buffer, bufferPointer, buffer.Length); + } + } +} \ No newline at end of file diff --git a/benchmark/BDN.benchmark/Network/NetworkParams.cs b/benchmark/BDN.benchmark/Network/NetworkParams.cs new file mode 100644 index 0000000000..d754582479 --- /dev/null +++ b/benchmark/BDN.benchmark/Network/NetworkParams.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +namespace BDN.benchmark.Network +{ + /// + /// Network parameters + /// + public struct NetworkParams + { + /// + /// Whether to use TLS + /// + public bool useTLS; + + /// + /// Constructor + /// + public NetworkParams(bool useTLS) + { + this.useTLS = useTLS; + } + + /// + /// String representation + /// + public override string ToString() + { + if (!useTLS) + return "None"; + + var ret = ""; + if (useTLS) + ret += "TLS"; + return ret; + } + } +} \ No newline at end of file diff --git a/benchmark/BDN.benchmark/Network/RawStringOperations.cs b/benchmark/BDN.benchmark/Network/RawStringOperations.cs new file mode 100644 index 0000000000..d58173b1de --- /dev/null +++ b/benchmark/BDN.benchmark/Network/RawStringOperations.cs @@ -0,0 +1,136 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +using BenchmarkDotNet.Attributes; + +namespace BDN.benchmark.Network +{ + /// + /// Benchmark for RawStringOperations + /// + [MemoryDiagnoser] + public unsafe class RawStringOperations : NetworkBase + { + static ReadOnlySpan SET => "*3\r\n$3\r\nSET\r\n$1\r\na\r\n$1\r\na\r\n"u8; + byte[] setRequestBuffer; + byte* setRequestBufferPointer; + + static ReadOnlySpan SETEX => "*4\r\n$5\r\nSETEX\r\n$1\r\nd\r\n$1\r\n9\r\n$1\r\nd\r\n"u8; + byte[] setexRequestBuffer; + byte* setexRequestBufferPointer; + + static ReadOnlySpan SETNX => "*4\r\n$3\r\nSET\r\n$1\r\na\r\n$1\r\na\r\n$2\r\nNX\r\n"u8; + byte[] setnxRequestBuffer; + byte* setnxRequestBufferPointer; + + static ReadOnlySpan SETXX => "*4\r\n$3\r\nSET\r\n$1\r\na\r\n$1\r\na\r\n$2\r\nXX\r\n"u8; + byte[] setxxRequestBuffer; + byte* setxxRequestBufferPointer; + + static ReadOnlySpan GETNF => "*2\r\n$3\r\nGET\r\n$1\r\nb\r\n"u8; + byte[] getnfRequestBuffer; + byte* getnfRequestBufferPointer; + + static ReadOnlySpan GETF => "*2\r\n$3\r\nGET\r\n$1\r\na\r\n"u8; + byte[] getfRequestBuffer; + byte* getfRequestBufferPointer; + + static ReadOnlySpan INCR => "*2\r\n$4\r\nINCR\r\n$1\r\ni\r\n"u8; + byte[] incrRequestBuffer; + byte* incrRequestBufferPointer; + + static ReadOnlySpan DECR => "*2\r\n$4\r\nDECR\r\n$1\r\nj\r\n"u8; + byte[] decrRequestBuffer; + byte* decrRequestBufferPointer; + + static ReadOnlySpan INCRBY => "*3\r\n$6\r\nINCRBY\r\n$1\r\nk\r\n$10\r\n1234567890\r\n"u8; + byte[] incrbyRequestBuffer; + byte* incrbyRequestBufferPointer; + + static ReadOnlySpan DECRBY => "*3\r\n$6\r\nDECRBY\r\n$1\r\nl\r\n$10\r\n1234567890\r\n"u8; + byte[] decrbyRequestBuffer; + byte* decrbyRequestBufferPointer; + + public override void GlobalSetup() + { + base.GlobalSetup(); + SetupOperation(ref setRequestBuffer, ref setRequestBufferPointer, SET); + SetupOperation(ref setexRequestBuffer, ref setexRequestBufferPointer, SETEX); + SetupOperation(ref setnxRequestBuffer, ref setnxRequestBufferPointer, SETNX); + SetupOperation(ref setxxRequestBuffer, ref setxxRequestBufferPointer, SETXX); + SetupOperation(ref getfRequestBuffer, ref getfRequestBufferPointer, GETF); + SetupOperation(ref getnfRequestBuffer, ref getnfRequestBufferPointer, GETNF); + SetupOperation(ref incrRequestBuffer, ref incrRequestBufferPointer, INCR); + SetupOperation(ref decrRequestBuffer, ref decrRequestBufferPointer, DECR); + SetupOperation(ref incrbyRequestBuffer, ref incrbyRequestBufferPointer, INCRBY); + SetupOperation(ref decrbyRequestBuffer, ref decrbyRequestBufferPointer, DECRBY); + + // Pre-populate data + SlowConsumeMessage("*3\r\n$3\r\nSET\r\n$1\r\na\r\n$1\r\na\r\n"u8); + SlowConsumeMessage("*3\r\n$3\r\nSET\r\n$1\r\ni\r\n$1\r\n0\r\n"u8); + SlowConsumeMessage("*3\r\n$3\r\nSET\r\n$1\r\nj\r\n$1\r\n0\r\n"u8); + SlowConsumeMessage("*3\r\n$3\r\nSET\r\n$1\r\nk\r\n$1\r\n0\r\n"u8); + SlowConsumeMessage("*3\r\n$3\r\nSET\r\n$1\r\nl\r\n$1\r\n0\r\n"u8); + } + + [Benchmark] + public void Set() + { + Send(setRequestBuffer, setRequestBufferPointer, setRequestBuffer.Length); + } + + [Benchmark] + public void SetEx() + { + Send(setexRequestBuffer, setexRequestBufferPointer, setexRequestBuffer.Length); + } + + [Benchmark] + public void SetNx() + { + Send(setnxRequestBuffer, setnxRequestBufferPointer, setnxRequestBuffer.Length); + } + + [Benchmark] + public void SetXx() + { + Send(setxxRequestBuffer, setxxRequestBufferPointer, setxxRequestBuffer.Length); + } + + [Benchmark] + public void GetFound() + { + Send(getfRequestBuffer, getfRequestBufferPointer, getfRequestBuffer.Length); + } + + [Benchmark] + public void GetNotFound() + { + Send(getnfRequestBuffer, getnfRequestBufferPointer, getnfRequestBuffer.Length); + } + + [Benchmark] + public void Increment() + { + Send(incrRequestBuffer, incrRequestBufferPointer, incrRequestBuffer.Length); + } + + [Benchmark] + public void Decrement() + { + Send(decrRequestBuffer, decrRequestBufferPointer, decrRequestBuffer.Length); + } + + [Benchmark] + public void IncrementBy() + { + Send(incrbyRequestBuffer, incrbyRequestBufferPointer, incrbyRequestBuffer.Length); + } + + [Benchmark] + public void DecrementBy() + { + Send(decrbyRequestBuffer, decrbyRequestBufferPointer, decrbyRequestBuffer.Length); + } + } +} \ No newline at end of file diff --git a/benchmark/BDN.benchmark/Operations/BasicOperations.cs b/benchmark/BDN.benchmark/Operations/BasicOperations.cs index 326a5cc548..f49093c22d 100644 --- a/benchmark/BDN.benchmark/Operations/BasicOperations.cs +++ b/benchmark/BDN.benchmark/Operations/BasicOperations.cs @@ -24,7 +24,7 @@ public override void GlobalSetup() [Benchmark] public void InlinePing() { - _ = session.TryConsumeMessages(pingRequestBufferPointer, pingRequestBuffer.Length); + Send(pingRequestBuffer, pingRequestBufferPointer, pingRequestBuffer.Length); } } } \ No newline at end of file diff --git a/benchmark/BDN.benchmark/Operations/OperationsBase.cs b/benchmark/BDN.benchmark/Operations/OperationsBase.cs index be4fa09608..17ab08a6a9 100644 --- a/benchmark/BDN.benchmark/Operations/OperationsBase.cs +++ b/benchmark/BDN.benchmark/Operations/OperationsBase.cs @@ -3,7 +3,7 @@ using System.Runtime.CompilerServices; using BenchmarkDotNet.Attributes; -using Embedded.perftest; +using Embedded.server; using Garnet.server; using Garnet.server.Auth.Settings; @@ -53,6 +53,7 @@ public virtual void GlobalSetup() { QuietMode = true, EnableLua = true, + DisablePubSub = true, }; if (Params.useAof) { @@ -73,7 +74,9 @@ public virtual void GlobalSetup() File.WriteAllText(aclFile, @"user default on nopass -@all +ping +set +get +setex +incr +decr +incrby +decrby +zadd +zrem +lpush +lpop +sadd +srem +hset +hdel +@custom"); opts.AuthSettings = new AclAuthenticationPasswordSettings(aclFile); } - server = new EmbeddedRespServer(opts); + + server = new EmbeddedRespServer(opts, null, new GarnetServerEmbedded()); + session = server.GetRespSession(); } finally { @@ -94,6 +97,11 @@ public virtual void GlobalCleanup() server.Dispose(); } + protected void Send(byte[] requestBuffer, byte* requestBufferPointer, int length) + { + _ = session.TryConsumeMessages(requestBufferPointer, length); + } + protected void SetupOperation(ref byte[] requestBuffer, ref byte* requestBufferPointer, ReadOnlySpan operation) { requestBuffer = GC.AllocateArray(operation.Length * batchSize, pinned: true); diff --git a/benchmark/BDN.benchmark/Operations/RawStringOperations.cs b/benchmark/BDN.benchmark/Operations/RawStringOperations.cs index 7ccc92abfb..16592ffa95 100644 --- a/benchmark/BDN.benchmark/Operations/RawStringOperations.cs +++ b/benchmark/BDN.benchmark/Operations/RawStringOperations.cs @@ -76,61 +76,61 @@ public override void GlobalSetup() [Benchmark] public void Set() { - _ = session.TryConsumeMessages(setRequestBufferPointer, setRequestBuffer.Length); + Send(setRequestBuffer, setRequestBufferPointer, setRequestBuffer.Length); } [Benchmark] public void SetEx() { - _ = session.TryConsumeMessages(setexRequestBufferPointer, setexRequestBuffer.Length); + Send(setexRequestBuffer, setexRequestBufferPointer, setexRequestBuffer.Length); } [Benchmark] public void SetNx() { - _ = session.TryConsumeMessages(setnxRequestBufferPointer, setnxRequestBuffer.Length); + Send(setnxRequestBuffer, setnxRequestBufferPointer, setnxRequestBuffer.Length); } [Benchmark] public void SetXx() { - _ = session.TryConsumeMessages(setxxRequestBufferPointer, setxxRequestBuffer.Length); + Send(setxxRequestBuffer, setxxRequestBufferPointer, setxxRequestBuffer.Length); } [Benchmark] public void GetFound() { - _ = session.TryConsumeMessages(getfRequestBufferPointer, getfRequestBuffer.Length); + Send(getfRequestBuffer, getfRequestBufferPointer, getfRequestBuffer.Length); } [Benchmark] public void GetNotFound() { - _ = session.TryConsumeMessages(getnfRequestBufferPointer, getnfRequestBuffer.Length); + Send(getnfRequestBuffer, getnfRequestBufferPointer, getnfRequestBuffer.Length); } [Benchmark] public void Increment() { - _ = session.TryConsumeMessages(incrRequestBufferPointer, incrRequestBuffer.Length); + Send(incrRequestBuffer, incrRequestBufferPointer, incrRequestBuffer.Length); } [Benchmark] public void Decrement() { - _ = session.TryConsumeMessages(decrRequestBufferPointer, decrRequestBuffer.Length); + Send(decrRequestBuffer, decrRequestBufferPointer, decrRequestBuffer.Length); } [Benchmark] public void IncrementBy() { - _ = session.TryConsumeMessages(incrbyRequestBufferPointer, incrbyRequestBuffer.Length); + Send(incrbyRequestBuffer, incrbyRequestBufferPointer, incrbyRequestBuffer.Length); } [Benchmark] public void DecrementBy() { - _ = session.TryConsumeMessages(decrbyRequestBufferPointer, decrbyRequestBuffer.Length); + Send(decrbyRequestBuffer, decrbyRequestBufferPointer, decrbyRequestBuffer.Length); } } } \ No newline at end of file diff --git a/playground/Embedded.perftest/Embedded.perftest.csproj b/playground/Embedded.perftest/Embedded.perftest.csproj index 24f3eb3ee2..1bb09ceed3 100644 --- a/playground/Embedded.perftest/Embedded.perftest.csproj +++ b/playground/Embedded.perftest/Embedded.perftest.csproj @@ -9,6 +9,13 @@ false + + + + + + + diff --git a/playground/Embedded.perftest/EmbeddedPerformanceTest.cs b/playground/Embedded.perftest/EmbeddedPerformanceTest.cs index 8cf9e277f0..e7eaf898c8 100644 --- a/playground/Embedded.perftest/EmbeddedPerformanceTest.cs +++ b/playground/Embedded.perftest/EmbeddedPerformanceTest.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Runtime.CompilerServices; using System.Threading; +using Embedded.server; using Microsoft.Extensions.Logging; namespace Embedded.perftest diff --git a/playground/Embedded.perftest/Program.cs b/playground/Embedded.perftest/Program.cs index fd2713779d..914ab0b170 100644 --- a/playground/Embedded.perftest/Program.cs +++ b/playground/Embedded.perftest/Program.cs @@ -3,6 +3,7 @@ using System; using CommandLine; +using Embedded.server; using Garnet.common; using Garnet.server; using Microsoft.Extensions.Logging; diff --git a/test/Garnet.test/Garnet.test.csproj b/test/Garnet.test/Garnet.test.csproj index f60804d6c9..cb119533fc 100644 --- a/test/Garnet.test/Garnet.test.csproj +++ b/test/Garnet.test/Garnet.test.csproj @@ -11,6 +11,7 @@ + @@ -23,7 +24,6 @@ - diff --git a/test/Garnet.test/RespSortedSetTests.cs b/test/Garnet.test/RespSortedSetTests.cs index 04311a99aa..3abfaa67c2 100644 --- a/test/Garnet.test/RespSortedSetTests.cs +++ b/test/Garnet.test/RespSortedSetTests.cs @@ -6,7 +6,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using Embedded.perftest; +using Embedded.server; using Garnet.common; using Garnet.server; using NUnit.Framework; @@ -97,7 +97,7 @@ public unsafe void SortedSetPopTest() db.SortedSetAdd("key1", "a", 1); db.SortedSetAdd("key1", "b", 2); - var session = new RespServerSession(0, new DummyNetworkSender(), server.Provider.StoreWrapper, null, null, false); + var session = new RespServerSession(0, new EmbeddedNetworkSender(), server.Provider.StoreWrapper, null, null, false); var api = new TestBasicGarnetApi(session.storageSession, session.storageSession.basicContext, session.storageSession.objectStoreBasicContext); var key = Encoding.ASCII.GetBytes("key1"); fixed (byte* keyPtr = key)