Ease with which microservices can be built with no sql database like DynamoDb is the exact opposite to build similar ones with relational databases. It’s always a challenging task as managing the connection pool from each instance of lambda, trying to keep them active inactive containers and removing the dead ones and many such critical things need to be precise to build a smooth experience for clients. This is on top of complexity to avoid application cold starts.
RDS Data API solves this problem giving us a way to run sql queries with http connections. If a single instance of simple nodejs lambda can easily establish 500+ active http connections, imagine how many queries we can simultaneously run if the database can scale with no limit on max connections.
To to be completely serverless, we not just need a serverless app but a serverless database. Lets get few abbreviations defined.
- Rds Mysql : A managed database server with computing and storage together.
- Aurora MySql: Separate compute node and storage. Storage shared across master and replicas, makes it easy to add new replicas or replace master for DR.
- Aurora Serverless: Scale-up/down/out of computing nodes on CPU/connections.
I am not going into details on how scaling works on Aurora Serverless but just a few points to note:
- Scales from 0 ACU( 1 Aurora Capacity Unit — 2GB Ram) to a very high number that we can’t afford. no worries there.
- Proxy layer sits in front of DB instance(s) and the client which redirects traffic to active instance helps to keep connections active during scaling activity. All we notice is a small latency but no drop on connection.
- If continuously used, will cost more than a regular instance that is equivalent Aurora instance with 0 replicas and of course you need to provision based on your max load.
Let’s compare how it scaled with CPU vs ACU
Throughout this test, I kept opening and closing a single http connection and ran one simple query from Lambda, a few times. so, max active connections is 1.
- At 21:30 as first query hit after the instance launch has straight away scaled to 4 acu probably aurora not predicting what the load could be resulting in aggressive scaling.
- Cool down period was 5 minutes initially and 15 minutes later. This depends on a setting “Pause compute capacity after consecutive minutes of inactivity” which I set to 300 seconds initially, later unchecked.
- After each cool down period subsequent requests scaled instance to 2 acu and 1 acu. It looked like Aurora is intelligently learning the pattern(not sure if its truly doing that but it sure looked like that)
- Launching the initial instance took up to 30 seconds i.e first connection could easily timeout if connection properties are not tweaked with most regular Jdbc clients. When tried from RDS Query Editor, the connection kept timing out after 3 seconds until the first scaling activity.
- This is not a lambda instance where we can send a ping and keep the container active. We can run a query and keep the instance active or set minimum Acu to 1 but then we will be charged for the minimum, unlike lambda where we are charged only for the run time of the container.
Aurora serverless scaling is very reliable and definitely a way to go for unpredictable workloads to save cost instead of regular Aurora. But relying on Aurora serverless for serverless apps may not be best yet purely because of the cold start time. Unless Aurora Serverless can do Machine Learning and predict the load and intelligently scales compute node, I will still try to rely on something like Dynamo as much as I can for serverless applications.