Beyond the buzz words and a general understanding of certain concepts, Function as a Service (FaaS)/serverless/microservices architectures are not yet well understood, as they are only now beginning to slowly gain momentum in the larger tech ecosystem, and there still is a lack of significant adoption. While there are absolutely nuanced differences between FaaS and Microservices, for the sake of this post, I'm going to consider them the same, with apologies to those that might shake their heads at my lazy hand waving. There are enough overlaps in the discussion herein to justify the generalizations, I hope.
You'll certainly find aspects of these architectural approaches at a number of organizations, and within the tech heavyweights with more appetite for trailblazing (e.g. Netflix, AWS), you'll find significantly bigger investments, but the lack of tried-and-true solutions, coupled with a lack of non-theoretical documentation in the wild, understandably make it a difficult undertaking for the vast majority of organizations.
To be sure, there are some very distinguished tech professionals out there talking a lot about Microservices and FaaS architectures. Adrian Cockroft and Martin Fowler come to mind, and there have been some books written on the subject, but a real depth of materials won't be available until we start to see more production deployments in the industry.
So, it was not without some risk that we took on building the entire architecture for a recently developed software product using a combination of these bleeding edge architectural approaches.
Since it's so new, and because tech loves to bastardize terms, there isn't necessarily total agreement on what these architectural approaches mean. Case-in-point, I spoke with a potential client a few months back that was very excited about building out a serverless architecture. While plans of Lambda functions danced in my head, managed services danced in his. To me, managed services, such as Snowflake, offer Platform-as-a-Service (PaaS) solutions. Like FaaS architectures, you may not need to provision any infrastructure, but Snowflake is a MPP solution, so it more closely resembles Redshift, or even AWS EMR, than it does the FaaS architectures I like to build out lately. Sure, (e.g.) EMR can (and should) be leveraged ephemerally, so you can manage and take advantage of bi-directional scalability (assuming you've decoupled your storage from the compute), but none of these would be considered FaaS technologies.
As someone who has worked extensively with AWS over the last decade, I'm going to talk about specific AWS technology offerings throughout the remainder of this post, but GCP and Azure (etc.) have similar offerings.
When I talk about FaaS and serverless architectures, I'm talking about leveraging bi-directionally scalable technology solutions that don't require any compute/server provisioning or management, small, stateless use of compute, and I'm talking about leveraging (AWS) technologies like Lambda, SNS, and DynamoDB, recognizing that an overall architecture like this has many more applications and technologies. I'm intentionally avoiding unnecessary religious battles: this post doesn't attempt to debate RESTful API best practices, or whether an individual function in a FaaS architecture should contain a single function, or multiple (there are places for each); rather, I'm speaking generally here about a handful of the applications and technologies that play a central role in an AWS FaaS architecture, and generally how those fit together.
When I look at our overall technical architecture, I'm most taken not by what is there, but what isn't. As a data and analytics professional, I've spent the better part of a twenty-five year career working with RDBMS technologies, writing SQL queries and ETL jobs, and the like. While a significant part of our offering is data visualizations (traditionally the responsibility of a visualization application leveraging the RDBMS), we don't have any RDBMS. Instead, we leverage primarily transient document datastores (specifically DynamoDB), which offers single-digit-millisecond performance, and total bi-directional scalability. This significantly helps with costs, since the only persisted document datastores are small (e.g. users), whereas everything else is managed with time-to-live restrictions, with long-term storage in an immutable file (object) system, using S3 (at a cost of $13/compressed terabyte). We then process data in a distributed fashion via Lambda functions that consume and transform those data stored in our document datastore and on S3.
The other thing that a traditional Big Data/Analytics Engineer might notice when looking at our architecture is a lack of a scheduling/orchestration application.
“[In traditional architectures], all flow, control, and security was managed by the central server application. In the Serverless version there is no central arbiter of these concerns. Instead we see a preference for choreography over orchestration, with each component playing a more architecturally aware role—an idea also common in a microservices approach.”Mike Roberts
Shifting our focus to compute, we rely solely on Lambda functions, which again, gives us total bi-directional scalability with (at ~ $0.0000002 per request) minimal costs, a consistent language (Python), and choreograph practically all computation via an event-driven approach. Lambda functions fire from websites, upon data arrivals, at points in time, after DynamoDB is altered, etc., and write messages to a series of SNS topics, and additional Lambda functions fire based on those messages.
As a practical example, let's quickly explore our data science model training and application:
Whenever a consumer makes a selection (such as insomnia), a Lambda function fires, sending those "tag" selections to our backend. Those tags are then applied against an up-to-the-second deployment of the data science model. Recommendations are returned to the Lambda function, and rendered to the consumer.
On the backend, whenever a store changes it's "store collection" (which you can loosely think of as "inventory"), a Lambda function fires that writes a message to SNS, indicating that the store collection has been altered, for store foo. Another Lambda function fires upon receipt of that SNS message, which extracts relevant data science information associated with that updated store collection, plus all the tags associated with that set of data, and re-trains the model and replaces the coefficients to apply the model. What this means is that we are re-training store-specific data science models hundreds or thousands of times a day across all the stores, with each re-training taking seconds to complete, and at a cost of pennies (in aggregate).
This pattern (Lambda→SNS→Lambda) is repeated across the entire architecture. While this event-driven choreography approach does introduce some complexities in the monitoring of the system, what it really requires is a different way of thinking and some additional discipline.
This approach allows us to really exploit the cloud-hosting model. Our disk/storage costs are minimal (transient DynamoDB and S3), as are our compute costs (Lambda). I believe serverless architectures are the way of the future, and I'm thrilled to be a part of productionalizing these architectural approaches to the larger tech industry.