Backwards Compatibility
Let's inspect some software versioning issues in a distributed system that lead to the backwards and forward compatibility properties.
We'll cover the following
As explained earlier, a defining characteristic of distributed systems is composed of multiple nodes. It is useful to allow the various nodes of such a system to operate independently for various reasons. A typical requirement for some applications in real life is to deploy new versions of the software with zero downtime.
Rolling deployments
The simplest way to deploy new versions of the software with zero downtime is to perform rolling deployments instead of deploying in lockstep the software to all the servers at the same time.
Note: In some cases, this is not just a nice-to-have but an inherent characteristic of the system.
Example
Mobile applications (e.g., Android applications), where user consent is required to perform an upgrade, imply that users are deploying the new version of the software at their own pace. As a result, the various nodes of a distributed system can run different software versions at any time.
This chapter will examine the implications of rolling deployment and some techniques that will help to manage this complication.
Implications of rolling deployments
When the system performs rolling deployments, it manifests in many different ways. One of the most common ways is when two different applications communicate with each other. At the same time each one of them evolves independently by deploying new versions of its software.
For example, one of the applications might want to expose more data at some point. If this is not done carefully, the other application might not understand the new data making the whole interaction between the applications fail. Two very useful properties related to this are backwards compatibility and forward compatibility.
-
Backwards compatibility is a property of a system that provides interoperability with an earlier version of itself or other systems.
-
Forward compatibility is a property of a system that provides interoperability with a later version of itself or other systems.
These two properties essentially reflect a single characteristic viewed from different perspectives, those of the sender and the recipient of data.
Examples
Let’s consider an example of two systems, S and R, where the former sends some data to the latter. We can say that a change on system “S” is backwards compatible if older versions of “R” will be able to communicate successfully with a new version of S. We can also say that the system R is designed in a forward compatible way so that it will be able to understand new versions of S. Let’s discuss some examples in detail.
Let’s assume system S needs to change the data type of a specific attribute. Changing the data type of an existing attribute is not a backwards compatible change in general. System R would expect a different type for this attribute, and it would fail to understand the data. However, this change could be decomposed into the following sub-changes that preserve compatibility between the two systems.
The system R can deploy a new version of the software capable of reading that data either from the new attribute with the new data type or the old attribute with the old data type. The system S can then deploy a new version of the software that stops populating the old attribute and starts populating the new attribute.
Note: Whether a change is backward compatible or not, it can differ depending on the used serialization protocol. This article explains it nicely.
The previous example demonstrated that the seemingly trivial changes to the software are more complicated when they need to perform in a distributed system safely. As a consequence, maintaining backward compatibility imposes a tradeoff between agility and safety.
Get hands-on with 1400+ tech skills courses.