Welcome back to my journal, where I’ve been documenting my experience of building a geo-distributed app in Java from scratch. In the previous article, I broke down the definition of geo-distributed apps. If you missed that part of the journey, turn the “page” back to catch up.
Today, I’ll compare and contrast geo-distributed apps with regular apps (the sort of apps you deploy within a single data center or availability zone).
To understand the difference and find similarities, I need to drill down into the building blocks (architecture) of a typical geo-distributed app. So, if you’re with me on this journey, then, as the pirates used to say - “All Hand Hoy!” which means “Everyone on deck!”
What are the main building blocks (architecture) of a geo-distributed app? The answer will surprise you!
Fundamentally, the architecture is the same as with regular applications. A geo-distributed app comes with data and application layers, just as you get with a standard app. It might have a dedicated API layer and consist of several micro-services and it may also use a load balancer to better handle user traffic. It can rely on some middleware and…the list goes on and on!
So, what's the big difference then? Well, the key to the right answer is engraved in the definition of the geo-distributed apps:
A geo-distributed app is an app that spans multiple geographic locations for high availability, resiliency, compliance and performance.
All of those building blocks and components have to possess the characteristics in bold. For the sake of simplicity, let's review those characteristics in relation to the data layer, application layer and load balancer. And some visuals might also help!
The Users of a geo-distributed app live around the world. Depending on the app, you might be dealing with users residing in a single continent (or a large part of it) or, literally anywhere else on planet Earth. In our example (above), we have three users. Let’s call them Ms. Blue, Mr. Green, and Mr. Red.
These users open up their laptops, launch a browser and go to the Internet. They type our app address in the browser window and expect to see the app’s page within a few seconds, if not immediately. If the page doesn’t load within 1-3 seconds they would consider the app slow (and may go elsewhere) So, how does the geo-distributed app handle this?
The geo-distributed app in our illustration relies on a global load balancer that receives requests, figures out the sender's location, and forwards the requests to the application instance closest to the user.
The picture shows that Ms. Blue's request is routed to an application instance running in the US West. Mr. Green's to an instance in Europe. And Mr. Red's to an instance in Australia. The closer the application instance to the user, the faster the app can process their request. This is how the global load balancer contributes to the performance characteristic of this geo-distributed app.
But, how does the load balancer help with high availability and reliability?
Imagine that the US West region becomes unavailable, and the load balancer can no longer forward Ms. Blue's requests there. The balancer won't panic. Instead, it will figure out another closest location for Ms. Blue (which should be US East) and start forwarding her traffic there. Automatically!
Alright, let’s move to the application layer of the architecture. This is where the global load balancer forwards a user request.
In the picture you can see that the application layer spans continents. The application can be a monolith or can be split into several micro-services. It doesn’t really matter for now. What’s most important is that multiple instances of the app are running across the globe. I guess it’s already apparent why it’s done this way, so let’s just recap.
Multiple app instances ensure that the geo-distributed app can tolerate various cloud outages, including major incidents. This makes the application layer reliable and highly available. On top of that, with multiple instances, the geo-distributed app can serve user requests at low latency, regardless of the user’s location. This is what makes the app layer performant.
Finally, the application instance selected to serve a user request needs to read data from, or write it to, the data layer (database). With geo-distributed apps, you usually use a distributed database that can scale horizontally. This is why the picture above has multiple database nodes scattered worldwide.
Distributed databases greatly improve the reliability and availability of geo-distributed apps. These databases store redundant copies of data, allowing the app to remain operational during various outages. If a database node becomes unavailable due to a cloud incident, the application requests can be handled by alive and healthy nodes.
From a performance standpoint, the closer the user data to the application instance, the better. You don’t want an application instance from Sydney handling requests for Mr. Red to go to a database node in Asia or South America. Right? Right! With distributed databases, it’s possible to arrange data close to the user’s location, minimizing latencies.
Importantly, the ability to place user data in specific locations also enables the geo-distributed app to comply with data residency requirements. GDPR is a serious thing. So, when the global load balancer forwards Mr. Green’s requests to an app instance in Europe, the instance has to read personal data from and write it to the database node(s) deployed in the European Union.
That’s it. As you see, the architecture of a geo-distributed app comes with the same components you use in regular applications - including the data layer, application layer, and load balancer. The only difference is, in the case of the geo-distributed apps all of those components have to function across several distant locations.
Still confused? Any questions? Nudge me in the comments and we’ll get things sorted together!
Alright, with this article I’ve finished discussing the basic concepts related to geo-distributed applications. Now you know what beast a geo-distributed app is, and what components it includes.
What do we have coming up next?
Well, I’ll introduce you to my first geo-distributed app prototype. It’s still raw, but that’s OK as long as there’s a foundation to build upon on.
This is a Java web application built on the Vaadin framework and deployed in Heroku. The database is YugabyteDB. The prototype functions within a single cloud region, but across multiple availability zones.