Adrian Cantrill’s SAA-C02 study course, 60 minutes: Serverless and Application services section: Architecture Deep Dive Parts 1 & 2
Architecture Deep Dive Part 1
This lesson was focused on event driven architecture, and also comparing it to other architectures.
It was discussed that having a solid understanding of all the different types of architectures was important because a solutions architect needs to design a solution using a specific architecture around a given set of business requirements, and that fully understanding the architectures was necessary to build anything.
To begin with, a hypothetical online, popular video sharing platform. Among other things, people used the site to upload videos. After uploading, the site would begin processing and generating multiple versions of the same video at different quality levels, and this particular usage of the site was the most resource intensive. Aside from this, the website displays videos, manages playlists and channels, and stores and retrieves data.
It was explained that there were multiple ways to potentially architect this solution, and that the most popular systems architecture was known as a Monolithic Architecture. It was explained that this was like a single black box with all the components within it. Because it’s one entity, it would fail together as an entity, and if one component fails, it would impact the whole thing. If uploading were to fail, it could also affect processing, as well as store and manage. Basically, if every function is contained in a single, monolithic architecture, then the failure of any part can affect everything else.
Also, monoliths scale together. The term used was ‘tightly coupled’. All of the components would be on the same server, directly connected, and have the same codebase. They scale together. With monolithic architectures, the system scales vertically, because everything is running on the same hardware. On top of this, they bill together. Regardless of if one component is not utilized at a given time, everything is billed at the same rate. So, monolithic architectures are very cost ineffective.
Another architecture is tiered. With a tiered architecture, the monolith is broken into different tiers. Each of these tiers can be on the same server or on different servers. Tiered architectures are tightly coupled because the tiers are interconnected. One benefit of tiers is that they can scale independently. On top of this, load balancers can be located between each of the tiers. This loosens the coupling as the tiers are no longer communicating directly with one another. This, in turn, allows for horizontal scaling, meaning that additional instances can be added. Also, because communication is through the load balancers, there is no exposure between components of the architecture.
There are two main problems with this architecture:
1. The tiers are still coupled
2. Any processing tiers would still need to have something running
Architecture Deep Dive Part 2
Continuing on from part one, queues were introduced, which are defined here as a system which accepts messages; messages go into a queue and can be received or pulled from the queue. Many queues are ordered, and in most cases use a FIFO, First In First Out, architecture, though this isn’t always the case. Most importantly, queues allow for the architecture to be decoupled.
As an example, if a video were uploaded to the hypothetical website mentioned in the previous lesson, once the upload finished, the video would be stored in an S3 bucket and a message would be added to the queue detailing where the video was located along with any relevant information. The upload tier doesn’t need to communicate directly with the processing tier, and doesn’t require a direct response from the processing tier. Decoupling has enabled asynchronous communications. This also allows for multiple video uploads to transpire independently of the other tiers, and because of the FIFO order in the queue, the first videos uploaded will be the first to be processed.
Another aspect of queues is the queue length, which is defined as the number of items in the queue. As the queue length grows, an auto scaling group could be configured to provision more instances to start pulling the queue and receiving messages at the front of the queue. Because the messages also contain the location of the S3 bucket, once the jobs are received from the queue by the processing instances, they can retrieve the master video from the S3 bucket. After the jobs have been processed and there are a minimum number of messages in the queue, the auto scaling group could scale down the number of instances.
With queues, the tiers become decoupled from each other, and so can function completely independently, with little concern for or dependence on the state of the other tiers. Components do not need to communicate directly, they can scale independently, and instances can be auto-scaled in and out as needed, based on the length of the queue. The asynchronous communications also helps support decoupling.
Moving on, we then looked at a microservice architecture. Microservices do individual things very well. A full architecure could contain hundreds or even thousands of these microservices. They could be different services or copies of the same services. Some microservices can be classified as producers and some as consumers, and what they produce and consume architecturally are events, and queues are used to communicate events. Larger microservices architectures can get complex quickly with services needing to exchange data between partner microservices, which would require a lot of queues.
It was stressed that a microservice is a a tiny self-sufficient application, and this whole architecure is referred to as an event-driven architecture. These even-driven architectures are a collection of event-producers. They could be components of the architecture which directly interact with customers or they might be parts of the infrastructure; they’re bits of software which generate or produce events in reaction to something. Producers produce events and consumers consume events. Components within an application can be both.
With event-driven architectures, neither the producers or consumers are sitting around waiting, not running at 100% cpu capacity waiting for something to happen. With producers, events are generated when something happens. These producers produce events. Consumers receive an event, take action, and then stop. To help simplify this architecture, there is an application called and event router, which is a highly available, central exchange point for events. The event router contains something called an event bus, which is like a constant flow of information. The producer generates events, they’re added to the event bus and the router delivers them to consumers.
Basically, the whole thing is a system with lots of smaller services, waiting for events. When events are received, the system springs into action, allocating resources and scaling components up as required. The events are dealt with and then the architecture returns to the low or no resource usage which is the default state.
Event-driven architectures only consume resources when required; there’s nothing constantly running. Producers generate events and they are delivered to consumers via an event router, which decides which consumers to deliver events to, and then the consumers take action, and then the system returns to waiting, going into a dormant state and not consuming resources.
Basically, a mature event-driven architecture only consumes resources while handling events. When events are not occurring, it doesn’t consume resources.