PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Dimensionamento vertical do PostgreSQL


O PostgreSQL pode escalar muito bem verticalmente. Quanto mais recursos (CPU, memória, disco) você puder disponibilizar para o seu servidor PostgreSQL, melhor será seu desempenho. No entanto, enquanto algumas partes do Postgres podem usar automaticamente os recursos aumentados, outras partes precisam de alterações de configuração antes que as melhorias possam ser notadas.

Continue lendo para saber mais sobre como garantir que o PostgreSQL faça uso total do sistema em que você o está executando.

CPU

O que é dimensionado automaticamente


O PostgreSQL tem uma arquitetura de processo tradicional, que consiste em um masterprocess (chamado de postmaster ) que gera um novo processo (chamado debackend ) para cada nova conexão de cliente. Isso significa que, se houver mais núcleos de CPU disponíveis, mais processos poderão ser executados simultaneamente e, portanto, os back-ends não precisarão competir tanto pela disponibilidade da CPU. As consultas vinculadas à CPU serão concluídas mais rapidamente.

Você pode querer ajustar o máximo de conexões simultâneas permitidas em todo o sistema, por banco de dados ou por usuário:
-- system level
ALTER SYSTEM SET max_connections = 200;

-- database level
ALTER DATABASE dbname CONNECTION LIMIT 200;

-- user level
ALTER ROLE username CONNECTION LIMIT 20;

para que aplicativos desonestos não acabem monopolizando muitas conexões.

O que precisa ser ajustado


O servidor PostgreSQL pode gerar processos para cuidar de tarefas domésticas, como aspiração, replicação, assinaturas (para replicação lógica) etc.

A definição de configuração de nível superior para o número de processos de trabalho é:
# typically specified in postgresql.conf
max_worker_processes = 16

Aumentar este valor pode resultar em aceleração de trabalhos de manutenção, consultas paralelas e criação de índice.

Consultas paralelas


A partir da versão 9.6, o Postgres pode executar consultas paralelamente se o planejador de consultas decidir que isso ajudará. A consulta paralela envolve a geração de trabalhadores, a distribuição do trabalho entre eles e a coleta (coleção) dos resultados. Sujeito ao limite geral de max_worker_processes definido anteriormente, o Postgres determinará quantos workers podem ser gerados para consulta paralela dependendo do valor de duas configurações:
# the maximum number of workers that the system can
# support for parallel operations
max_parallel_workers = 8

# the maximum number of workers that can be started
# by a single Gather or Gather Merge node
max_parallel_workers_per_gather = 8

Se você tiver CPUs ociosas e consultas paralelizáveis, aumentar esses valores pode acelerar essas consultas.

Criação de índice paralelo


No Postgres 11, foi adicionado suporte para criação paralela de índices B-Tree. Se você cria índices B-Tree regularmente ou os REINDEX, aumentar esse valor pode ajudar:
# the maximum number of parallel workers that can be
# started by a single utility command
max_parallel_maintenance_workers = 8

Isso permitirá que o Postgres gere esses muitos trabalhadores (sujeito ao limite geral de max_worker_processes ) para acelerar a criação de índices B-Tree.

Replicação lógica


A replicação lógica (disponível no Postgres 10 e superior) depende de processos de trabalho no lado da assinatura para buscar alterações do editor. Ao solicitar ao Postgres para gerar mais operadores de replicação lógica, as alterações podem ser buscadas e aplicadas em paralelo, especialmente se houver mais tabelas. Esta configuração aumenta o número total de trabalhadores de replicação:
# maximum number of logical replication workers
max_logical_replication_workers = 8

Na replicação de streaming, você pode iniciar uma sincronização com um backup básico. No entanto, a replicação forlógica, as alterações precisam ser obtidas por meio do próprio protocolo de replicação, pela rede. Isso pode ser demorado. Permitir mais trabalhadores durante a fase de sincronização pode acelerar esse processo:
# basically the number of tables that are synced in
# parallel during initialization of subscription
max_sync_workers_per_subscription = 8

Autovacuum


Periodicamente, com base em um monte de configurações, o Postgres irá gerar um monte de workers que irão VACUUM as tabelas do banco de dados. Isso é, obviamente, chamado de autovacuum, e o número de trabalhadores que o lançador de autovacuum gera a cada vez pode ser definido por meio da configuração:
# the maximum number of autovacuum processes
autovacuum_max_workers = 8

Compressão WAL


Se você tiver CPU de sobra, poderá trocar a CPU pela largura de banda do disco compactando as páginas gravadas nos arquivos WAL. Isso reduz a quantidade de dados que precisam ser gravados no disco, à custa de mais ciclos de CPU para compactar os dados. Também reduz o tamanho dos dados que precisam ser enviados pela rede para replicação de streaming.

Praticamente, os benefícios da compactação WAL valem a despesa muito razoável. Para ativá-lo, use:
# compresses full page images written to WAL
wal_compression = on

Memória

O que é dimensionado automaticamente


O sistema operacional gerencia e usa automaticamente a memória que não é utilizada por qualquer aplicativo para armazenar em cache os dados lidos e gravados no disco recentemente. Isso acelera bastante os aplicativos com uso intensivo de disco e, certamente, o PostgreSQL.

No Linux, o host mais popular do Postgres, o tamanho do cache de disco do SO não pode ser definido pelo usuário. Seu gerenciamento é interno ao Linux. Sob pressão de memória, ele fornecerá memória cache de disco para aplicativos.

O que precisa ser ajustado

Planejador de consultas


O planejador de consultas deve incluir a quantidade de cache de disco fornecida pelo sistema operacional como um fator em suas estimativas. Se você conseguiu aumentar significativamente o cache de disco do SO (aumentando a memória disponível), aumentar essa configuração pode ajudar a melhorar as estimativas do planejador:
# the planner's assumption about the effective size
# of the disk cache that is available to a single query.
effective_cache_size = 64GB

Memória Compartilhada


O PostgreSQL usa um conjunto de buffers que é compartilhado entre todos os workers e processos de backend. Eles são chamados de buffers compartilhados , e a quantidade de memória alocada para buffers compartilhados é definida usando a definição de configuração:
shared_buffers = 32GB

Buffers temporários


Quando as tabelas temporárias são acessadas por uma consulta, os buffers são alocados para armazenar em cache o conteúdo que é lido. O tamanho desse buffer é definido usando a configuração:
# the maximum number of temporary buffers used
# by each database session
temp_buffers = 100MB

Se você tiver memória de sobra e consultas que usam muito tabelas temporárias, aumentar esse valor pode acelerar essas consultas.

Memória de trabalho


A memória de trabalho é alocada localmente e privadamente pelos back-ends. Ele é usado para realizar ordenações e junções sem ter que criar tabelas temporárias. Aumentar isso do padrão de 4 MB pode permitir que as consultas sejam concluídas mais rapidamente durante a criação de tabelas temporárias:
# the amount of memory to be used by internal sort
# operations and hash tables before writing to temporary disk files
work_mem = 16MB

Operações de manutenção


A memória usada pelo VACUUM, criação de índice e outros comandos de manutenção são controlados pela configuração maintenance_work_mem . Aumentar essa quantidade pode acelerar essas operações, especialmente em índices ou tabelas que precisam ser recriadas.

A memória usada pelos trabalhadores do autovacuum pode ser retirada da memória de trabalho de manutenção (definindo autovacuum_work_mem = -1 ) ou configurado de forma independente.
# the maximum amount of memory to be used by
# maintenance operations
maintenance_work_mem = 128MB

# maximum amount of memory to be used by each
# autovacuum worker process
autovacuum_work_mem = -1

Disco

O que é dimensionado automaticamente


Os discos podem ser maiores, mais rápidos ou mais simultâneos. O tamanho do disco é a única coisa sobre a qual o PostgreSQL não precisa ser instruído. Por padrão, o PostgreSQL não se limitará a usar qualquer espaço em disco disponível. Isso geralmente é bom.

Você pode colocar um limite no tamanho total dos arquivos temporários criados para fornecer alguma proteção contra consultas que tentam classificar bilhões de linhas e similares:
# the maximum amount of disk space that a process
# can use for temporary files
temp_file_limit = 500GB

O que precisa ser ajustado

Simultaneidade


Discos RAID-ed e sistemas de arquivos como ZFS podem ser configurados para suportar mais simultaneidade. Ou seja, você pode ter algumas leituras/gravações de disco sendo atendidas simultaneamente por esses sistemas de arquivos devido à maneira como armazenam ou manipulam os dados internamente.

Você pode deixar o Postgres emitir várias E/S de disco simultâneas, usando esta configuração:
# the number of concurrent disk I/O operations that
# PostgreSQL expects can be executed simultaneously
effective_io_concurrency = 4

No entanto, isso é usado atualmente apenas por varreduras de heap de bitmap.

Custo de página aleatória


O planejador de consultas do Postgres assume que as leituras sequenciais são mais rápidas que as leituras aleatórias. Exatamente quanto mais rápido é um valor que você pode ajustar. Por padrão, ele assume que leituras aleatórias são 4 vezes mais caras.

Dependendo da configuração do disco, carga de trabalho e benchmarking, se você tiver certeza de que as leituras aleatórias são, digamos, apenas duas vezes mais caras que as leituras sequenciais, você pode dizer isso ao Postgres:
# the planner's estimate of the cost of a disk page
# fetch that is part of a series of sequential fetches
seq_page_cost = 1

# the planner's estimate of the cost of a
# non-sequentially-fetched disk page
random_page_cost = 2

Espaços de tabela


Para tirar vantagem de vários discos que não são montados como um grande sistema de arquivos único, você pode usar tablespaces. Com tablespaces, você pode colocar tabelas ou indexar diferentes sistemas de arquivos. Isso pode melhorar a simultaneidade e fornece uma maneira fácil de lidar com o crescimento da tabela.
CREATE TABLESPACE disk2 LOCATION '/mnt/disk2/postgres';

Leia mais sobre tablespaces aqui.

Rede


A rede geralmente é o recurso menos usado em um servidor PostgreSQL e raramente está saturado. Se você precisar dimensionar, é fácil adicionar mais interfaces de rede, cada uma com seu próprio IP, e fazer com que o PostreSQL escute todas elas:
listen_addresses = '10.1.0.10,10.1.0.11'

Os clientes terão que ter balanceamento de carga em todos os IPs que o Postgres escuta.

Outro


Existem algumas outras configurações que podem ser ajustadas, a maioria das quais consome mais CPU e memória.

Operações em partições


O Postgres 10 introduziu o particionamento de tabelas, que foi aprimorado no Postgres 11. Algumas otimizações de consulta em partições não são ativadas por padrão, pois podem resultar em maior consumo de CPU e memória. Esses são:
# allow a join between partitioned tables to be
# performed by joining the matching partitions
enable_partitionwise_join = on

# allow grouping or aggregation on a partitioned
# tables performed separately for each partition
enable_partitionwise_aggregate = on