<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Chris Murton]]></title><description><![CDATA[Chris Murton]]></description><link>https://blog.chrismurton.uk</link><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Apr 2026 21:35:23 GMT</lastBuildDate><atom:link href="https://blog.chrismurton.uk/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Amazon Aurora MySQL Parallel Query: Beware]]></title><description><![CDATA[I'll start by saying that I'm a big fan of Amazon Aurora. Plain old RDS shares a lot of the benefits by removing the 'undifferentiated heavy lifting' of running your own database cluster on EC2 but Aurora goes further by allowing you access to extra ...]]></description><link>https://blog.chrismurton.uk/amazon-aurora-mysql-parallel-query-beware</link><guid isPermaLink="true">https://blog.chrismurton.uk/amazon-aurora-mysql-parallel-query-beware</guid><category><![CDATA[AWS]]></category><dc:creator><![CDATA[Chris Murton]]></dc:creator><pubDate>Sun, 30 Apr 2023 23:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/WNS__aBJjl4/upload/604ce923d999cd7e07c644cb84ef908a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I'll start by saying that I'm a big fan of Amazon Aurora. Plain old RDS shares a lot of the benefits by removing the 'undifferentiated heavy lifting' of running your own database cluster on EC2 but Aurora goes further by allowing you access to extra smarts such as:</p>
<ul>
<li><p>Removing the need to provision and manage storage due to the shared layer native to Aurora</p>
</li>
<li><p>Running multi-master in a single region</p>
</li>
<li><p>Running a master in one region and having continual, millisecond latency replication to other regions with the ability to initiate swift failover via Global Database</p>
</li>
<li><p>Supporting the concept of blue/green deployments of your database cluster</p>
</li>
<li><p>Vastly and opportunistically improving the performance of certain queries by offloading them from the database engine itself to the shared storage layer beneath</p>
</li>
</ul>
<p>It is the last feature in that list that I want to talk about today.</p>
<p>The general recommendation from AWS before embarking on any compute migration (or greenfield deployment) is to experiment to find the sweet spot for performance vs. cost, i.e. right-sizing your infrastructure. I'm here to tell you the same is absolutely true for the Parallel Query functionality in Amazon Aurora for MySQL.</p>
<h2 id="heading-what-is-parallel-query">What is Parallel Query?</h2>
<p>AWS pitch it as below:</p>
<blockquote>
<p>While some databases can parallelize query processing across CPUs in one or a handful of servers, Parallel Query takes advantage of Aurora’s unique architecture to push down and parallelize query processing across thousands of CPUs in the Aurora storage layer. By offloading analytical query processing to the Aurora storage layer, Parallel Query reduces network, CPU, and buffer pool contention with the transactional workload.</p>
</blockquote>
<p>Essentially rather than chew up CPU cores on the Aurora writer or reader nodes, your query will (if chosen) be pushed down to the storage layer thereby freeing up resources to handle more concurrent queries.</p>
<h2 id="heading-why-should-i-beware">Why should I beware?</h2>
<p>Whilst Parallel Query is disabled by default but as it is something which appears on the surface to be entirely beneficial (who wouldn't want increased performance and reduced CPU contention!) you may want to toggle it on. It works in conjunction with the Query Optimiser present in native MySQL and variants to decide the most optimal path to take to retrieve your query results most efficiently; the optimiser itself is relatively opaque to the client. In my experience, it can <strong>slow down</strong> your query response times and cause a significant increase in your monthly AWS spending if your schema and dataset don't fit the profile.</p>
<p>In my testing, this has been especially relevant on large tables with extensive column indexes. I would see queries that would depend almost exclusively on indexes be targeted for pushing down to the storage layer when it would have taken a much shorter period to complete if the query had taken the non-Parallel Query route. In some cases, the query took over 900x longer using Parallel Query rather than having this functionality disabled and resorting to traditional query optimiser behaviour.</p>
<p>What is also not immediately obvious is this has a direct impact on your AWS bill; Aurora charges both for compute time and IOPS to the storage layer, and whilst queries made to indexes that are already loaded in memory can be satisfied without generating read traffic to the storage subsystem, <strong>every query</strong> pushed down to storage results in read IOPS.</p>
<h3 id="heading-how-to-experiment">How to experiment</h3>
<p>AWS document how to go about kicking the tyres on Parallel Query at <a target="_blank" href="https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-mysql-parallel-query.html#aurora-mysql-parallel-query-sql-explain">https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-mysql-parallel-query.html#aurora-mysql-parallel-query-sql-explain</a>. Different variables need adjusting depending on the major version of Aurora MySQL you are running, but enabling this at a session level allows you to experiment without downtime.</p>
<h3 id="heading-how-much-could-it-cost">How much could it cost?</h3>
<p>This will vary drastically based on your workload, request volume, row count and query and schema complexity.</p>
<p>The cost factor only gets a cursory mention in the AWS documentation:</p>
<blockquote>
<p>If your Aurora MySQL cluster uses parallel query, you might see an increase in <code>VolumeReadIOPS</code> values. Parallel queries don't use the buffer pool. Thus, although the queries are fast, this optimized processing can result in an increase in read operations and associated charges.</p>
</blockquote>
<p>In my experience, turning off Parallel Query support (after demonstrating it did not provide any performance improvement for a given dataset) reduced a production AWS bill by $4k a month.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>There are undoubtedly use cases where Amazon Aurora Parallel Query makes sense. Examples show that in best-case scenarios it can dramatically improve query responsiveness and offload work from your Aurora cluster nodes, but it does not fit every use case, every query and every workload.</p>
<p>The worst-case scenario is what I experienced - slower query response times and a much larger AWS bill for the privilege of using it.</p>
]]></content:encoded></item><item><title><![CDATA[CloudWatch isn't just for the cloud]]></title><description><![CDATA[Amazon CloudWatch is an inexpensive way to monitor your solution in AWS and due to the extensive set of metrics provided for every AWS service out of the box, it’s easy and quick to adopt. Granted it’s not going to replace your enterprise monitoring ...]]></description><link>https://blog.chrismurton.uk/cloudwatch-isnt-just-for-the-cloud</link><guid isPermaLink="true">https://blog.chrismurton.uk/cloudwatch-isnt-just-for-the-cloud</guid><category><![CDATA[AWS]]></category><dc:creator><![CDATA[Chris Murton]]></dc:creator><pubDate>Thu, 06 Apr 2017 23:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1686616655846/36caa3c4-1c97-4864-a5a4-bedf2d07a694.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Amazon CloudWatch is an inexpensive way to monitor your solution in AWS and due to the extensive set of metrics provided for every AWS service out of the box, it’s easy and quick to adopt. Granted it’s not going to replace your enterprise monitoring solution overnight, but for those who haven’t got the time or justification to spin up their own Nagios/Zabbix/OpsView solution, it can do basic event monitoring and alerting.</p>
<h3 id="heading-but-theres-more">But there's more...</h3>
<p>As well as Amazon CloudWatch supporting a bunch of metrics for most AWS services, it has powerful functionality that frankly isn’t talked up enough: <strong>custom metrics</strong>. Combine that fact with the very easy-to-use AWS CLI/API that you can run from anywhere and you can quickly start storing metrics for anything and everything in Amazon CloudWatch - even if it’s not in the cloud.</p>
<h3 id="heading-its-a-bit-chilly-in-the-garage">It's a bit chilly in the garage!</h3>
<p>For ages, I’ve had a USB CurrentCost meter hooked up in the garage so that I can track power consumption over time. As well as power consumption in watts the meter is capable of reporting the current temperature where it’s sat, so I previously set up MRTG and latterly Cacti to collect and store these values over time so I could graph it. Yep - if I can graph it and store it for analysis I will. Blame my past as a monitoring specialist for that. Of course, this is all very nice but MRTG doesn’t natively support any form of alerting and at the time Cacti’s monitoring support felt like a bit of a hack.</p>
<p>As part of my drive to minimise the amount of hardware I have at home and simplify some of the random scripts I have - I started looking at alternative ways to collect, store and hopefully alert on these values when they went out of bounds. Step forward Amazon CloudWatch.</p>
<hr />
<h3 id="heading-create-an-iam-user">Create an IAM User</h3>
<p>The first thing you’ll need to do is create an IAM user in your AWS account with sufficient privileges to talk to CloudWatch via the AWS API. If you do this via the wizard you can get it to give you an access key ID &amp; secret access key which you’ll need for later.</p>
<p>Go ahead and create the IAM user via the AWS Management Console and then give it an inline policy (or create a managed policy) like the one below:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"Version"</span>: <span class="hljs-string">"2012-10-17"</span>,
  <span class="hljs-attr">"Statement"</span>: [
    {
      <span class="hljs-attr">"Sid"</span>: <span class="hljs-string">"AllowCloudWatchPutMetricData"</span>,
      <span class="hljs-attr">"Action"</span>: <span class="hljs-string">"cloudwatch:putMetricData"</span>,
      <span class="hljs-attr">"Effect"</span>: <span class="hljs-string">"Allow"</span>,
      <span class="hljs-attr">"Resource"</span>: <span class="hljs-string">"*"</span>
    }
  ]
}
</code></pre>
<p>This gives your IAM user the ability to publish metrics into CloudWatch and nothing else.</p>
<h3 id="heading-set-up-the-aws-cli">Set up the AWS CLI</h3>
<p>On the machine that had my USB CurrentCost meter attached, I needed to download and install the AWS CLI. Depending on your OS and distribution there are a variety of ways to achieve this; Ubuntu provide a package (<code>apt-get install aws-cli</code>) but for most other distributions you’re best off running this if you’ve got Python’s package manager installed, preferably inside a virtual environment:</p>
<pre><code class="lang-bash">pip install --upgrade --user awscli
</code></pre>
<p>Hopefully that’s got the AWS CLI all installed for you. Next pick the user that will be running the CLI to push your custom metrics to CloudWatch and sudo/su to that user. Once you’re in a shell as that user, run the following and use the credentials you obtained when you created your IAM user:</p>
<pre><code class="lang-bash">$ aws configure
AWS Access Key ID [None]: ZZZZZZZZZZZZZZZZZZZZ
AWS Secret Access Key [None]: AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTt
Default region name [None]: (any valid AWS region.. I chose eu-west-1)
Default output format [None]:
</code></pre>
<p>This configures the AWS CLI to use the credentials of your IAM user by default whenever it is run under that user account, by creating ~/.aws/config and ~/.aws/credentials.</p>
<h3 id="heading-test">Test</h3>
<p>You should now be ready to start publishing custom metrics to Amazon CloudWatch. You can incorporate a call out to the AWS CLI in any of your custom scripts like so:</p>
<pre><code class="lang-bash">$ MONITOR_VALUE=15.1
$ aws cloudwatch put-metric-data --namespace Home/Environmentals \
    --metric-name GarageTemperatureCelsius --value <span class="hljs-variable">${MONITOR_VALUE}</span>
</code></pre>
<p>Wrap that command into a cronjob or custom script that extracts the metric you’re interested in, replace <code>MONITOR_VALUE</code> with it, change the metric name to something that represents your data and also change the namespace to protect the innocent remembering it can be <strong>anything</strong> that doesn’t begin “AWS/”.</p>
<p>You now have your custom metric going into CloudWatch that you can create alarms against, sending notifications to SNS topics when that garage gets a bit nippy.</p>
]]></content:encoded></item></channel></rss>