Microsoft Orleans – is it fast?

Microsoft Orleans is a developer-friendly framework for building distributed, high-scale computing applications. It does not require from developer to implement concurrency and data storage model. It requires developer to use predefined code blocks and enforces application to be build in a certain way. As a result Microsoft Orleans empowers developer with a framework with an exceptional performance.

Orleans proved its strengths in many scenarios, where the most recognizable ones are cloud services for Halo 4 and 5 games.

You can have a look at full introduction in my previous post: Getting started with Microsoft Orleans

The Scenario

To test the performance of Microsoft Orleans I’ll compare it to simple micro-service implementation. The scenario is about transferring money from one account to another using a persistent storage. Here is the idea:

  • Both services will use .Net Core
  • Data will be saved in Azure CosmosDB database
  • Services will read and send messages from Service Bus
  • One message will trigger transferring money, that will need to get and save data from DB and then service will send two messages with account balance updates

Simple Micro-service approach

This app is really simple. It is a console application, that registers message handler and processes messages. This is how architecture looks like, simple right?

Code that handles message looks like this:

TableStorageService is used to synchronize state with the database, which in this case it read and update account balance.

DocumentClient is CosmosDB client provided by the framework. You might be intrigued by try-catch clause. Currently for in CosmosDB package for .Net Core there is no way to check if the document exists and the proposed solution is to handle an exception when the document is not found. In this case, the new document will be created. NotifyBalanceUpdate sends messages to Service Bus.

When we go to Azure portal, we can query the data to check if it is really there:

This is how reading 100 messages looks like:

Microsoft Orleans approach

Microsoft Orleans is an actor framework, where each actor can be understood as a separate service, that does some simple operations and can have its own state. In this case, every account can be an actor, it doesn’t matter if we have few or few hundred thousands of them, the framework will handle that. Another big advantage is that we do not need to care about concurrency and persistence, it is also handled by the framework for us. In Orleans, accounts can perform operations in parallel.  In this case, the architecture looks much different.

Project structure looks like this:

  • SiloHost – sets up and run a silo to host grains, which is just another name for actors
  • OrleansClient – second application. This one connects to the silo and run client code to use grains
  • AccountTransfer.Interfaces – its an abstraction for grains
  • AccountTransfer.Grains – grains implementation, that handles business logic

Let’s have a look at how running a silo looks like:

This is the whole code. Amazingly short comparing to what we are doing here. Notice, that configuring CosmosDB Azure Table storage takes just a few lines. I even configured dependency injection that I will use in account grain.

This is how connecting to silo looks like:

This is also a simple console application. Both apps need to be run together, cause client is connecting to the silo and if fails, tries again after few seconds. The only part missing here is DoClientWork method:

This is almost the same code that we had in micro-service approach. We are reading Service Bus messages and deserialize them, but then we use actors. From this point execution will be handled by them. AccountGrain looks like this:

Notice that on top we have serializable Balance class. When defining actor like this: AccountGrain : Grain<Balance>, it means that Balance will be our state, that we can later refer to as this.State. Getting and updating state is trivial, and both Withdraw and Deposit causes sending Service Bus message by calling NotifyBalanceUpdate.

In Azure portal we can have a look how data is saved. I choose to serialize it to json, so we can see account state easily:

Let’s have a look at reading 1000 messages by a single thread with Microsoft Orleans looks like:

It runs noticeably faster, but what’s more interesting is that we can read messages with even 20 concurrent threads at a time:

Comparsion

As you could see, I used two approaches to read and process 100 and 1000 Service Bus messages, written in .net core with a persistant state in remote CosmosDB database. Results can be seen here:

Blue color represents reading 100 messages, red represents reading 1000 messages. As you can see Microsoft Orleans is a few times faster.

To sum up, using Microsoft Orleans:

Pros:

  • Microsoft actor framework could give you outstanding performance
  • It requires minimal knowledge to write your first app
  • Documentation is great
  • The code is open source, you can post issues

Cons:

  • It doesn’t fit every scenario
  • Maintenance and deployment is a bit more difficult than a simple IIS app

 

If you’re interested in the code, have a look at my GitHub:

 

One thought on “Microsoft Orleans – is it fast?

  1. Pingback: dotnetomaniak.pl

Leave a Reply

Your email address will not be published. Required fields are marked *