Arquivo de etiquetas: pgbench

Medir o desempenho do PostgreSQL

Não é todos os dias que temos a oportunidade de fazer um upgrade ao nosso velhinho servidor de PostGIS. Quando um servidor usado fica disponível ou, ainda melhor, quando recebemos uma máquina novinha em folha para instalar a nossa base de dados, queremos saber qual a melhoria de desempenho que vamos ter. Pelo menos eu quero Piscar de olho

Por outro lado, se vamos comprar um novo servidor temos de definir as características dentro do preço que podemos pagar. E convém ter uma orientação que nos ajude a perceber que tipo de desempenho podemos obter dentro desse orçamento.

Outra utilidade para este tipo de medição é perceber quais os melhores parâmetros de configuração do PostgreSQL para a nossa nova máquina. Podemos alterar os parâmetros e testar, vendo rapidamente qual a combinação de parâmetros que melhor desempenho consegue.

Este artigo mostra como medir o desempenho do PostgreSQL usando o comando standard para isso – o pgbench. Para outro post fica a proposta de um teste standard para medir o desempenho da componente geográfica – PostGIS – usando o pgbench com dados geográficos disponíveis publicamente. Isto permite que todos os utilizadores de PostGIS possam usar um teste padrão, tal como já existe para dados não-espaciais, e comparar diferentes servidores.

O ideal seria ter uma tabela online onde se pudessem comparar vários servidores, editada pelos utilizadores… isso é que era!

Os 2 servidores em confronto

Ao longo do artigo vão ser feitas comparações de desempenho entre 2 servidores praticamente iguais ao nível do hardware, onde apenas se altera o sistema de disco – o novo servidor promete muito melhor desempenho de disco. Mas há também diferenças no software – a versão do sistema operativo, e as versões do PostgreSQL e PostGIS são mais recentes e passam a 64bit. As características dos servidores são as seguintes:

Servidor CPU RAM Disco SO PostgreSQL PostGIS
velho Xeon E5420, 4cores 2,5GHz 12 GB SAN, 215GB Win 2003 x64 8.4.10, x32 1.4.2
novo Igual Igual SAN, 50GB Win 2008 x64 9.2.8, x64 2.1.1

Ambos os servidores têm a mesma configuração do PostgreSQL:

  • Shared Buffers: 512MB
  • Work Memory: 6MB
  • Effective Cache Size:  256MB

Usar o pgbench

O pgbench é uma ferramenta que vem incluída na instalação do PostgreSQL, e é usada para efectuar testes padronizados de desempenho transacional. Ou seja, é um teste que todos os utilizadores podem fazer e comparar entre si, já que o teste é sempre o mesmo, usando os mesmos dados. Como sempre, a documentação do PostgreSQL é excelente e o manual do pgbench também.

Como o pgbench envia comandos SQL para o servidor tentando levá-lo ao limite das suas capacidades, convém executá-lo a partir de outro computador ligado em rede, como por exemplo, o seu portátil ou desktop.

Para começar, temos de usar o pgbench para criar os dados necessários aos testes. Aqui temos de ter já uma ideia de quantas conexões vamos considerar. Isto depende do(s) processador(es) do nosso servidor. Quanto mais cores mais conexões simultâneas vamos conseguir executar em simultâneo. Podemos jogar pelo seguro e exagerar um pouco. Por exemplo, para o meu processador de 4 cores, vou iniciar os dados para 20 conexões simultâneas, embora saiba de antemão que são demasiadas (vou acabar por fazer os testes com apenas 12 conexões).

Para criar os dados, o pgbench precisa de saber o nome da base de dados a usar (que tem já existir). Se instalámos o PostGIS é provável que tenhamos criado uma bd com o nome “postgis” e é isso que vou usar nos exemplos. Também nos exemplos, o nome do servidor será “pgServer” e o utilizador será “userteste”.

Assim, para começar, executamos o pgbench no nosso computador (não no servidor) com o seguinte comando:

pgbench –i –s 20 –h pgServer –U userteste postgis

Este comando irá criar as tabelas do teste no schema do utilizador “userteste” e criará dados suficientes para testar 20 conexões simultâneas.

Em seguida vamos medir o desempenho do nosso servidor, medido em Transações por segundo, ou TPS.

O pgbench é muito completo, mas vamos simplificar e medir apenas 2 tipos de operações:

  • Transação típica, em que os registos são inseridos em tabelas relacionadas entre elas com chaves primárias e estrangeiras. Este é o desempenho mais típico de uma base de dados. É medida uma mistura de operações de escrita e leitura, com garantia de integridade.
  • Transação apenas de leitura, em que apenas se testa a componente de leitura da bd. Em princípio mede o valor máximo de TPS para o nosso servidor.

Vamos executar todos os testes durante 5 minutos. Assim, para testar a transação típica, vamos usar o comando seguinte:

pgbench –h pgServer –U userteste –c 12 –j 2 –T 300 postgis

A explicação do comando é a seguinte:

  • -c 12 => testar 12 conexões em simultâneo
  • -j 2 => cada conexão em 2 threads
  • -T 300 => testar durante 300 segundos, ou seja, 5 minutos

Já vamos ver os resultados mais à frente… para já temos de discutir como aparecem as 12 conexões…

Um servidor consegue responder a 1 só conexão com uma certa rapidez ou velocidade, medida em TPS. E queremos que seja o mais rápido possível. Ao aumentarmos o número de conexões, em principio, também vai aumentando o número de pedidos à base de dados que são processados por segundo pelo servidor. Até que estagna e começa a reduzir-se. Isto significa que o servidor tem um limite para processar pedidos em simultâneo. O seu máximo de TPS será obtido para um dado número de conexões. Este TPS máximo é um dos melhores indicadores de desempenho de um servidor de base de dados.

A questão que este comando coloca é: como vamos definir o n.º de conexões a testar? De forma geral, o servidor nunca deve ultrapassar os 85% de ocupação de CPU, porque acima deste valor começa a sentir-se contenção no acesso ao processador, ou seja, começa a formar-se uma fila de pedidos que aguardam pela disponibilidade do CPU para serem executados, e o próprio sistema operativo começa a atrapalhar-se. É este o nosso alvo – manter o CPU próximo dos 85% de uso.

Felizmente, podemos perceber rapidamente qual é o n.º de conexões que mantém o CPU perto dos 85%. Em geral, a partir daqui o valor de TPS não aumenta, podendo mesmo baixar.

Isto é muito fácil: basta executar alguns comandos pgbench rápidos, de 30 segundos (usando -T 30 em vez de –T 300), com cada vez mais conexões, e vigiar o CPU do servidor ao mesmo tempo que apontamos os resultados. Há um n.º de conexões que acaba por saturar o processador e partir do qual não se aumenta o desempenho. Por exemplo, podemos usar esta sequência de comandos:

pgbench –h pgServer –U userteste –c 6 –j 2 –T 30 postgis

pgbench –h pgServer –U userteste –c 8 –j 2 –T 30 postgis

pgbench –h pgServer –U userteste –c 10 –j 2 –T 30 postgis

pgbench –h pgServer –U userteste –c 12 –j 2 –T 30 postgis

pgbench –h pgServer –U userteste –c 14 –j 2 –T 30 postgis

No meu caso, as 12 conexões revelaram ser o ideal, o CPU nunca passou os 85%, e o desempenho foi o maior de todos. Já com 14 conexões, o desempenho começou a reduzir ligeiramente.

Resultados do pgbench

Os resultados do comando acima são os seguintes:

starting vacuum...end.
transaction type: TPC-B (sort of)
scaling factor: 20
query mode: simple
number of clients: 12
number of threads: 2
duration: 300 s
number of transactions actually processed: 537417
tps = 1791.328213 (including connections establishing)
tps = 1792.516930 (excluding connections establishing)

Qual a conclusão?

Este servidor conseguiu executar 537.417 transações “normais” do pgbench, em 5 minutos, o que dá um valor de 1.792 transações por segundo (TPS). Com este número já podemos comparar com outros servidores que tenham usado o pgbench.

Em seguida, medimos também o desempenho com transações apenas de leitura, usando um comando quase igual – apenas adicionamos o parâmetro –S:

pgbench –h pgServer –U userteste –c 12 –j 2 –T 300 –S postgis

Os resultados são os seguintes:

starting vacuum...end.
transaction type: SELECT only
scaling factor: 20
query mode: simple
number of clients: 12
number of threads: 2
duration: 300 s
number of transactions actually processed: 6844551
tps = 22815.432028 (including connections establishing)
tps = 22830.845226 (excluding connections establishing)

Ou seja, para queries apenas de leitura, conseguimos um TPS de 22.830, muito mais elevado, como é de esperar.

Assim, a comparação entre o servidor antigo e o novo fica com este aspecto:

Servidor Teste “normal” (TPS) Teste só leitura (TPS)
velho 590 20.944
novo 1.792 22.830

Boas notícias. Tudo aponta que o novo servidor vale a pena… +200% de desempenho em queries mistas, e +9% em queries de leitura apenas. Isto confirma a suspeita inicial: o sistema de discos do novo servidor é muitíssimo melhor, sendo o seu impacto terrivelmente visível no desempenho de escrita na base de dados, e ainda aumentando o desempenho de leitura em 9% (até porque grande parte das queries de leitura são efectuadas em memória). Claro que a introdução de uma nova versão de PostgreSQL também terá a sua influência, e neste caso é impossível determiná-la.

No próximo artigo vamos medir o desempenho do PostGIS, usando o pgbench com dados geográficos.

Até lá, bons desempenhos! Piscar de olho