Making Globally Distributed Systems easier with Leadership elections in .NetCore

Recently I’ve been looking at how to ensure services are always running globally across a number of data centres.

Why would you want to using Leadership elections to do this?

I’ll cover this at a very high level, for more detail look at articles like this, this I also highly recommend the chapter covering this in Google’s Site Reliability Engineering book.

I want the service to remain available during outages which affecting a particular node or DC.

To do this you have two options, active-active services, where all DC’s can serve all traffic, or active-passive, where one DC or Node is a master and the others are secondary’s. There is also a halfway house but we’ll leave that for now.

The active-active example is better for some scenarios but comes at a cost, data replication, race conditions and synchronisation require careful thought and management.

For a lot of services the idea of a master node can greatly simplify matters. If you have a cluster of 3 machines spread across 3 DCs and they consistently elect a single, healthy, master node which orchestrates requests – things can get nice and simple. You always have 1 node running as the master and it moves around as needed, in response it issues.

The code it runs can be written in a much simpler fashion (generally speaking). You will only ever have one node executing it, as the elected master, so concurrency concerns are removed. The master can be used to orchestrate what the secondaries are doing or simple process requests itself and only use a secondary if it fails. Developers can write, and more importantly test, in a more managable way.

Now how does this affect scaling a service? Well you can now partition to scale this approach. When your single master is getting top hot you can now split the load across two clusters. Each responsible for a partition, say split by user id. But we’ll leave this for another day.

So how do we do this in .Net?

Well we need a consensus system to handle the election. I chose to use an etcd cluster deployed in multiple DCs, others to consider are Consul and Zookeeper. Lets get into the code..

Continue reading

Azure, Coding, How to

Fixing ASPNET Production Issues by adding custom data to App Insights logs

Debugging issues in production is hard. Things vary – seemingly identical requests to the same URL could be made but one succeed and the other fail.

Without information about the context and configuration it’s hard to isolate issue, here is a quick way to get more of that context.

The key is having the data to understand the cause of the failures. One of the things we do to help that is creating our own ITelemetryInitializer for application insights.

In this we track which environment the request was made in, the cloud instance handling the request, code version, UserId and lots more.

This means, if an issue occurs, we have a wealth of data to understand and debug the issue. It’s embedded in every telemetry event tracked.

Here is an example of a Telemetry Initializer which adds the UserID and Azure WebApps Instance Id to tracked events, if a user is signed in. You’ll find, once you start using this you’ll add more information over time.

To get it setup register it, like this, in your Startup.cs:


Go do it now, seriously you’ll need it later!

Azure, Thoughts

Building a SaaS App from your Boxed Software – Pricing, Profit, Architecture and Performance

While working as a consultant I spent time with a number of large companies helping them move from a tradition boxed software model to providing SaaS applications.

One of the first hurdles to overcome is the pricing model for their new SaaS app and the cultural change to pricing SaaS apps vs traditional boxed software.

In the old world the sales, product and marketing team would have a discussion about the value proposition of the product, take into account cost of creating the code, understand the price elasticity and market demand.

Once that’s done the dev team would produce a machine minimum spec required to run the solution and burn the code to a disk or zip up a download for the customers.

At that point all is done, trouble would brew if future versions needed significantly higher spec hardware. That might put pressure on a dev team to optimize but the pricing decision wasn’t part of this process.

Now let’s look at this is a SaaS world, the pricing discussions has to take into account the running costs of hosting the solution. There are two approaches at this point, ignore this completely and continue down the old path OR treat this as a lever you can control and use it to make the product more successful.

Let’s take two examples of decisions that now, in the SaaS world, have a huge impact on the cost of running your solution and, ultimately, your profit margin.

Continue reading