Benchmarking
============
.. raw:: html
The CNPG kubectl plugin provides an easy way for benchmarking a
PostgreSQL deployment in Kubernetes using CloudNativePG.
Benchmarking is focused on two aspects:
- the **database**, by relying on `pgbench `_
- the **storage**, by relying on `fio `_
.. Note::
`pgbench` and `fio` must be run in a staging or pre-production environment. Do not use these plugins in a production environment, as it might have catastrophic consequences on your databases and the other workloads/applications that run in the same shared environment.
pgbench
^^^^^^^
The ``kubectl`` CNPG plugin command ``pgbench`` executes a user-defined
``pgbench`` job against an existing Postgres Cluster.
Through the ``--dry-run`` flag you can generate the manifest of the job
for later modification/execution.
A common command structure with ``pgbench`` is the following:
.. code:: shell
kubectl cnpg pgbench \
-n \
--job-name \
--db-name \
--
.. Note::
Please refer to the `pgbench `_
for information about the specific options to be used in your jobs.
This example creates a job called ``pgbench-init`` that initializes for
``pgbench`` OLTP-like purposes the ``app`` database in a ``Cluster``
named ``cluster-example`` , using a scale factor of 1000:
.. code:: shell
kubectl cnpg pgbench \
--job-name pgbench-init \
cluster-example \
-- --initialize --scale 1000
.. Note::
This will generate a database with 100000000 records, taking approximately 13GB of space on disk.
You can see the progress of the job with:
.. code:: shell
kubectl logs jobs/pgbench-run
The following example creates a job called ``pgbench-run`` executing
``pgbench`` against the previously initialized database for 30 seconds,
using a single connection:
.. code:: shell
kubectl cnpg pgbench \
--job-name pgbench-run \
cluster-example \
-- --time 30 --client 1 --jobs 1
The next example runs ``pgbench`` against an existing database by using
the ``--db-name`` flag and the ``pgbench`` namespace:
.. code:: shell
kubectl cnpg pgbench \
--db-name pgbench \
--job-name pgbench-job \
cluster-example \
-- --time 30 --client 1 --jobs 1
By default, jobs do not expire. You can enable automatic deletion with
the ``--ttl`` flag. The job will be deleted after the specified duration
(in seconds).
.. code:: shell
kubectl cnpg pgbench \
--job-name pgbench-run \
--ttl 600 \
cluster-example \
-- --time 30 --client 1 --jobs 1
If you want to run a ``pgbench`` job on a specific worker node, you can
use the ``--node-selector`` option. Suppose you want to run the previous
initialization job on a node having the ``workload=pgbench`` label, you
can run:
.. code:: shell
kubectl cnpg pgbench \
--db-name pgbench \
--job-name pgbench-init \
--node-selector workload=pgbench \
cluster-example \
-- --initialize --scale 1000
The job status can be fetched by running:
::
kubectl get job/pgbench-job -n
NAME COMPLETIONS DURATION AGE
job-name 1/1 15s 41s
Once the job is completed the results can be gathered by executing:
::
kubectl logs job/pgbench-job -n
fio
^^^
The kubectl CNPG plugin command ``fio`` executes a fio job with default
values and read operations. Through the ``--dry-run`` flag you can
generate the manifest of the job for later modification/execution.
.. Note::
The kubectl plugin command `fio` will create a deployment with predefined fio job values using a ConfigMap. If you want to provide custom job values, we recommend generating a manifest using the `--dry-run` flag and providing your custom job values in the generated ConfigMap.
Example of default usage:
.. code:: shell
kubectl cnpg fio
Example with custom values:
.. code:: shell
kubectl cnpg fio \
-n \
--storageClass \
--pvcSize
Example of how to run the ``fio`` command against a ``StorageClass``
named ``standard`` and ``pvcSize: 2Gi`` in the ``fio`` namespace:
.. code:: shell
kubectl cnpg fio fio-job \
-n fio \
--storageClass standard \
--pvcSize 2Gi
The deployment status can be fetched by running:
.. code:: shell
kubectl get deployment/fio-job -n fio
NAME READY UP-TO-DATE AVAILABLE AGE
fio-job 1/1 1 1 14s
After running kubectl plugin command ``fio`` .
It will:
1. Create a PVC
2. Create a ConfigMap representing the configuration of a fio job
3. Create a fio deployment composed by a single Pod, which will run fio
on the PVC, create graphs after completing the benchmark and start
serving the generated files with a webserver. We use the
`fio-tools `_ image for that.
The Pod created by the deployment will be ready when it starts serving
the results. You can forward the port of the pod created by the
deployment
::
kubectl port-forward -n deployment/ 8000
and then use a browser and connect to ``http://localhost:8000/`` to get
the data.
The default 8k block size has been chosen to emulate a PostgreSQL
workload. Disks that cap the amount of available IOPS can show very
different throughput values when changing this parameter.
Below is an example diagram of sequential writes on a local disk mounted
on a dedicated Kubernetes node (1 hour benchmark):
.. figure:: /images/write_bw.1-2Draw.png
:width: 70%
:alt: Sequential writes bandwidth
Sequential writes bandwidth
After all testing is done, fio deployment and resources can be deleted
by:
.. code:: shell
kubectl cnpg fio --dry-run | kubectl delete -f -
make sure use the same name which was used to create the fio deployment
and add namespace if applicable.