MotorsportReg (MSR), holds the prestige of having the world's largest motorsport events calendar. Their website, a hub for motorsports enthusiasts, allows visitors to search for events based on various criteria such as event type or location. Despite the ongoing success of their existing containerized architecture MSR aspired to innovate. In a move to stay ahead of the technological curve and diverging from their traditional architecture, MSR wanted to build a new GraphQL API which encorporated both established and emerging technologies.
Challenges
General Requirements
- Innovative API Development: MSR aimed to break new ground by introducing a new GraphQL API into their product lineup. MSR anticipated that the API would unlock new capabilities for how event information is accessed and displayed, not just on MSR's platform but also for it's customers and the entire motorsports community.
- Integration of a Dynamic Widget: A key feature of this initiative was the development of an HTML and JS Widget. This widget, designed to be embedded easily on various websites, would harness the power of the GraphQL API to deliver customized, real-time event data to users worldwide.
- Geolocation-Based Personalization: Recognizing the importance of relevance in user experience, the GraphQL API needed to include the capability to automatically geolocate visitors. This feature was essential in ensuring that the event information displayed was pertinent to the user's geographical location.
- Handling Traffic Uncertainties: A significant challenge was the unpredictable nature of traffic to the API. MSR needed a solution that could not only handle potential high traffic loads but also operate cost-effectively during periods of low traffic.
Noisy Neighbors
- System Isolation: Given the shared database environment, a crucial requirement was to ensure that the new GraphQL API did not adversely affect the performance of other systems. This involved strategizing to prevent the new API from becoming a 'noisy neighbor' within their existing infrastructure.
- Database Load Management: Another aspect was to address the potential increase in load on the Postgres database. The solution needed to circumvent the risk of overburdening the database, especially during traffic spikes.
What is a Noisy Neighbor?
In software architecture, a 'noisy neighbor' is a process or application in a shared environment that uses excessive resources, causing performance degradation for applications in the same ecosystem. This is akin to a noisy neighbor in an apartment building who disrupts the peace for others.
Data Storage
- Adaptable Data Storage: Data needed to be stored in a format that was not only scalable but also capable of supporting both predetermined and ad hoc access patterns.
Public API
- Choosing the Right Architecture: A significant decision was selecting the most suitable architecture to support the GraphQL requests. This involved evaluating whether to replicate their existing ColdFusion or NodeJS container cluster model or to explore alternative solutions.
Geolocation
- Optimal Service Selection: Identifying the most effective geolocation service was critical. The decision hinged on whether to continue with the existing service used by their public-facing website or to adopt a new one.
Cost Efficiency
- Budget Management: Developing a cost-effective solution was paramount, particularly considering the potential for traffic spikes and the associated autoscaling requirements.
Reliability
- Infrastructure Stability: Emphasizing reliability, the architecture needed to incorporate Infrastructure as Code (IaC) principles for seamless and stable management.
Solutions
We'll delve into some of the specific solutions employed to address the unique challenges developing the GraphQL API. Our approach was multifaceted, combining strategic database management, serverless computing, and intelligent data handling to overcome issues such as the 'noisy neighbor' problem and ensuring efficient data retrieval.
Eliminating the Noisy Neighbor
We needed to find a way to isolate load from our GraphQL API from other parts of the ecosystem.
- Database Replication Strategy: To address the challenge of the new API affecting other systems, we considered using a read replica of the existing Postgres database. However, recognizing the limitations and potential bottlenecks, particularly during traffic spikes, we opted for a more robust solution.
- AWS Database Migration Service (DMS): Our solution was the implementation of AWS DMS to replicate data from Postgres to DynamoDB. This approach allowed us to leverage a familiar replication slot configuration in Postgres while ensuring continuous data synchronization to DynamoDB.
- Isolation in DynamoDB: By replicating data into DynamoDB, we effectively isolated the GraphQL API from requiring any access to the upstream data providers, protecting the Postgres database. This architecture ensured that the new API could function independently, without impacting other systems.
Replication Architecture
![Continuous replication using AWS Database Migration Service](/img/work/02.global-event-api-replication.png)
Continuous replication using AWS Database Migration Service
Data Storage Use Cases
Isolating data into it's own DynamoDB data store was a great first step, but DynamoDB alone wasn't enough to handle ad hoc requests.
- DynamoDB as Primary Store: We chose DynamoDB for its scalability and efficiency in handling known access patterns. However, recognizing its limitations in ad hoc query support, we complemented it with another solution.
- Integration with OpenSearch: To support ad hoc queries, we streamed data from DynamoDB into OpenSearch. This combination allowed us to direct GraphQL queries either to DynamoDB or OpenSearch, depending on the nature of the request, optimizing data retrieval based on each use case.
Adding OpenSearch
![After replication, data is streamed from DynamoDB to OpenSearch](/img/work/02.global-event-api-replication-opensearch.png)
After replication, data is streamed from DynamoDB to OpenSearch
Serverless Public API
With data storage under control, now it was time to build the public facing API.
- AWS AppSync and Lambda Selection: Our choice of AWS AppSync, backed by Lambda functions, was pivotal. Both are managed serverless services, offering automatic scaling and efficient management of incoming GraphQL queries.
- Lambda Resolvers: Each query to the API is handled by a Lambda resolver. These resolvers were designed to intelligently route the requests to either DynamoDB or OpenSearch independantly, ensuring efficient and accurate data retrieval.
AppSync API w/Lambda Resolvers
![User requests are routed to DynamoDB or OpenSearch using Lambda](/img/work/02.global-event-api-appsync.png)
User requests are routed to DynamoDB or OpenSearch using Lambda
Geolocation Integration
The API was coming along great but there was one last problem to solve. Geolocation.
- Evaluating Options: We meticulously reviewed various geolocation services, including those already in use by MSR. Our criteria focused on performance, cost-effectiveness, and ease of integration.
- Choosing AWS CloudFront: We settled on AWS CloudFront due to its seamless integration capabilities, cost benefits, and the ability to inject geolocation headers. This choice proved to be efficient, leveraging existing infrastructure while providing accurate geolocation data.
Adding CloudFront
![Geolocation headers are injected into each request as it passes through CloudFront](/img/work/02.global-event-api-cloudfront.png)
Geolocation headers are injected into each request as it passes through CloudFront
Cost Management
- Serverless Services for Cost Reduction: By utilizing AWS's serverless offerings, we significantly reduced the operational costs. These services' ability to 'scale to zero' was particularly advantageous in managing expenses in development environments with low traffic.
- DMS Cost Considerations: One exception to the serverless stack was DMS, which runs continuously. However, a serverless version was released shorly after we launched the API, opening the door for additional potential future savings and efficiencies.
Reliability through IaC
- AWS CDK for Infrastructure Management: The use of AWS CDK played a crucial role in ensuring a consistent and reliable deployment process across development, testing, and production environments. This approach minimized manual interventions, enhancing the overall reliability and stability of the infrastructure.
Outcomes
The successful implementation of the GraphQL API marked a significant milestone for MSR. The solution excelled in managing high traffic volumes efficiently and remained cost-effective during periods of lower traffic. The strategic use of AWS's serverless services, coupled with the dual data storage strategy, resulted in a robust, scalable, and reliable API that is now being adopted globally. Key accomplishments include:
- Exceptional Performance: The API demonstrated remarkable speed and scalability, handling varying traffic loads with ease.
- Resilient Architecture: The solution ensured that traffic surges did not impact other systems, maintaining system integrity at all times.
- Controlled Costs: The serverless infrastructure ensured that costs were kept in check, regardless of traffic fluctuations.
- Confidence in Deployment: The use of IaC guaranteed a smooth and reliable deployment process, allowing for confident architectural and code changes.
- Global Adoption: The GraphQL API and its accompanying widget have been successfully deployed on numerous websites worldwide, solidifying MSR's position as a leader in digital innovation in the motorsports event sector.
More Information
- From the MotorsportReg blog: New Events API and Widget
- You can also read the Global Event Calendar API Documentation