{
  "date": "2021-03-08T19:34:38",
  "slug": "aws-postgresql-on-graviton2",
  "link": "https://www.dbi-services.com/blog/aws-postgresql-on-graviton2/",
  "title": {
    "rendered": "AWS: PostgreSQL on Graviton2"
  },
  "content": {
    "rendered": "<h2>By Franck Pachot</h2>\n<p>.<br />\n<a href=\"https://aws.amazon.com/ec2/instance-types/t4/\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-full wp-image-48021\" src=\"https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2022/04/Site-Merch_Graviton_T4g_trial_Sign-in_EN.b703bb5939c5e5d7c045f6ef5c45a66955e036ff.jpg\" alt=\"\" width=\"285\" height=\"225\" /></a>On the AWS free tier, you can run a t2.micro instance for 750 hours per month during the first 12 month after sign-up date. And currently, until June 2021, you can also run a T4g.micro. But be careful, when the free trial ends, or if your usage exceeds the free trial restrictions, you’ll pay the standard pay-as-you-go rates. This is a good occasion to test the Graviton2 ARM processors, and you can do the same as I do in this blog post on those instances. However, as I want to compare the CPU performance during a long run I&#8217;ll use larger (and non-burstable) instances: m5d.2xlarge for x86_64 and m6gd.2xlarge aarch64 which have both 8 vCPUs and 32 GB or RAM.</p>\n<p>I&#8217;ve installed &#8220;Amazon Linux 2 AMI (HVM)&#8221; on m5d.2xlarge (x86_64) and &#8220;Amazon ECS-Optimized Amazon Linux 2 AMI (ARM)&#8221; for m6gd.2xlarge ARM64 (aarch64)<br />\n<a href=\"https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2022/04/Screenshot-2021-03-07-230532.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-48104\" src=\"https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2022/04/Screenshot-2021-03-07-230532.jpg\" alt=\"\" width=\"1816\" height=\"1210\" /></a></p>\n<h3>PostgreSQL</h3>\n<p>I&#8217;ll install PostgreSQL here and measure LIOPS with PGIO (<a href=\"https://github.com/therealkevinc/pgio\">https://github.com/therealkevinc/pgio</a>)</p>\n<pre><code>sudo yum install -y git gcc readline-devel zlib-devel bison bison-devel flex\ngit clone https://github.com/postgres/postgres.git\nsudo yum install -y gcc readline-devel zlib-devel bison-devel\ntime ( cd postgres &amp;&amp; ./configure &amp;&amp; make all &amp;&amp; sudo make install )\n( cd postgres/contrib &amp;&amp; sudo make install )</code></pre>\n<p>This compiles PostgreSQL from the community source (version 14devel). I can already get an idea about the CPU performance:</p>\n<ul>\n<li>m5d.2xlarge x86_64 Xeon time: real 3m32.192s, user 3m14.176s, sys 0m18.400s</li>\n<li>m6gd.2xlarge aarch64 ARM time: real 3m54.493s, user 3m39.324s, sys 0m15.373s</li>\n</ul>\n<pre><code>\nexport PGDATA=~/pgdata\necho \"$PATH\" | grep /usr/local/pgsql/bin || export PATH=\"$PATH:/usr/local/pgsql/bin\"\ninitdb\npg_ctl -l postgres.log start\ntop -bn1 -cp $(pgrep -xd, postgres)\n</code></pre>\n<p>Environment is set and instance started</p>\n<pre><code>\nsed -ie \"/shared_buffers/s/^.*=.*/shared_buffers= 8500MB/\" $PGDATA/postgresql.conf\nsed -ie \"/huge_pages/s/^.*=.*/huge_pages= true/\" $PGDATA/postgresql.conf\nawk '/Hugepagesize.*kB/{print 1 + int(1024 * MB / $2)}' MB=9000 /proc/meminfo | sudo bash -c  \"cat &gt; /proc/sys/vm/nr_hugepages\" \npg_ctl -l postgres.log restart\n</code></pre>\n<p>I set 8GB of shared buffers to be sure to measure logical I/O from the database shared memory.</p>\n<h3>PGIO</h3>\n<pre><code>\ngit clone https://github.com/therealkevinc/pgio\ntar -zxf pgio/pgio*tar.gz\ncat &gt; pgio/pgio.conf &lt;&lt;CAT\n UPDATE_PCT=0\n RUN_TIME=$(( 60 * 600 ))\n NUM_SCHEMAS=4\n NUM_THREADS=1\n WORK_UNIT=255\n UPDATE_WORK_UNIT=8\n SCALE=1024M\n DBNAME=pgio\n CONNECT_STRING=\"pgio\"\n CREATE_BASE_TABLE=TRUE\nCAT\ncat pgio/pgio.conf\npsql postgres &lt;&lt;&lt;'create database pgio;'\ntime ( cd pgio &amp;&amp; sh setup.sh )\n</code></pre>\n<p>I initialized PGIO for four 1GB schemas</p>\n<pre><code>\necho $(curl -s http://169.254.169.254/latest/meta-data/instance-type) $(uname -m)\ntime ( cd pgio &amp;&amp; sh runit.sh )\nuptime\n</code></pre>\n<p>This will run PGIO as configured (4 threads on 1GB for 1 hour)</p>\n<h4>4 threads on ARM</h4>\n<pre><code>[ec2-user@ip-172-31-46-196 ~]$ echo $(curl -s http://169.254.169.254/latest/meta-data/instance-type) $(uname -m)\n\nm6gd.2xlarge aarch64                    \n\n[ec2-user@ip-172-31-46-196 ~]$ time ( cd pgio &amp;&amp; sh runit.sh )\n\nDate: Fri Mar  5 11:35:18 UTC 2021\nDatabase connect string: \"pgio\".\nShared buffers: 8GB.\nTesting 4 schemas with 1 thread(s) accessing 1024M (131072 blocks) of each schema.\nRunning iostat, vmstat and mpstat on current host--in background.\nLaunching sessions. 4 schema(s) will be accessed by 1 thread(s) each.\npg_stat_database stats:\n          datname| blks_hit| blks_read|tup_returned|tup_fetched|tup_updated\nBEFORE:  pgio    | 12676581 |   2797475 |      2663112 |       26277 |         142\nAFTER:   pgio    | 11254053367 |   2797673 |  11063125066 | 11057981670 |         162\nDBNAME:  pgio. 4 schemas, 1 threads(each). Run time: 3600 seconds. RIOPS &gt;0&lt; CACHE_HITS/s &gt;3122604&lt;\n</code></pre>\n<p>This is about 780651 LIOPS / thread.</p>\n<h4>4 threads on x86</h4>\n<pre><code>\n[ec2-user@ip-172-31-29-57 ~]$ echo $(curl -s http://169.254.169.254/latest/meta-data/instance-type) $(uname -m)\n\nm5d.2xlarge x86_64\n\n[ec2-user@ip-172-31-29-57 ~]$ time ( cd pgio &amp;&amp; sh runit.sh )\nuptimeDate: Fri Mar  5 13:20:10 UTC 2021\nDatabase connect string: \"pgio\".\nShared buffers: 8500MB.\nTesting 4 schemas with 1 thread(s) accessing 1024M (131072 blocks) of each schema.\nRunning iostat, vmstat and mpstat on current host--in background.\nLaunching sessions. 4 schema(s) will be accessed by 1 thread(s) each.\npg_stat_database stats:\n          datname| blks_hit| blks_read|tup_returned|tup_fetched|tup_updated\nBEFORE:  pgio    | 109879603 | 2696860921 |   2759130206 |  2757898526 |          20\nAFTER:   pgio    | 13016322621 | 2697387365 |  15459965084 | 15455884319 |          20\nDBNAME:  pgio. 4 schemas, 1 threads(each). Run time: 3600 seconds. RIOPS &gt;146&lt; CACHE_HITS/s &gt;3585123&lt;\n</code></pre>\n<p>This is about 896280 LIOPS / thread.</p>\n<h3>pgbench</h3>\n<p>For pgbench test you may want to read <a href=\"https://www.percona.com/blog/2021/01/22/postgresql-on-arm-based-aws-ec2-instances-is-it-any-good/\" target=\"_blank\" rel=\"noopener\">https://www.percona.com/blog/2021/01/22/postgresql-on-arm-based-aws-ec2-instances-is-it-any-good/</a> where Jobin Augustine and Sergey Kuzmichev have run long tests, read-only and read-write, with and without checksum. And also sysbench-tpcc. I&#8217;m doing only a very simple test here to show that result depend on what you test.</p>\n<pre><code>\ntime pgbench -i -s 100 postgres\n</code></pre>\n<h4>pgbench simple protocol</h4>\n<pre><code>\ntime pgbench -T 600 -c 4 --protocol=simple postgres\n</code></pre>\n<p>Result:</p>\n<ul>\n<li>m5d.2xlarge x86_64 Xeon: tps = 2035.794849 (excluding connections establishing)</li>\n<li>m6gd.2xlarge aarch64 ARM: tps = 2109.661869 (excluding connections establishing)</li>\n</ul>\n<h4>pgbench prepared statements</h4>\n<pre><code>\ntime pgbench -T 600 -c 4 --protocol=prepared postgres\n</code></pre>\n<p>Result:</p>\n<ul>\n<li>m5d.2xlarge x86_64 Xeon: tps = 2107.070647 (excluding connections establishing)</li>\n<li>m6gd.2xlarge aarch64 ARM: tps = 2121.966940 (excluding connections establishing)</li>\n</ul>\n<h3>Price/Performance</h3>\n<p>Here is the price of the instance I used. The software is free and the EC2 running hours for Graviton2 is 20% cheaper:</p>\n<ul>\n<li>m5d.2xlarge x86_64 Xeon EC2 cost: $0.504/hr</li>\n<li>m6gd.2xlarge aarch64 ARM EC2 cost: $0.403/hr</li>\n</ul>\n<p>The compilation time for the PostgreSQL sources was 11% slower on ARM: 3 minutes 39 seconds vs. 3 minutes 14 seconds vs.<br />\nThe PostgreSQL shared buffer cache hits were 13% faster x86: 896280 LIOPS / thread vs. 780651 LIOPS / thread, but that is the most optimal database work: all in shared buffers, limited calls, roundtrips and context switch. All is in CPU and RAM access.<br />\nHowever, where running pgbench, ARM had nearly the same performance for the prepared statement protocol and even a bit faster with the simple protocol. And that&#8217;s finally what most of database applications are doing. So, finally, the big difference is the price as the Graviton2 m6gd.2xlarge is 20% cheaper than the m5d.2xlarge x86. Here I installed PostgreSQL on EC2, but Graviton2 is available on RDS as well (in preview) with db.r6g</p>\n<p>I&#8217;ve given more details about the GCC version and compilation flags in the <a href=\"https://www.dbi-services.com/blog/aws-postgresql-on-graviton2-aarch64/\" target=\"_blank\" rel=\"noopener\">next post</a></p>\n",
    "protected": false
  }
}
