Skip to content

Commit 5e744ff

Browse files
Update Akka.Remote performance guidance for Akka.NET v1.4.14 (#4703)
* stubbing out performance documentation per #4685 * close #4685
1 parent 58294a4 commit 5e744ff

File tree

1 file changed

+58
-4
lines changed

1 file changed

+58
-4
lines changed

docs/articles/remoting/performance.md

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,61 @@ If you're building a large-scale system using Akka.NET, the performance of Akka.
99

1010
Akka.NET is [horizontally scalable using Akka.Cluster](../clustering/cluster-overview.md), meaning that Akka.NET applications typically respond to surges in demand by scaling up and down the number of nodes inside the network - however, ensuring that the messages per node throughput is consistently high will give you the most value on a per-node basis.
1111

12-
## Optimizing the DotNetty TCP Transport
12+
## Akka.NET v1.4.14 and Later
13+
In Akka.NET v1.4.14 we introduced a [self-optimizing batching system for DotNetty](https://github.com/akkadotnet/akka.net/pull/4685), which means that end-users no longer manually need to specify explicit batching thresholds in their configuration. The default DotNetty transport for Akka.NET will now automatically group and ungroup batches in a manner that reduces latency for light workloads and increases throughput for heavy workloads automatically without any need for tuning.
14+
15+
### Performance Comparison
16+
Here is how Akka.NET v1.4.14 performs with batching enabled (it's on by default) on an AMD Ryzen 7 1700 Eight Core 3.2 Ghz processor running Windows 10 on .NET Core 3.1:
17+
18+
| Num clients (actors) | Total [msg] | Msgs/sec | Total [ms] |
19+
|----------------------|-------------|----------|------------|
20+
| 1 | 200000 | 107759 | 1856.35 |
21+
| 5 | 1000000 | 193312 | 5173.15 |
22+
| 10 | 2000000 | 193611 | 10330.16 |
23+
| 15 | 3000000 | 191657 | 15653.83 |
24+
| 20 | 4000000 | 191645 | 20873.00 |
25+
| 25 | 5000000 | 190462 | 26252.27 |
26+
| 30 | 6000000 | 189281 | 31699.14 |
27+
28+
Versus the numbers with
29+
30+
```
31+
akka.remote.dot-netty.tcp.batching.enabled = false
32+
```
33+
34+
| Num clients (actors) | Total [msg] | Msgs/sec | Total [ms] |
35+
|----------------------|-------------|----------|------------|
36+
| 1 | 200000 | 73341 | 2727.85 |
37+
| 5 | 1000000 | 111745 | 8949.62 |
38+
| 10 | 2000000 | 120475 | 16601.53 |
39+
| 15 | 3000000 | 124559 | 24085.95 |
40+
| 20 | 4000000 | 126343 | 31660.58 |
41+
| 25 | 5000000 | 128469 | 38920.63 |
42+
| 30 | 6000000 | 129163 | 46453.05 |
43+
44+
This is a significant difference - the batching system is around ~47% faster even for low traffic systems.
45+
46+
The way the I/O batching system works is by grouping messages that written in succession together into the socket's outbound byte buffer, via a "flush" system call. System calls are sometimes expensive, so the fewer system calls made in rapid succession, the lower the CPU consumption and the greater the throughput.
47+
48+
The Akka.Remote batching system can be disabled and tuned via the following settings:
49+
50+
```
51+
akka.remote.dot-netty.tcp{
52+
batching{
53+
54+
enabled = true
55+
56+
max-pending-writes = 30
57+
}
58+
}
59+
```
60+
61+
The `max-pending-writes` setting determines the maximum number of writes that can be grouped together before Akka.Remote forces a flush - this is done in order to reduce latency (the amount of time it takes a single write to reach its destination) and to limit the amount of data that needs to be written to the socket all in one go.
62+
63+
## Pre-Akka.NET v1.4.14
64+
The advice below is applicable to all versions of Akka.NET v1.4.14, which is when the self-optimizing batching system was introduced into Akka.Remote.
65+
66+
### Optimizing the DotNetty TCP Transport
1367
The default transport in Akka.Remote is the DotNetty TCP transport, which is a good choice for most Akka.NET developers because TCP preserves message order and guarantees delivery of every message over the wire so long as the network remains available, which is consistent with `IActorRef` default messaging. The same cannot be said for alternative transports such as a UDP transport.
1468

1569
As of Akka.NET v1.4.0-beta4, we've added a new feature to Akka.Remote called a "batch writer" which has tremendously improved the performance of outbound writes in Akka.Remote by grouping many logical writes into a smaller number of physical writes (actual flush calls to the underlying socket.)
@@ -18,7 +72,7 @@ Here are some performance numbers from our [RemotePingPong benchmark](https://gi
1872

1973
These numbers were all produced on a 12 core Intel i7 2.6Ghz Dell laptop over a single Akka.Remote connection running .NET Core 2.1 on Windows 10:
2074

21-
### No I/O Batching
75+
#### No I/O Batching
2276

2377
| Num clients (actors) | Total [msg] | Msgs/sec | Total [ms] |
2478
|----------------------|-------------|----------|------------|
@@ -34,7 +88,7 @@ Average performance: **82,539 msg/s**.
3488

3589
Standard deviation: **46,827 msg/s**.
3690

37-
### With I/O Batching
91+
#### With I/O Batching
3892

3993
| Num clients (actors) | Total [msg] | Msgs/sec | Total [ms] |
4094
|----------------------|-------------|----------|------------|
@@ -54,7 +108,7 @@ Akka.Remote's flush batching system for DotNetty operates on the principle of tr
54108

55109
You can achieve similar results for your application.
56110

57-
### Optimizing Batches for Your Use Case
111+
#### Optimizing Batches for Your Use Case
58112
To take advantage of I/O batching in DotNetty, you need to [tailor the following Akka.Remote configuration values to your use case](../../configuration/akka.remote.md):
59113

60114
```

0 commit comments

Comments
 (0)