O benchmarking é uma forma de descobrir o desempenho de sua infraestrutura. Sysbench é uma ótima ferramenta para benchmark de servidores PostgreSQL. Nesta postagem do blog, mostraremos como gerar cargas de teste usando o sysbench. Usaremos uma configuração de replicação de streaming mestre-escravo de dois nós pelo ClusterControl. Isso também nos ajudará a gerar alguma atividade no cluster e verificar se a replicação está funcionando conforme o esperado.
Instalaremos a versão mais recente do sysbench, atualmente mantida aqui. Usaremos o pacote mais atualizado fornecido na página oficial do Github para instalar o sysbench. Também usaremos os binários padrão do PostgreSQL 9.6 da página de download do PostgreSQL. Observe que o caminho usado nesta postagem do blog pode ser diferente dependendo da versão do PostgreSQL e do fornecedor que você instalou.
Como uma observação lateral, abordamos uma postagem de blog semelhante sobre o benchmarking do PostgreSQL usando o pgbench nesta postagem do blog, Como comparar o desempenho do PostgreSQL.
Instalando o Sysbench
Instalar o sysbench é fácil. Para Debian/Ubuntu:
$ curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.deb.sh | sudo bash
$ sudo apt -y install sysbench
E para RHEL/CentOS:
$ curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash
$ sudo yum -y install sysbench
Instale o pacote sysbench:
$ yum install sysbench
Verifique a versão:
$ sysbench --version
sysbench 1.0.15
Agora instalamos o sysbench.
Inicializando dados de teste
Se você estiver familiarizado com o sysbench, ele usa os seguintes padrões para os parâmetros do PostgreSQL:
- pgsql-host=localhost
- pgsql-port=5432
- pgsql-user=sbtest
- pgsql-password=senha
- pgsql-db=sbtest
Primeiramente, crie o banco de dados e o usuário dentro do PostgreSQL:
$ su - postgres
$ psql
> CREATE USER sbtest WITH PASSWORD 'password';
> CREATE DATABASE sbtest;
> GRANT ALL PRIVILEGES ON DATABASE sbtest TO sbtest;
Em seguida, edite o arquivo de acesso baseado em host, pg_hba.conf :
$ vim /var/lib/pgsql/9.6/data/pg_hba.conf
E adicione a seguinte linha para permitir conexões para o usuário sbtest, ao banco de dados sbtest de todos os hosts na rede 192.168.55.0:
host sbtest sbtest 192.168.55.0/24 md5
Recarregue o servidor para aplicar as alterações:
$ /usr/pgsql-9.6/bin/pg_ctl --reload
Verifique no cliente de linha de comando psql se a autenticação do usuário funciona corretamente:
$ psql -U sbtest -h 192.168.55.61 -p 5432 -d sbtest -W
Você deve conseguir entrar no servidor no banco de dados sbtest:
$ psql -U sbtest -h 192.168.55.61 -p 5432 -W
Password for user sbtest:
Type "help" for help.
sbtest=>
Execute "\q" para sair do terminal. Agora podemos inicializar o banco de dados usando o sysbench com o seguinte comando:
$ sysbench \
--db-driver=pgsql \
--oltp-table-size=100000 \
--oltp-tables-count=24 \
--threads=1 \
--pgsql-host=192.168.55.61 \
--pgsql-port=5432 \
--pgsql-user=sbtest \
--pgsql-password=password \
--pgsql-db=sbtest \
/usr/share/sysbench/tests/include/oltp_legacy/parallel_prepare.lua \
run
O comando acima gera 100.000 linhas por tabela para 24 tabelas (sbtest1 a sbtest24) dentro do banco de dados 'sbtest'. O nome do esquema é "público", que é o padrão. Os dados são preparados por um script chamado parallel_prepare.lua que está disponível em /usr/share/sysbench/tests/include/oltp_legacy.
Verifique as tabelas geradas com o seguinte comando:
$ psql -U sbtest -h 192.168.55.61 -p 5432 -W -c '\dt+\'
Password for user sbtest:
List of relations
Schema | Name | Type | Owner | Size | Description
--------+----------+-------+--------+-------+-------------
public | sbtest1 | table | sbtest | 21 MB |
public | sbtest10 | table | sbtest | 21 MB |
public | sbtest11 | table | sbtest | 21 MB |
public | sbtest12 | table | sbtest | 21 MB |
public | sbtest13 | table | sbtest | 21 MB |
public | sbtest14 | table | sbtest | 21 MB |
public | sbtest15 | table | sbtest | 21 MB |
public | sbtest16 | table | sbtest | 21 MB |
public | sbtest17 | table | sbtest | 21 MB |
public | sbtest18 | table | sbtest | 21 MB |
public | sbtest19 | table | sbtest | 21 MB |
public | sbtest2 | table | sbtest | 21 MB |
public | sbtest20 | table | sbtest | 21 MB |
public | sbtest21 | table | sbtest | 21 MB |
public | sbtest22 | table | sbtest | 21 MB |
public | sbtest23 | table | sbtest | 21 MB |
public | sbtest24 | table | sbtest | 21 MB |
public | sbtest3 | table | sbtest | 21 MB |
public | sbtest4 | table | sbtest | 21 MB |
public | sbtest5 | table | sbtest | 21 MB |
public | sbtest6 | table | sbtest | 21 MB |
public | sbtest7 | table | sbtest | 21 MB |
public | sbtest8 | table | sbtest | 21 MB |
public | sbtest9 | table | sbtest | 21 MB |
(24 rows)
Os dados de teste agora estão carregados.
Baixe o whitepaper hoje PostgreSQL Management &Automation with ClusterControlSaiba o que você precisa saber para implantar, monitorar, gerenciar e dimensionar o PostgreSQLBaixe o whitepaper
Gerar cargas de teste
Existem diferentes tipos de carga de trabalho de banco de dados que você pode executar com o sysbench, conforme mostrado nas seções a seguir.
Carregamento de leitura/gravação
O comando é semelhante à versão do MySQL do sysbench. Parâmetros semelhantes podem ser usados, exceto parâmetros relacionados ao PostgreSQL:
$ sysbench \
--db-driver=pgsql \
--report-interval=2 \
--oltp-table-size=100000 \
--oltp-tables-count=24 \
--threads=64 \
--time=60 \
--pgsql-host=192.168.55.61 \
--pgsql-port=5432 \
--pgsql-user=sbtest \
--pgsql-password=password \
--pgsql-db=sbtest \
/usr/share/sysbench/tests/include/oltp_legacy/oltp.lua \
run
O comando acima irá gerar a carga de trabalho OLTP do script LUA chamado /usr/share/sysbench/tests/include/oltp_legacy/oltp.lua, contra 100.000 linhas de 24 tabelas com 64 threads de trabalho por 60 segundos no host 192.168.55.61 (master ). A cada 2 segundos, o sysbench reportará as estatísticas intermediárias (--report-interval=2 ).
Uma vez executado, você obteria algo como abaixo:
sysbench 1.0.15 (using bundled LuaJIT 2.1.0-beta2)
Running the test with following options:
Number of threads: 16
Report intermediate results every 2 second(s)
Initializing random number generator from current time
Initializing worker threads...
Threads started!
[ 2s ] thds: 64 tps: 0.00 qps: 466.69 (r/w/o: 406.55/28.33/31.81) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
[ 4s ] thds: 64 tps: 30.55 qps: 525.38 (r/w/o: 335.56/128.72/61.10) lat (ms,95%): 3639.94 err/s: 0.00 reconn/s: 0.00
[ 6s ] thds: 64 tps: 39.55 qps: 718.41 (r/w/o: 496.13/142.68/79.60) lat (ms,95%): 4128.91 err/s: 0.00 reconn/s: 0.00
[ 8s ] thds: 64 tps: 35.98 qps: 840.95 (r/w/o: 604.11/163.89/72.95) lat (ms,95%): 2198.52 err/s: 0.50 reconn/s: 0.00
[ 10s ] thds: 64 tps: 65.57 qps: 1314.94 (r/w/o: 912.00/271.80/131.14) lat (ms,95%): 3040.14 err/s: 0.00 reconn/s: 0.00
...
Quando o teste estava em andamento, podemos monitorar a atividade do PostgreSQL usando pg_activity ou pg_top , para confirmar a estatística intermediária relatada pelo sysbench. Em outro terminal, faça:
$ su - postgres
$ pg_activity
PostgreSQL 9.6.9 - postgres1.local - [email protected]:5432/postgres - Ref.: 2s
Size: 654.62M - 7.67K/s | TPS: 74
Mem.: 39.10% - 382.72M/979.68M | IO Max: 3395/s
Swap: 0.20% - 3.57M/2.00G | Read : 8.36M/s - 2141/s
Load: 20.20 6.02 2.44 | Write: 2.54M/s - 650/s
RUNNING QUERIES
PID DATABASE USER CLIENT CPU% MEM% READ/s WRITE/s TIME+ W IOW state Query
5130 sbtest sbtest 192.168.55.61 1.0 2.8 791.57K 3.84K 0.788732 N N active SELECT c FROM sbtest7 WHERE id BETWEEN 33195
AND 33294
...
Assim como o fluxo de replicação, observando o pg_stat_replication tabela no servidor mestre:
$ su - postgres
$ watch -n1 'psql -xc "select * from pg_stat_replication"'
Every 1.0s: psql -xc "select * from pg_stat_replication" Tue Jul 31 13:12:08 2018
-[ RECORD 1 ]----+------------------------------
pid | 3792
usesysid | 16448
usename | slave
application_name | walreceiver
client_addr | 192.168.55.62
client_hostname |
client_port | 44654
backend_start | 2018-07-30 13:41:41.707514+08
backend_xmin |
state | streaming
sent_location | 0/60933D78
write_location | 0/60933D78
flush_location | 0/60933D78
replay_location | 0/60933D78
sync_priority | 0
sync_state | async
O comando "watch" acima executa o comando psql a cada 1 segundo. Você deve ver que as colunas "*_location" são atualizadas de acordo quando a replicação acontece.
Ao final do teste, você deverá ver o resumo:
SQL statistics:
queries performed:
read: 67704
write: 19322
other: 9682
total: 96708
transactions: 4830 (79.34 per sec.)
queries: 96708 (1588.53 per sec.)
ignored errors: 6 (0.10 per sec.)
reconnects: 0 (0.00 per sec.)
General statistics:
total time: 60.8723s
total number of events: 4830
Latency (ms):
min: 4.52
avg: 799.70
max: 8082.70
95th percentile: 2279.14
sum: 3862532.62
Threads fairness:
events (avg/stddev): 75.4688/7.39
execution time (avg/stddev): 60.3521/0.20
O resumo acima nos diz que nosso servidor de banco de dados PostgreSQL pode lidar em média com cerca de 80 transações por segundo e cerca de 1.588 consultas por segundo em 64 threads de trabalho.
Carregamento somente leitura
Para teste somente leitura, você pode usar o mesmo comando, mas altere o script LUA para select.lua , select_random_points.lua , select_random_ranges.lua ou oltp_simple.lua :
$ sysbench \
--db-driver=pgsql \
--report-interval=2 \
--oltp-table-size=100000 \
--oltp-tables-count=24 \
--threads=64 \
--time=60 \
--pgsql-host=192.168.55.62 \
--pgsql-port=5432 \
--pgsql-user=sbtest \
--pgsql-password=password \
--pgsql-db=sbtest \
/usr/share/sysbench/tests/include/oltp_legacy/select.lua \
run
O comando acima executa uma carga de trabalho somente leitura chamada select.lua contra um servidor escravo PostgreSQL (replicação de streaming), 192.168.55.62 com 64 threads de trabalho.
Outras cargas
Existem muitas outras cargas de trabalho OLTP que você pode gerar com o sysbench, conforme listado neste diretório, /usr/share/sysbench/tests/include/oltp_legacy :
$ ls -1 /usr/share/sysbench/tests/include/oltp_legacy/
bulk_insert.lua
common.lua
delete.lua
insert.lua
oltp.lua
oltp_simple.lua
parallel_prepare.lua
select.lua
select_random_points.lua
select_random_ranges.lua
update_index.lua
update_non_index.lua
Você pode usar o comando semelhante e alterar o caminho para o script LUA para carregá-lo.
Considerações finais
Usando o sysbench, podemos gerar cargas de teste para nosso servidor PostgreSQL (assim como para MySQL). Observe que o melhor benchmark seria com seus dados e aplicativos reais, mas isso nem sempre é possível. Também pode ser um novo aplicativo que evoluirá rapidamente. Apesar da carga gerada pelo sysbench não representar sua carga de trabalho OLTP do mundo real, ela pode ser boa o suficiente.