|
1 | | -# PostgREST benchmark(Work in progress) |
| 1 | +# PostgREST Benchmark |
2 | 2 |
|
3 | | -Updated and reproducible benchmark for PostgREST by using [Nix](https://nixos.org/) and [k6](https://k6.io/). |
| 3 | +Repeatable benchmark for PostgREST by using [Nix](https://nixos.org/) and [NixOps](https://github.com/NixOS/nixops). |
4 | 4 |
|
5 | | -## Setup |
| 5 | +NixOps provisions AWS EC2 instances on a dedicated VPC and deploys the different components for load testing. |
6 | 6 |
|
7 | | -The tests are ran on AWS EC2 instances on a dedicated VPC. The client(k6) and the servers(pg+pgrest) are on different instances. This whole setup will be handled by Nix. |
| 7 | +The default setup includes: |
| 8 | + |
| 9 | +- A `m5a.xlarge` instance which uses [k6](https://k6.io/) for load testing. |
| 10 | +- A `t3a.nano` instance with PostgreSQL. |
| 11 | +- A `t3a.nano` instance with PostgREST + Nginx. |
| 12 | + |
| 13 | +This setup, including the size of the EC2 instances, can be modified with environment variables. As the PostgreSQL server instance size increases, its settings are modified according to [PGTune](https://pgtune.leopard.in.ua/) recommendations. |
| 14 | + |
| 15 | +## Requirements |
| 16 | + |
| 17 | +- [AWS](https://aws.amazon.com) account with an `~/.aws/credentials` file in place (can be created with `aws-cli`). The "default" profile is picked up by default but you can change it by doing: |
| 18 | + ``` |
| 19 | + export PGRSTBENCH_AWS_PROFILE="another_profile" |
| 20 | + ``` |
| 21 | + |
| 22 | +- [Nix](https://nixos.org/). |
| 23 | + |
| 24 | +## Quickstart |
8 | 25 |
|
9 | 26 | Run `nix-shell`. This will provide an environment where all the dependencies are available. |
10 | 27 |
|
11 | 28 | ``` |
12 | | -nix-shell |
| 29 | +$ nix-shell |
13 | 30 | > |
14 | 31 | ``` |
15 | 32 |
|
16 | | -Now create the environment with nixops. |
| 33 | +Deploy with: |
| 34 | + |
| 35 | +``` |
| 36 | +$ pgrstbench-deploy |
| 37 | +
|
| 38 | +pgrstBenchVpc.....> creating vpc under region us-east-2 |
| 39 | +.. |
| 40 | +
|
| 41 | +pg................> activation finished successfully |
| 42 | +pgrstbench> deployment finished successfully |
| 43 | +
|
| 44 | +# this command will take a couple minutes, it will deploy the client and server AWS machines VPC stuff |
| 45 | +``` |
| 46 | + |
| 47 | +Run a `k6` test on the client instance and get the output: |
| 48 | + |
| 49 | +``` |
| 50 | +$ pgrstbench-k6 20 k6/GETSingle.js |
| 51 | +``` |
| 52 | + |
| 53 | +Destroy all the setup and the AWS instances: |
| 54 | + |
| 55 | +``` |
| 56 | +$ pgrstbench-destroy |
| 57 | +``` |
| 58 | + |
| 59 | +## SSH |
| 60 | + |
| 61 | +To connect to the PostgreSQL instance: |
| 62 | + |
| 63 | +``` |
| 64 | +$ pgrstbench-ssh pg |
| 65 | +
|
| 66 | +# Check the installed services |
| 67 | +$ systemctl list-units |
| 68 | +
|
| 69 | +## connect to postgres |
| 70 | +$ psql -U postgres |
| 71 | +$ \d |
| 72 | +``` |
| 73 | + |
| 74 | +The postgresql server comes loaded with the [chinook database](https://github.com/xivSolutions/ChinookDb_Pg_Modified). |
| 75 | + |
| 76 | +To connect to the PostgREST instance: |
| 77 | + |
| 78 | +``` |
| 79 | +$ pgrstbench-ssh pgrst |
| 80 | +
|
| 81 | +# Check the installed services |
| 82 | +$ systemctl list-units |
| 83 | +
|
| 84 | +# Do a request |
| 85 | +$ curl localhost:80/artist |
| 86 | +``` |
| 87 | + |
| 88 | +You can also get info (like the IPs) of the instances with: |
| 89 | + |
| 90 | +``` |
| 91 | +$ pgrstbench-info |
| 92 | +``` |
| 93 | + |
| 94 | +## K6 |
| 95 | + |
| 96 | +K6 runs on the client instance, but you can get the output of the load test on your machine: |
| 97 | + |
| 98 | +``` |
| 99 | +## k6 will run with 10 VUs on the AWS client instance and load test the t3anano instance with the local k6/GETSingle.js script |
| 100 | +$ pgrbench-k6 10 k6/GETSingle.js |
| 101 | +
|
| 102 | +## You will see the k6 logo and runs here |
| 103 | +``` |
| 104 | + |
| 105 | +There are different scripts on `k6/` which test different PostgREST requests. |
17 | 106 |
|
| 107 | +## Pgbench |
| 108 | + |
| 109 | +pgbench also runs on the client instance, you can get its output with: |
| 110 | + |
| 111 | +``` |
| 112 | +$ pgrstbench-pgbench pgbench/GETSingle.sql |
18 | 113 | ``` |
19 | | -# This assumes there's a `~/.aws/credentials` file(created with aws-cli) with a default profile. |
20 | | -nixops create ./deploy.nix -d pgrst-bench |
21 | 114 |
|
22 | | -# To explore and connect to the ec2 instances |
23 | | -# nixops ssh -d pgrst-bench t2nano |
24 | | -# nixops ssh -d pgrst-bench t3anano |
25 | | -# nixops ssh -d pgrst-bench client |
26 | | -# |
27 | | -# you can inspect the db with |
28 | | -# psql -U postgres |
29 | | -# \d |
| 115 | +The `GETSingle.sql` runs an equivalent SQL statement to what PostgREST generates for `GETSingle.js`. The motivation for this comparison is to see how much PostgREST performance differs from direct SQL connections. |
| 116 | + |
| 117 | +## Varying Scripts |
| 118 | + |
| 119 | +There are scripts that help with varying the environment while load testing. You can use these to get a report once the command finishes running: |
| 120 | + |
| 121 | +Run pgbench with a different qty of clients: |
| 122 | + |
| 123 | +``` |
| 124 | +$ pgrstbench-pgbench-vary-clients pgbench/GETSingle.sql |
30 | 125 | ``` |
31 | 126 |
|
32 | | -## Usage |
| 127 | +Run k6 with a different qty of VUs: |
| 128 | + |
| 129 | +``` |
| 130 | +$ pgrstbench-k6-vary-vus k6/GETSingle.js |
| 131 | +``` |
33 | 132 |
|
34 | | -Run the k6 script: |
| 133 | +Run pgbench with varied clients and with varied pg instances (this will involve reprovisioning/redeploying the pg instance, it will take a while): |
35 | 134 |
|
36 | 135 | ``` |
37 | | -## k6 will run on the aws instance |
38 | | -nixops ssh -d pgrst-bench client k6 run -e HOST=t3anano - < k6/GETSingle.js |
| 136 | +$ pgrstbench-vary-pg pgrstbench-pgbench-vary-clients pgbench/GETSingle.sql > PGBENCH_GET_SINGLE.txt |
| 137 | +``` |
| 138 | + |
| 139 | +Run k6 with varied vus and with varied pg instances and pgrst instances (this will involve reprovisioning/redeploying the pg and pgrst instance, it will take even longer): |
| 140 | + |
| 141 | +``` |
| 142 | +$ pgrstbench-vary-pg-pgrst pgrstbench-k6-vary-vus k6/GETSingle.js > K6_GET_SINGLE.txt |
| 143 | +``` |
| 144 | + |
| 145 | +## Different Setups |
| 146 | + |
| 147 | +### Nginx included (default) |
| 148 | + |
| 149 | +To load test with nginx included do: |
| 150 | + |
| 151 | +```bash |
| 152 | +export PGRBENCH_WITH_NGINX="true" |
| 153 | +pgrbench-deploy |
| 154 | +``` |
| 155 | + |
| 156 | +To only have PostgREST listening directly on port 80: |
| 157 | + |
| 158 | +```bash |
| 159 | +export PGRBENCH_WITH_NGINX="false" |
| 160 | +pgrbench-deploy |
39 | 161 | ``` |
40 | 162 |
|
41 | | -(Steps for collecting the results are pending) |
| 163 | +### Unix socket (default) |
| 164 | + |
| 165 | +To load test connecting pgrest to pg with unix socket, and pgrest to nginx with unix socket. |
| 166 | + |
| 167 | +```bash |
| 168 | +export PGRBENCH_WITH_UNIX_SOCKET="true" |
| 169 | +pgrbench-deploy |
| 170 | +``` |
| 171 | + |
| 172 | +To use tcp instead, you can do: |
| 173 | + |
| 174 | +```bash |
| 175 | +export PGRBENCH_WITH_UNIX_SOCKET="false" |
| 176 | +pgrbench-deploy |
| 177 | +``` |
| 178 | + |
| 179 | +### Separate PostgreSQL instance (default) |
| 180 | + |
| 181 | +To load test with a pg on a different ec2 instance. |
| 182 | + |
| 183 | +```bash |
| 184 | +export PGRBENCH_SEPARATE_PG="true" |
| 185 | +pgrbench-deploy |
| 186 | +``` |
| 187 | + |
| 188 | +To use the same instance for both PostgreSQL and PostgREST. |
| 189 | + |
| 190 | +```bash |
| 191 | +export PGRBENCH_SEPARATE_PG="false" |
| 192 | +pgrbench-deploy |
| 193 | +``` |
| 194 | + |
| 195 | +### Two PostgREST instances over load balanced with Nginx |
| 196 | + |
| 197 | +Some experiments indicate that when load testing on big instances (like `m5a.8xlarge` and above), having two postgrest instances instead of one increase throughput. You can try this with: |
| 198 | + |
| 199 | +```bash |
| 200 | +export PGRSTBENCH_PGRST_NGNIX_LBS="true" |
| 201 | +pgrbench-deploy |
| 202 | +``` |
| 203 | + |
| 204 | +### Different EC2 instance types |
| 205 | + |
| 206 | +To change pg and PostgREST EC2 instance types(both `t3a.nano` by default): |
| 207 | + |
| 208 | +```bash |
| 209 | +export PGRBENCH_PG_INSTANCE_TYPE="t3a.xlarge" |
| 210 | +export PGRBENCH_PGRST_INSTANCE_TYPE="t3a.xlarge" |
| 211 | +export PGRBENCH_PGRST_INSTANCE_TYPE="t3a.xlarge" |
| 212 | + |
| 213 | +pgrbench-deploy |
| 214 | +``` |
42 | 215 |
|
43 | | -## Notes |
| 216 | +## Limitations |
44 | 217 |
|
45 | | -- Scenarios to test: |
46 | | - - [x]read heavy workload(with resource embedding) |
47 | | - - [x]write heavy workload(with and without [specifying-columns](http://postgrest.org/en/v7.0.0/api.html#specifying-columns)) |
48 | | - - [ ]pg + pgrest on the same machine(unix socket and tcp). |
49 | | - - [ ]pg and pgrest on different machines? |
50 | | - - [ ]pgrest with `pre-request`? |
| 218 | +- Uses an outdated version of NixOps, 1.7. Newer versions have changed considerably. |
| 219 | +- Don't try changing to ARM-based instances, these don't work with the above NixOps version. |
| 220 | + + The instances tested for this benchmark are the `t3a` series and the `m5a` series. |
51 | 221 |
|
52 | 222 | ## Other benchmarks |
53 | 223 |
|
|
0 commit comments