Database Caching for AWS RDS with PolyScale.ai, ECS and Fargate
Sam Aybar
May 17, 2023Introduction
Database scaling challenges typically arise as a result of increased workloads, higher data volumes, supporting new application features (think increased query complexity) or supporting new geographical regions. If you are running a data-driven application on AWS using RDS as the database service, there are several options to help overcome these scaling challenges such as vertical scaling, read-replicas and detailed observability metrics for debugging (slow logs etc).
Another way to address such scaling challenges is with a caching solution, such as PolyScale.
PolyScale.ai is a serverless, plug-and-play database cache. It dramatically accelerates database read performance, lowers network latency and reduces database infrastructure costs. PolyScale is plug-and-play requiring no code to implement, and zero configuration or tuning. It can be implemented in minutes with a simple configuration change. PolyScale offers a global edge network SaaS platform as well as a self hosted option.
Why Cache?
When building data driven applications, employing a caching strategy can help improve user experience and reduce costs dramatically. User experience is improved because results from complex queries can be served instantly (since no database computation is required to provide a cached result). Database costs can be reduced due to the fact that a cache can reduce the load on the database, offsetting the reads, potentially lowering the specifications required for the origin database (and thus reducing cost). Latency can be reduced for distributed applications by locating the cache along side the application tier, in all required regions.
Historically, while caching improves performance and reduces database utilization, it comes with the tradeoff of the additional cost and complexity. The time required to build caching logic into your application is often non-trivial. You need to decide what to cache and for how long, and each change you make to your application potentially necessitates amending your caching logic. You need to write, test, and maintain the code for each query you decide to cache, and constantly assess whether you are caching the right queries for the right amount of time i.e. hit rates vs data accuracy.
With PolyScale, you can get the benefits of caching without the complexity of implementation. Because PolyScale is wire-compatible with your database, it is able to intercept existing queries and then apply algorithms to determine what to cache and for how long. With this methodology, all possible queries are cached for the optimal amount of time, automatically. When you use PolyScale, not only have you implemented a caching solution for your existing queries, but also for all future queries supporting new application features.
To SaaS or not to SaaS
PolyScale offers two deployment models. Firstly, a Serverless SaaS that requires no infrastructure deployments or management. PolyScale’s edge network covers AWS locations, so it is trivial to add a high performance database cache to your AWS hosted applications. PolyScale publishes static IP’s for each location so these can be added to firewall rules accordingly.
Many enterprises however, operate private networks where the database is not accessible outside of their VPC and as such, utilizing such SaaS services is not applicable. Likewise, data residency and security compliance may also restrict the use of such external services.
For these situations, PolyScale offers a self hosted option. PolyScale Self Hosted consists of a single downloadable component named the Private Cache Endpoint (PCE). The PCE can be downloaded and started in a single command, yielding a fully automated database cache engine. No configuration, no code to write.
Deploying PolyScale with Elastic Container Service and Fargate
AWS has proven itself to be a dominant host for enterprise applications. Companies from Netflix to Kellogg, from Airbnb to Pfizer rely on AWS to provide infrastructure needs. With PolyScale Self Hosted, companies can now easily add a cache to their data driven applications, increasing performance and reducing database costs. The PCE is packaged as a docker image which can be run on any machine running Docker. In this blog article, we will explain how to deploy PCE on AWS using Elastic Container Service (ECS) and Fargate.
Prerequisites
Before starting the deployment, you will need to have an AWS account and a basic understanding of the following services:
- Elastic Container Service (ECS): A fully-managed AWS container orchestration service that simplifies the deployment and management of containers.
- Fargate: An AWS service that provides automatically managed compute capacity in the cloud.
- Docker: An open-source platform for building, shipping, and running distributed applications.
- A PolyScale account with a PCE enabled API key. (See https://docs.polyscale.ai/self-hosted-install for instructions on getting a key.)
Step 1: Create an ECS Cluster
The first step is to create an ECS cluster to manage the PCE container. Follow these steps:
- Open the AWS Management Console and navigate to the ECS service.
- Click on the “Create Cluster” button.
- Under “Cluster configuration” give the Cluster a name (e.g. PCE-Cluster)
- Under “Networking”, be sure to choose the VPC for the application and database for which you are looking to provide a cache.
- Under Infrastructure, AWS Fargate should already be selected.
- Click “Create”.
AWS will then begin the creation process for the Cluster behind the scenes. Once the cluster is successfully created, a message at the top of the dashboard will indicate so.
Step 2: Define the task to Run the PCE
Next, we need to define a task that will be run by ECS to run the PCE.
From ECS, click on “Task definitions” on the left hand side
Click “Create new task definition” on the top right of the Task definitions page
Under “Task definition configuration” give the Task definition family a name, e.g. PCE-Task
Under “Container - 1” specify a name (PCE) and Image URI (ghcr.io/polyscale/pce:stable) for the PCE Image.
Under “Port mappings” expose the ports the PCE uses for the different database protocols:
Click “Add environment variable” to add the following environment variables:
Click “Next”
On the “Configure environment, storage, monitoring, and tags” page, accept the defaults and click “Next” at the bottom
On the “Review and create” page, double check the Image URI, port mappings and environment variables and then click “Create”
You have now created the task you assign ECS will execute to run the PCE.
Step 3: Create a Service to Run the Task
Now return to your Cluster overview to create the service to run your PCE task.
- From cluster overview page in ECS for your PCE Cluster, click on “Create” in the Services section
- On the “Create” page, in the “Deployment configuration” section, under “Family” choose the task created above in Step 2 (e.g. “PCE-Task”)
- Assign a “Service Name” (e.g. “PCE-Service”)
- Under “Networking” if you will not need to access the PCE from outside your VPC, you can turn off “Public IP”; however, if you wish to be able to use your cache from devices/applications outside the VPC, leave this switched on.
- Accept all the other default values and click “Create” at the bottom of the page.
The process of running the PCE will now begin. Once startup is complete, under the Services section of the Cluster, it should indicate that the service (e.g. PCE-Service) is active. If you click on the “Tasks” tab, and then click on the Task name, you can then find the Private IP address you will use to connect to the PCE with your application. (For example 172.30.0.80
)
Step 4: Create a PolyScale cache
A PolyScale account can have one or more caches
defined. A cache simply identifies a database origin via a hostname
and port
that you wish to cache data for. Typically you create a cache per database for simplicity.
- To create a new cache, click the New Cache button in the upper right of the caches dashboard
- Give the cache a name, select the database type, and enter the hostname and port of the database you wish to connect to. (This will be the private IP address for your database that is accessible from within your VPC and the port on which your application currently accesses the database.) Note that if your database is not publicly accessible, the Network test that runs will fail, as it is testing access to your database from PolyScale’s public infrastructure. Assuming you have installed your PCE on the same VPC as your database and your security rules are set properly, your PCE should be able to access the database.
- When you have created your cache, you will be provided with a cache ID, as well as a new connection string. Save this for use in step 5 (though note the connection string is for use with the public SaaS endpoints and will need to be modified as described below).
You have now successfully created a cache.
Step 5: Connecting to the PolyScale PCE Cache
To connect to your database via PolyScale, you will need to make the following changes to your connection string:
- Update your host
- Update the port
- Pass in the PolyScale cache ID
The connection string provided in step 4 above is the easiest starting point. You simply make the following changes.
- Replace the
psedge.global
hostname with the Private IP address from Step 3 above if you will be accessing the cache from within the VPC. (Otherwise, use the Public IP address for the cache, located on the same page.) - Replace the port in the connection string using the following port, based on which database you are using:
- MySQL:
9000
(replaces3306
) - MariaDB:
9001
(replaces3307
) - PostgreSQL:
9010
(replaces5432
) - SQL Server:
9020
(replaces1433
)
- MySQL:
So, for example, for a MySQL database, if the connection string provided when you created your cache was:
mysql://POLYSCALE_CACHE_ID-USERNAME:PASSWORD@psedge.global:3306/DATABASE
And your private IP address was 172.30.0.80
To use this with the PCE, you would use a connection string in your application of:
mysql://POLYSCALE_CACHE_ID-USERNAME:PASSWORD@172.30.0.80:9000/DATABASE
Alternatively, for a Postgres database, the PolyScale SaaS connection string of:
postgres://USERNAME:PASSWORD@psedge.global:5432/DATABASE?application_name=POLYSCALE_CACHE_ID
Would instead become:
postgres://USERNAME:PASSWORD@172.30.0.80:9010/DATABASE?application_name=POLYSCALE_CACHE_ID
For more details on connection strings, see the PolyScale documentation Getting Connected page.
You should now have a working cache running. If you have updated your connection string in your application as described above, you are now automatically caching all possible queries. That’s it! You can visit the PolyScale web user interface and see the queries PolyScale has cached for you.
Step 6: (Optional) Testing your Cache
PolyScale provides an open source utility that can be used to test the latency for your cache. This Network Test Utility can be found at https://github.com/polyscale/ntu
This section will describe how to run this tool within your ECS Cluster to test the latency between an application in your VPC and your database via PolyScale. (The steps should be familiar, as we will be creating another Task, as in Step 2 above, this time to run the NTU.)
From ECS, click on “Task definitions” on the left hand side
Click “Create new task definition” on the top right of the Task definitions page
Under “Task definition configuration” give the Task definition family a name, e.g. NTU
Under “Container - 1” specify a name (NTU) and Image URI (ghcr.io/polyscale/ntu-worker) for the NTU Image.
Under “Port mappings”, this time no changes are necessary
Click “Add environment variable” to add the following environment variables:
- PROTOCOL – the database type, eg mysql or postgres
- TEST – latency
- QUERY - the SQL query you want to run to test – eg Select * from employees limit 1;
- SLACK_WEBHOOK - to get the results for the NTU test, you must have a Slack webhook configured, e.g. https://hooks.slack.com/services/SLACKTEAMINFO/SLACKCHANNELINFO
- URL – the connection string for your database as discussed in step 5 above
Click “Next”
On the “Configure environment, storage, monitoring, and tags” page, accept the defaults and click “Next” at the bottom
On the “Review and create” page, double check the Image URI, port mappings and environment variables and then click “Create”
Now that the Task Definition is created, select “Deploy” and choose “Run task”
From the Create screen, choose the Existing cluster you created above (e.g. PCE Cluster), and then leave the rest of the defaults. Click “Create” at the bottom of the page
The NTU will then run 100 queries against your database via PolyScale and post a message to Slack that shows the distribution of latencies for the query
Shutting down and restarting the PCE
If you want to shut down the running PCE, From PCE Cluster, click on the PCE Service and click “Update Service”. In the “Desired tasks” section, change the value from 1 to 0 and then click Update. This will scale the service down to 0, stopping the PCE from running.
To restart the PCE, return to the “Update Service” page and increase “Desired tasks” back to 1, and then click “Update”. Note that when restarting the service this way after stopping it, the private IP address may change, so you may need to update your connection string accordingly.
(There are workarounds to get a static IP address, either by using EC2 with a static IP address rather than Fargate or by using a load balancer, but that is outside the scope of this article.)
Launching the PCE Using CloudFormation
If you are set up with the AWS Command Line Interface, you can also use a CloudFormation template to install and launch the PCE. The template can be found in this repository.
To create and launch the PCE, simply type these two commands:
export PCE_API_KEY=<YOUR_PCI_API_KEY>
aws cloudformation create-stack \
--capabilities CAPABILITY_NAMED_IAM \
--stack-name pce-ecs-fargate-example \
--parameters ParameterKey=PceApiKey,ParameterValue=$PCE_API_KEY \
--template-body file://pce-ecs-fargate-example.yaml
You can then follow the instructions in Step 3 above to find the IP address for the PCE.
Summary
With the introduction of PolyScale’s Self Hosted PCE, it is easy to create a cache for your MySQL, Postgres, MariaDB or MsSQL database running within a VPC on AWS. With the PolyScale PCE, you can reduce the load on your database and lower latency to your application without modifying your code at all.
The PCE can be set up in minutes using ECS and Fargate, and provides a robust caching solution for all your current and future queries.
To learn more about Self Hosted PolyScale or to get an API Key enabled for use with the PCE, complete the signup form.