Abstractions have been with us since the birth of computer science. They provide a way to simplify the complexities of working with computers. The first assembly languages simplified how programmers fed instructions to the machine, and today we are awash with abstractions: Kubernetes, React, and the Linux Kernel all are “abstracting” complex, lower-level systems. It would be impossible for today’s software engineer to learn many facets of these technologies in detail, without abstractions.
But have we gone too far in using abstractions, rendering more complexity for developers than is necessary?
This was one of many questions raised by Venmo Systems Engineer André Henry at USENIX SRECon last December. He waged that abstractions took us from a one-to-one relationship with software to a “multilayered configuration and deployment” model, which is inherently more cumbersome in many cases.
“It’s almost like we’re all starship captains now. We have become managers of ecosystems of complexity,” he told the virtual crowd. “If there is a problem with the application, we now have to start peeling back all these layers to figure out what’s causing the problem” Is the abstraction broken? Is the layer its abstracting broken? Is the other layer broken? An individual software might not understand all the layers covered by the abstractions.”
As an example of undue complexity, he pointed to the Cloud Native Computing Foundation’s voluminous landscape chart of cloud native technologies. How is the chief technology officer to make sense of all these technologies, each an abstraction of some aspect of distributed cloud native computing?
For instance, the container so popular at least in part because it solved the problem of dependency management. But perhaps more effort should have been applied to improving the packaging management tools themselves? “If your abstraction is compensating for a problem in another tool, should you write an abstraction for that, or should you solve that in the other tool?”
These abstractions can fool you into using technologies that may not even be required. Take Kubernetes for example, which offers the true benefit of fast scaling of resources. But do all web services require such rapid scaling?
Henry offered an example from a former job at an educational company. There, the company needed to ramp up its services each morning, for the school day, and then ramp it down at the end of the day, when the students go home. While this could have been handled easily by Kubernetes, Kubernetes wasn’t really needed at all, given that the workload was predictable. An easier approach would be to pre-scale, or pre-schedule a set of pre-baked images for these times. No K8s required.
“Think about the goal of the problem you’re solving, like what are you trying to accomplish and if this is the most efficient way and sustainable way,” he advised. “All abstractions are going to have a life. They have to be managed right.”
The Cloud Native Computing Foundation is a sponsor of The New Stack.