Sitemap

Part 1 — Introduction to distributed systems

9 min readJun 3, 2020

In this blog series I will try to explain what are distributed systems, why do we need such complex systems in the first place, what are the challenges they solve, and what are the various complexities they bring along with them. First, we will try to understand things from a beginner’s perspective, and then later on in this series, we will try to drill down into a bit more detail about the distributed system’s complexities and ways to tackle them.

So, Let’s begin by understanding our traditional Monolithic Architecture and its several usages.

What is Monolith?

A Wikipedia definition of monolith says

“Monolith is a geological feature consisting of a single massive stone or rock, such as some mountains, or a single large piece of rock placed as, or within, a monument or building

Press enter or click to view image in full size
Monolith of Ramanagara

In simple words, Monolith means composing everything in a single piece.

What is Monolithic architecture?

Monolithic architecture is a traditional application development architecture where all components of an application are unified together in a single codebase. Such applications can have multiple modules, they can be divided into n tiers where each tier can have a different role to play, but in the end, it will have a single build system that builds an entire application and its dependencies and will output a single executable or deployable binary (including dependent binaries). In other words, it’s a centralized system whose state is stored on a single computer. Even today 90% of the applications that are developed are following Monolithic architecture.

Press enter or click to view image in full size
Traditional Monolithic Architecture

What design decisions follow monolithic architecture?

Monolithic applications have to be designed keeping into consideration that an entire application stack will be deployed on a single machine.

What does that mean?

It simply means,

- All our application components will be strongly bound to each other via direct references / binary dependencies.

- There will be a single instance of database that can either be installed on same server or some different server.

- Handling Transactions will not be a concern as there will be a single database instance.

Benefits of using Monolithic architecture

- It’s simple to understand the code and develop.

- It’s easier to maintain code in a single repository.

- Debugging code is like a charm, very easy since all functional components are in a single codebase that are strongly bounded with each other.

- Easily deployable to any single machine / server.

- Testing environment can be setup easily on a single machine. It enables testers to perform end to end testing of an entire application from early development phase itself.

- It becomes simpler to scale your application instance horizontally and deploy in multiple machines. A load balancer can be added as an entry point to distribute traffic among them. (we will be discussing in detail about scaling and Load balancers in other part of this series)

Trade-offs for monolith architecture

- If due time when any application gets too large then,

It becomes tedious to maintain it in a single repository. Imagine maintaining all functionalities of amazon within one repo such that even if you have to make a small change you will have to checkout the entire repository. Its close to impossible unless you are someone like google who have a tool that do partial checkout of only that part of code that you want to work with.

Continuous integration and deployment becomes time consuming.

- Too much technology dependent, all functional components have to be coded in same programming language using same development framework.

- Have to redeploy entire application on every small or big update.

- Have to scale entire application even if a single components has more transaction throughput requirement.

- Failure of even a single functionality can bring down an entire application due to its tight coupling of components.

Now we are well versed with Monolithic architecture, its usages, and its trade-offs. So, now let’s talk about what is all about this so-called Microservice architecture, or in other words why do we require to deploy our applications in a more than one machine (Distributed system architecture)?

Distributed Microservices Architecture

First, let’s try to understand a bit about Microservices.

What is Microservice?

A Wikipedia definition of microservice says,

Microservices is a technique or a variant of Service Oriented Architecture (SOA) structural style, that arranges an application as a collection of loosely coupled fine-grained services

In simple words, Microservice architecture is an approach in which a large application is built by developing several small loosely coupled modular components that can be independently deployable and can communicate with each other over a network. For example, if we are developing an e-commerce website then we can think of different components like Authorization service, Products service, Recommendation service, Shopping Cart Service, Payment Service and many more, and all these services can communicate among themselves to fulfill the functional needs of an entire web application.

Press enter or click to view image in full size
Distributed Microservices Architecture

These services can also be treated as different processes running on the same or different servers that communicate over the network.

Advantages of Microservice

- Scaling becomes easy now as each and every microservice can be scaled independently based on the throughput / query per second load it has to bear. Example, if we want to scale only products service we can do that now.

- Services are designed to be Autonomous in nature.

- Deployments becomes faster and easier, since code has reduced significantly an services are now autonomous and independent hence, can be deployed easily.

- Improved Testability since each component is independent of others, so they can be tested independently as well.

- Technology Independent and faster development, multiple teams can work on different components independently and in parallel and at the same time they can use any programming language of their choice for development of their respective component. This is what has helped many startups in becoming the fastest growing technological centers in the world, Because now they were able to on-board more developers to work on different components of the same application more independently in their choice of programming language in and efficient way.

- Improved Fault tolerance, if there is an issue in a single microservice, then it won’t impact entire application.

There can be several other smaller or bigger advantages that we will be discussing later in this series. But for the time being, let’s talk about the trade-offs involved when we choose microservices as our application’s design architecture.

Trade-offs

- Increased infrastructure Complexity, let’s say you have five different components, so now all these components can be deployed on five servers, or will be running in five different processes, this increases the infra cost as well as brings with it many other complexities like,

— Distributed Transactions

— Distributed Locks

— Distributed Unique Id generation

— Service Registries, to keep track of all servers and their respective service.

- Increased Latency, since now all different services are communicating over network, the latency / response time of each call is relatively increased.

- End to End Testing now becomes a pain since different components have to be deployed and entire infrastructure has to be setup now to enable end to end testing for entire application.

- Debugging application becomes relatively hard when you have to debug some external calls.

- Inter service communication has to be implemented by developers. Maintaining that becomes an overhead if any API or contract changes in one microservice then that may require changes in other dependent microservice as well. All this to work efficiently requires lot of coordination between different teams.

Now we know about the advantages and trade-offs of both monolithic applications and microservices. So, let’s discuss what role does Distributed Systems play in all these.

What is a Distributed System?

In simple words, all these microservices when distributed to multiple systems / servers / nodes / computers in an interconnected way and have the ability to communicate reliably with each other in order to fulfill unified common goal, then such complex systems are known as Distributed Systems.

A single application can be distributed across multiple functional components. These components can be deployed across multiple servers. These servers can be deployed across multiple geographical locations and each geographical location can have multiple data centers. The ultimate goal of such a complex distributed system is to enable the scalability, performance, and high availability of applications.

Few well-known examples of distributed systems are,

- Domain Name Servers (DNS), Lookup table for all domains and their respective server Ip address, widely distributed all across the world on multiple servers, working together to serve any domain lookup from any part of the world in as fast as few milliseconds.

- Email Servers, multiple distributed email server working together to ensure reliable email to and fro SMTP communication.

- Websites like Google or Facebook, massively uses distributed systems to scale their services, distribute them to different part of the world for better and faster accessibility, all time availability and more reliability.

- Distributed File Systems, like Hadoop (earlier know as Google Distributed File System), that is designed to works with multiple petabytes of data / files stored across thousands of nodes in a cluster. All these nodes work collaboratively to solve various Big Data challenges and can scale pretty well.

Several other companies are currently using complex distributed systems to fulfill their goals of providing the best possible service and user experience. Some of the famous examples are YouTube, Uber, Netflix, Ola, Amazon, Flipkart, Paypal, Google maps, Dropbox, TinyUrl, Google Drive, cloud providers like AWS /Azure, etc. By designing such complex systems, these companies can handle humongous throughput of read & write requests per second to ensure complete reliability for their customers utilizing their services. Many Cloud operators even ensure a Service Level Agreement(SLA) of providing up to 99.999% of monthly up-time (this means max 25 seconds of service downtime per month) that is close to impossible to achieve, Isn’t it !! Just imaging if any data center or server fails then somehow they need to make sure that services are up and running again within the next 25 seconds.

Let’s talk about a few basic principles that architects keep in mind while designing applications for distributed systems.

- Availability, all services should be highly available, if one server is down then there should always be other servers with same instance running to back it up. This can be considered in terms of data in databases as well.

- Low Latency, all services are distributed across different computers and they communicate with each other over network, so latency will obviously be there, but a good system design should be such that there should be minimum latency in serving any request to the client.

- Consistency, database is the major and most complex part of distributed systems to manage and if its distributed across multiple systems then data consistency becomes a challenge keeping into mind low latency.

- Reliability, all network communication within services should happen reliably without getting lost whether its sent, received or acknowledged.

- Fault Tolerance, node failures should be handled without affecting other principles ensuring load balancer knows about the failed nodes and requests are redirected efficiently to other active nodes while giving time to the failed nodes to recover.

- Partition Tolerance, when data size grows tremendously and it becomes too big to be handled in a single server instance then, data is partitioned into multiple servers using different algorithms (will be discussed later in detail). Any distributed system should be able to handle such scenarios effectively and redirect requests for respective data to respective server.

- Concurrency, since multiple machines are involved, they can process same function at the same time, hence there can be multiple concurrency issues like race condition or trying to access same record at exactly same nano second. Such scenarios have to be handled.

- Access Control, firewalls and other network accessibility configuration is to be done in order to ensure access level security that each node can have while locating and communicating with other nodes in the system.

Hence, we came to an end of this introductory blog for understanding the basics of different architectures and systems.

This can be a lot of learning in beginning but trust me things will get clearer once we start diving deep into this series of distributed systems design. Even if a few concepts are not yet crystal, no need to worry. Distributed systems are a highly complex topic in computer science not only because they solve a lot of problems, but instead because they bring a lot of complexities along with them. Few of those are already discussed above but there are multiple others that we will be discussing further in this blog series and try to understand and solve them one by one.

Thanks a lot !!!

--

--

Akash Agarwal
Akash Agarwal

Written by Akash Agarwal

Right-brained techie, Passionate coder, Senior fullstack developer. Still makes silly mistakes daily. Incase u wanna connect- linkedin.com/in/akash-agarwal-ind

No responses yet