Microservices offer a number of benefits, which include helping release software faster, update software more frequently, and add new features more quickly. Microservices provide the flexibility to use different technologies and different programming languages, depending on the organization’s needs. The Microservice philosophy of decentralization effects the management and architecture of data.
The traditional monolithic approach – with data processing, error handling, data input and output, and the user interface all interwoven – saves data using a massive storage system, rather than architecturally separating the components. A standard SQL server using a single database with multiple tables is a good example of a monolithic storage system.
By contrast, Microservice architecture supports decentralized Data Management. Microservice Architecture organizes applications as an assortment of loosely coupled services. This system provides continuous delivery and deployment of large, complex applications. If done correctly, Microservice entities will provide the desired benefits.
Einas Haddad of Uber described Uber’s adoption of Microservices:
“Continuous integration turned into a liability because deploying the codebase meant deploying everything at once. Our engineering team experienced rapid growth and scaling, which not only meant handling more requests but also handling a significant increase in developer activity. We decided to follow the lead of other hyper-growth companies—Amazon, Netflix, SoundCloud, Twitter, and others—and break up the monolith into multiple codebases to form a service-oriented architecture (SOA).”
It should be noted, there are concerns about using Microservices. They rely on polyglot persistence and can be much more difficult to build compared to monolithic systems. (They are easier to work with, not easier to build.) After construction, deployment needs to be developed, as the system now requires a script to function. Microservices on the Cloud will often incorporate automated scaling and load balancing services, and this may cause development teams to become reliant on certain Cloud providers.
The basic purpose of a Microservice entity is to “Focus on one task, and do it well.” A Microservice can be described as a tightly focused, flexible software program “entity” that is compatible with any other application. A shipping Microservice entity does not care which application requests an item be shipped to a client. Microservice entities also do not care about why or what is being shipped. A shipping entity’s only focus is to send an item somewhere, to someone. The Microservice entity is focused and efficient.
Karma Go, an organization that turns a cell or smartphone into a WiFi hotspot, described their experience with Microservices:
“Ultimately, a Microservice works best when it has one, and only one, responsibility — we even wrap most of our third-party dependencies to make sure we don’t have to think about them in other parts of the app. It takes at most a week or two to build or rebuild a Microservice, and changes to other parts of the system don’t necessitate a rewrite of other parts. We have one service we wrote two years ago called ‘Collector’ which we haven’t touched since, other than occasional dependency updates.”
Consider three separate Microservice entities, each highly focused on performing a simple, specific task. One will scan a data silo, searching for the keywords “ultra-thin cells,” “ultra-thin solar cells,” and “perovskite.” The second watches the overall system for glitches and problems, correcting them, as needed. And the third Microservice entity scans the security system, watching for viruses, or suspicious patterns. While these simplistic Microservice entities aren’t actually bright enough to be called Artificial Intelligence, they might evolve in that direction.
Decentralization of Microservices
The philosophy of decentralization used for Microservices suggests two services should not share a data store. Instead, each Microservice entity maintains its own individual data store. Because each Microservice entity organizes its own data, redundancy, consistency, and data integrity are significant concerns. Phil Calçado, of SoundCloud, wrote:
“[T]he team decided that the best approach to deal with the architecture changes would not be to split the Mothership immediately, but rather to not add anything new to it. All of our new features were built as Microservices, and whenever a larger refactoring of a feature in the Mothership was required, we extract the code as part of this effort.”
The specific reason for the rule of decentralization is to avoid accidental couplings between services. This can happen if services share the same foundational data schemas. Any change to the data schema must be coordinated with every service relying on that database. By isolating each Microservice entity’s data store, changes have minimal impact and the agility of independent services is maintained. Another reason for maintaining a separation is that each Microservice may come with its own read/write patterns, data models, or queries.
Maintenance of Microservices
Generally speaking, the maintenance of individual Microservices is easier than maintaining one monolithic application with all services interwoven. Each Microservice entity has been developed and maintained individually within the source repository. Developing a complete, new Microservice entity is fairly easy, and as a consequence, the decomposed architecture allows for functional changes to be made to the application quickly and efficiently. Code reviews and unit testing also become quite easy.
Because a Microservice entity can be updated as an isolated piece of the application, changes offer minimal risk to the rest of the system. In monolithic architecture, more risk is involved. Microservice architecture offers greater availability, because if one Microservice fails, one part of the application fails, not the entire application. On the other hand, a monolithic application makes it easier to maintain consistent coding and error handling. Microservice entities managed by different teams may apply conflicting standards, creating confusion in the process.
Microservices can evolve. In the process, “breaking backwards compatibility” can develop, because it becomes cluttered with code. This refers to a system that has been altered to block backward compatibility when it is needed. Backward compatibility allows for access and interoperability with older systems. Backward compatibility has also been called “downward compatibility.” A Microservice can evolve without getting cluttered with code and can support older versions of itself, as needed.
The distributed approach to managing data may come with some storage problems. The same item of data may be redundantly stored in multiple locations. This can happen when data is included as part of an activity and then stored in another location for analytics, archiving, or reporting. Partitioned or duplicated data can cause problems with data integrity and consistency. In a Microservices architecture, how updates are propagated across different services must be considered with the goal of eventual consistency.
Being able to retrieve stored data is important. Microservice data storage offers a variety of improvements over monolithic systems, in such areas as:
- High availability
- Strong performance
- Low latency security for each interaction and layer of data
- Support for the use multiple programming languages
While developing each area requires careful planning and forethought, Microservices offer greater flexibility than a traditional monolithic system. There is no single path for developing Microservices, but there are general guidelines for managing data within Microservice architectures:
- Locate and embrace eventual consistency, where possible. (Eventual consistency is a model in distributed computing used to achieve high availability. It informally guarantees “eventually” all access to an item will be returned to the last updated value. Eventual consistency is also known as optimistic replication.)
- Transactions patterns, including Scheduler Agent Supervisor and Compensating Transaction, keep data consistent across several services.
- Store only data that a Microservice entity needs. (An entity might need no more than a subset of data about one domain entity.)
- Assure the Microservice entities are loosely coupled and coherent.
The Cloud and Microservices
While Microservices do not require a Cloud to function in, they do work very well within the Cloud. Generally, Microservices complement Cloud Computing, allowing resources to be used efficiently, especially when different services use different performance profiles. Transferring data by way of containers is quite efficient.
Containers are relatively easy to build with Microservice components. The underlying operating system shared by containers can link together, forming one overall application. It is important, however, to point out the differences between containers and Microservices. Containers are a tool used by developers to transport and deploy components used in Microservice applications. The goal is to install components needed for solving a developer’s problems. Additionally, a developer can use load balancing services and performance monitoring to create and destroy a container, and to drive automated scaling behaviors. The major public cloud providers now support container services.
Jason McGee, the vice president of IBM Cloud Platform, is quoted as saying his company was betting on Cloud native solutions because they have the potential to help customers move faster. He added,
“Microservices are allowing companies to mix and match containerized, open source solutions so they don’t have to build everything from scratch. I can build a Microservice that you can re-use. That will allow the overall industry to go faster. Right now, we spend a lot of time re-solving the same problems.”
Photo Credit: nikkytok/Shutterstock.com