Can you guess what’s one of the top IT services pain point list apart from old-generation devices? Yes, you got it right! The lack of scalability.
It’s a common expectation that IT systems will be able to adapt to the changing business demand. In the recent years, practically each new architectural style in IT has claimed to be resolving issues related to managing the increasing scale. How did it go?
The three dimensions of scalability
Before we verify that, let’s start with the definition of scaling.
A change of enterprise scale can be considered in three dimensions:
- The volume of data
- The number of interactions
- Functional features
All these dimensions have specific features, and enterprises achieve them to a different degree.
1. Data volume
Data is often perceived as the primary asset establishing the competitive advantage of a company. Businesses in general collect and process an increasing volume of data.
This growth is sometimes well-justified, regardless whether companies use data for current processing or for future reference. For example, companies store resolved customer complaint records for statistical & analytical purposes. They can also use such data for machine learning scenarios. Nevertheless, the trend is clear. The volume of data will continue to grow. Moreover, the IoT revolution will enforce a non-linear increase pattern.
What about data VALUE?
The rapid change in data volume comes as no surprise to anyone. But what about alternating data value?
Although this may not seem obvious, the value of particular records changes over time. A customer’s order information at delivery is valuable for many parties. The integrity and availability of this data directly affect the customer experience. However, the exact same piece of information a few months later is hardly worth anything for most of the interacting parties, yet it should still remain accessible to the customer and customer care staff.
Different data, same database
Despite the above, all customer records continue to be stored in the same operational database after delivery. It is very uncommon to move data collected after purchase to a separate data storage device with reduced availability to help reduce costs.
But why is that? The reason is quite simple. The data structure in databases of huge monolithic systems tends to tie information with numerous integrity constraints. Usually, the architecture of those systems assumes that all data is stored in one database. Splitting data into two or more DBs would entail a substantial architectural change involving high risk and costs.
2. The number of interactions
The ease of communication facilitated by the Internet creates the risk of drastic fluctuations in the number of user interactions with IT systems. Some of them are predictable, while others aren’t.
Companies themselves may generate some of the communication traffic. A common practice in the retail branch is organizing flash sales. A flash sale is a discount or a promotion offered for a very short period. For some companies, a flash sale is a valuable tactic to attract and engage customers. For others, it’s a smart way to clear the end-of-season stock.
Sales are all cheers; IT’s in tears!
The downside for IT is a much higher load on e-commerce websites while flash sales are on than on a regular day. Some companies report a twentyfold increase in traffic after a flash sales. However, there’s a catch (there always is). The critical factor for a successful event is to provide excellent customer service throughout the sale period. Flash sales are only meaningful if they leave customers with a positive perception of your company. Having IT infrastructure ready for the peak and utilizing only five percent during the rest of the year will cost you a lot.
Here’s another example of similar fluctuation in user interactions. Events. Be it cultural, sports, or political. Events are planned, they last a few days or several weeks, and happen once a year or even less frequently. Or natural disasters, an incident that’s completely unpredictable and can quickly get out of hand. The number of interactions with media reps or government sites can soar within minutes. An IT department may have an SLA, sure. But it still does not solve the overload problem that the company may be facing in moments like that.
3. Functional features
The last, but by no means, the least important, dimension of scalability reflects the number and complexity of business functions implemented in IT systems. As a company grows, it is enhancing its systems with a new set of features. New products and services, new channels, and new processes require new functions or modifications of the existing ones. Moreover, the constant pressure from the competition and increasing customer expectations enforce system modifications at an ever-increasing pace.
Same feature, longer time to implement
The reality is that adding new features requires more time than ever. Throughout my career, I have very often come across similar opinions of people who claimed that several years ago implementation of a function of an equal complexity required much less time than now. The ugly truth is that this criticism is well-deserved.
The reason for that is usually the same. Several years ago the size of an application source code was only a fraction of what it is today. Developers who wrote a system a while ago and knew it inside out are not available any more. Currently, software engineers develop only a piece of a system or an application that is a combined effort of collaborative teamwork, and so it takes much longer to design, implement, and test a new feature.
Microservices: delivering scale in three dimensions
We can see that each of the above dimensions has its challenges. How can we resolve some of them? Let’s take a step back.
If small applications are easier and quicker to develop, why not split the huge existing applications into smaller ones of more manageable sizes? Several IT teams practiced that architectural style for a few years and developed its details under the name Microservices Architecture (or MSA for short).
What is Microservices Architecture?
It is an architectural style that structures a system as a collection of loosely-coupled services. In MSA, services should be fine-grained and connected using lightweight network protocols. The benefit of decomposing an application into different smaller services is that it improves modularity and makes each service easier to understand, develop, and test.
How does Microservices Architecture deal with scalability dimensions?
Let me break it down for you.
1. Data volume
One neat feature of MSA is that each microservice may use the type of data storage optimal for its needs. Developers no longer have to use the same database for all data in the system. Nowadays, there are far more options than RDBMS to persist data. In-memory key-value stores, document-, or graph-oriented databases enable you to choose accordingly to your needs and the value of the information stored.
When services are operational, and data is stored, there are no integrity links between entities from different domains in the database layer. Thanks to such approach, one may replace service’s DB technology as needed. With monolith systems, even performing database version upgrades can be very challenging, not to mention changes to vendor or type.
Dedicated services, separate DBs
Let’s go back to our example of customer order records that should remain accessible to a user after an order is complete.
The transaction data must be available, but not for modification, and with reduced availability. In such a case, you can create separate services:
- The first one, based on RDBMS, will be handling orders at delivery. This service will be subject to multiple data modifications and will require high availability. In this case, the value of the information justifies the cost of the active-active replication to a distinct data center.
- The information about past orders can be handled by a dedicated service with a document database that easily supports enormous volumes of data. For this kind of data, longer recovery time after failure is accepted. It also doesn’t require costly solutions that minimize downtime. Moreover, because of the lack of schema, order records can be stored with an evolved model. There is no need for ‘alter table’ operations, which in case of enormous amounts of records in tables cause significant downtime during deployment of changes into the production environment.
2. The number of interactions
Despite the fact that the massive scalability of the number of interactions is somewhat a side effect of microservices, it is sometimes used as an argument to support their adoption.
A system composed of small services, each of them separately deployable on virtually any infrastructure, allows you to immediately react to a sudden surge in parallel interactions. What it also offers is the capability to release a part of infrastructure when it is no longer needed. Of course, for the solution to work properly, it takes a skilled infrastructure team who can adjust the number of servers according to the need. More often than not, cloud adoption becomes imperative in these circumstances. However, without small software components, cloud computing wouldn’t be able to reveal its full potential.
Designed to be scalable
The above benefits derive from dividing systems into smaller components, but not only. Design each subcomponent to meet specific scalability requirements. Keeping in mind the ephemeral nature of the infrastructure, develop all services as stateless, i.e., the state of user conversation may not be retained inside of the run-time environment of a service. You can route all subsequent service invocations to any service instance. The state of the conversation can be stored on the client side or in some highly-available distributed in-memory database.
A nice feature of all leading platforms for running microservices is autoscaling. It can be achieved not only by automating the starting and stopping service instance to assure the needed throughput but also by requesting new servers to be provisioned in a public cloud. Even if the platform of your choice does not deliver this feature, you can quickly add it using the platform API.
3. Functional features
And thus we’ve arrived at the functional scalability, which was the real reason for drifting towards the distributed systems architecture.
The introduction of a functional change in a large system with a codebase including hundreds of thousands of lines inevitably leads to a time-consuming analysis and testing. If this process requires a synchronized change in several systems and the integration layer between them, the situation only worsens.
Divide and rule
The answer to that issue is to divide the system into parts that perform some useful business functions but remain manageable. Each part should contain all layers starting with a user interface, and ending in the persistence layer. This approach is not that different from what the service-oriented architecture proposes, although it emphasizes the decoupling of source code and run-time environment of business function.
What is the guiding principle behind dividing existing monoliths into parts or building new systems? First, it should be usability of the detached part. What I mean by that is usefulness and usability from the user’s perspective, as opposed to the system reusability, which is sometimes counterintuitive.
Usually, highly reusable software components are… useless for the end users. To create a component that is meaningful from the user’s perspective requires the composition of many functions. A functional change involves modification to a greater number of services to obtain the desired effect. Synchronized deployment of dozens of coupled services may be much harder than the deployment of a massive monolith. A change in one commonly used component may result in a cascade of changes in the dependent elements.
Doing away with a distributed monolith
This is a recognized anti-pattern, a so-called ‘distributed monolith.’ A mammoth like that may still enable high scalability in other dimensions, while practically killing the functional scalability. The bounded context, a concept introduced by Eric Evans in his famous book Domain-Driven Design, is extremely helpful in the decomposition of complex systems into independent but functional parts.
Another approach that helps preserve functional scalability is relying on the history of functional change. Aligning component boundaries the way that frequently changes will require modification of only one component. This is an especially useful strategy when breaking down an existing monolith. There are more techniques that help define service boundaries, but they don’t concentrate on reducing time-to-market.
So what do we get in the end? It seems like the architecture is becoming more complex. The architecture diagram is filling in with more and more connected components. The multitude of functions implemented by the system and the relationships between them become conspicuous.
This increase of complexity is, however, illusory.
The complexity has been always there, obscured by the monolith. The difference is that now the underlying structure has surfaced, allowing you to plan a series of minor changes, each of which is easier to code, test, and deploy. The decreased codebase of the system makes it less daunting to modify. The remodeled architecture invites experimentation. Introducing a hazardous change is now less expensive, and easier to track and improve in the next iteration. Dividing the system into smaller components allows you to gain greater control over their development.
Invitation to Microservices Workshop
This article is only a lead-in for further discussion on microservices, cloud, and DevOps. Every organization can benefit from the ‘power-of-the-three’ provided that it selects appropriate solutions and applies the right configuration.
Join us and let’s start building something special together! With BlueSoft engineers, your organization is on the best route to identifying the transformation areas for a microservices introduction. But there’s more.
You will receive our full support in adopting microservices and developing an intelligible and transparent solution.
We are waiting for your call.
Let us know what time and place work best for you.
To schedule a workshop led by Robert our Head of Microservice Architecture, send us an email at: firstname.lastname@example.org
Looking forward to seeing you soon!