Distributed Architecture: 5 concepts of software distributed systems
For years, developers have been struggling to find the way to create high-scalable projects. When building complex software, they face a plenty of challenges required to be solved. Otherwise, the app is likely to fail and bring no income.
Uber-like applications are capable to handle up to thousands of requests per second and can be easily scaled if necessary. What’s more, users can access the main functionality if some system’s parts are down. So, how to develop such high availability solutions where critical functions work even if something fails?
The answer lies in the distributed architecture. While centralized systems have low availability, scalability, and consistency, distributed software systems provide their high levels. Certainly, the development of distributed systems is more complicated, but the result is worth it.
Distributed software systems can be demonstrated by the client-server architecture, designing the base for multi-tier architectures, which in turn, have functions like presentation, application processing, and data management separated from each other. Alternatives include the broker architecture and Service-Oriented Architecture (SOA).
Add development teams can use different development frameworks to support distributed architectures, for example,.NET, J2EE, CORBA, .NET Web services, AXIS Java Web services, and Globus Grid services.
Middleware is an infrastructure supporting both the creation and execution of distributed software systems and providing a buffer between the network and applications. It’s established in the middle of the system and manages/supports various software system’s components.
Distributed architecture is based on the idea of distributed system concepts such as availability, consistency, durability, idempotency, and persistence. When the application complies with these concepts, it can easily withstand high loads, process thousands of requests per second, have all operations correctly made, and all messages successfully delivered.
Distributed system concepts
High availability means the percentage of time the service is operational. It is one of the most important characteristics of successful software. Though developers dream about achieving 100% availability, it can be very challenging and expensive. Even such large and complex systems as Gmail and the VISA card network don’t provide 100% availability.
Distributed software systems are often designed on top of machines with a lower level of availability. To develop an application with 99.99% availability you can use machines/nodes that have the four nines availability.
Also, a good way to achieve it is to add a bunch of machines/nodes into the cluster. It will enable to ensure an effective system’s functioning even if some of the nodes are down.
Consistency is one of the main distributed system concepts and elements of highly available systems. In a consistent system, all nodes see and return the same information simultaneously. In order to ensure that all nodes have the same data, they need to exchange messages and work in synchronization.
However, in speaking of data communications between nodes, some difficulties may arise. For example, messages’ delivery may fail, or messages may get lost, or some nodes may be unavailable at some point.
Generally, the weaker the required level of consistency, the faster the system can work – but at the same time the higher chances that it won’t return the latest dataset.
When building a consistent system, you need to decide what level of consistency it needs to have. In some cases, some system’s parts must have strongly consistent data. For instance, when you need to keep information about payments’ initiation in a highly consistent way. For other parts that aren’t so important, the level of consistency can be a bit lower.
Idempotency means that the actual event execution will occur only one time regardless the number of times a specific request is executed. By providing a high level of idempotency, developers manage to avoid bad consequences of dropped connections, request errors, and more.
For example, if the customer tries to make a payment but nothing happens, he/she could try again. When the system is idempotent, the payment will be charged only one time, while non-idempotent systems don’t guarantee the lack of double charges and users returning their money back.
So, to develop a software system with lossless message/data delivery, you need to ensure idempotency. For that, you can integrate versioning and optimistic locking, where the systems implement idempotency by applying a strongly consistent storage as their data source.
4. Data durability
Durability is one of the key concerns of distributed software systems. It means that once data is added to the data storage, they will be available in the future, even if the some system’s nodes are offline or have their data corrupted.
Different distributed databases have different levels of data durability. Some databases support data durability at the machine/node level, some of them maintain it at the cluster level, and some don’t offer this functionality out of the box.
Data durability takes an important role when developing high-scalable applications able to process millions of events per day. In many cases, product owners/companies can’t allow data loss, especially when dealing with transactions and other critical operations. That’s why developers need to strongly focus on providing a high level of data durability.
Nowadays, most distributed data storage services, e.g. Cassandra, MongoDB, and Dynamodb, offer durability support at different levels and can be all configured to ensure data durability at the cluster level.
5. Message Persistence
When the node which is processing a message goes offline or some other failure happens, there is a risk that a message will be lost. Message persistence implies that the message is saved and will be processed after the issue is solved.
Message persistence is one of the most important characteristics of a quality application. However, to implement the system protected from losses, for example, a messaging app with billions of users or an Uber-like app with millions of payments per day, is quite difficult and requires proven technologies and developers’ expertise.
The creation of a messaging system that delivers a message at least one time and the implementation of a lossless cluster can become a solution to this challenge.
In speaking of distributed software systems, messaging is generally ensured by some distributed messaging service like RabbitMQ or Kafka, supporting various levels of reliability in delivering messages. In our work, we use RabbitMQ as it proved itself to be a great tool for providing a successful delivery with no losses.
Scaling of a distributed architecture
You never know what will happen with your software system tomorrow. Perhaps, the number of users will increase hundreds of times as some minor feature has unexpectedly gained huge success! Or you will need to expand your project as your business is growing.
At one time, the existing system will be unable to handle increasing loads and you’ll need to add more capacity. When developing distributed software systems, first and foremost you should focus on providing high scalability. There are two main scaling strategies – vertical and horizontal.
Horizontal scaling means the addition of new machines/nodes to the system (cluster) to improve capacity. For now, it’s the most popular way of scaling a distributed architecture. Vertical sharing is essentially about “purchasing a bigger machine/stronger” machine with more cores, increased processing power, and better memory.
As vertical scaling is more expensive, it’s not so popular as horizontal scaling. Also, learn how to create high-performance applications that can be successfully scaled when required.
Most often, distributed software systems need to store much more data, than a single node/machine can do. Sharding is the most used way to store a data set on a certain number of machines.
A database shard is about a horizontal data partition in a database/search engine using some sort of hash to assign to the partition. Each shard is held on a separate database server instance in order to spread load and acts as the single source for the subset of data.
A database shard can be placed on the separate hardware, and various shards can be placed on various nodes/machines. This approach allows a database distribution over multiple machines, which significantly improves performance.
Hope, the article has been useful to you. If you have some questions about the development of a distributed architecture or have a project idea, you’re welcome to apply to a reliable software dev company.
Having large expertise in delivering high-quality applications that withstand high loads and comply with distributed system concepts, we are always ready to provide you with smart recommendations to your project!