Performance Considerations
performance
of the server
There are number of configuration parameters that affect the
performance of
Pgpool-II. In this chapter we present
how to tune them.
Resource Requirement
Pgpool-II does not consume too much
resource. However there are minimum requirements for
resource. In this section we are going to explain one by one.
Memory Requirement
There are two types of memory usage
in Pgpool-II: shared memory and
process private memory. The former is allocated at the startup
of Pgpool-II main server process
and will not be freed until
whole Pgpool-II servers shut down.
The latter is allocated within
each Pgpool-II child process and
will be freed at the end of the process.
Shared Memory Requirement
Here is a formula to calculate the shared memory requirement.
Shared memory requirement (in mega bytes) = 10 + * * 0.02
For example if you have num_init_children = 32 (the default) and max_pool = 4 (the
default), then you will need 10 + 32 * 4 * 0.02 = 12.6 MB.
If you plan to use in memory query cache
(see for more
details) in the shared memory, you will need more RAM for
it. See
and
for required RAM
size.
Note that, however, in Pgpool-II 4.1
or after, even if the in memory query cache is not enabled, it
consumes additional 128MB of shared memory, if is enabled (it is enabled
by default).
Process Memory Requirement
Here is a formula to calculate the process memory requirement.
Process memory requirement in total (in mega bytes) = * 0.16
For example if you have num_init_children = 32
(the default), you will need 5.2MB. Please note that this is
minimum memory requirement
upon Pgpool-II child process starting
up. Once the process runs, it will consume more memory depending
on the message packet sizes and other factors. It is recommended
to measure the amount of memory actually used by the process
before starting production use.
Disk Requirement
Pgpool-II does not consume much
disk space. Also it does not require high speed disk because
disk I/O traffic caused
by Pgpool-II is small. However,
if you plan to emit much logs, of course you need disk space
for them.
Managing Client Connections
As the number of client connections accepted is growing, the
number of Pgpool-II child process
which can accept new connections from client is decreasing and
finally reaches to 0. In this situation new clients need to wait
until a child process becomes free. Under heavy load, it could
be possible that the queue length of waiting clients is getting
longer and longer and finally hits the system's limit (you might
see "535 times the listen queue of a socket overflowed"
error"). In this case you need to increase the queue
limit. There are several ways to deal with this problem.
Controlling num_init_children
The obvious way to deal with the problem is increasing the
number of child process. This can be done by
tweaking . However
increasing child process requires more CPU and memory
resource. Also you have to be very careful about
max_connections parameter
of PostgreSQL because once the
number of child process is greater than
max_connections, PostgreSQL refuses
to accept new connections, and failover will be triggered.
Another drawback of increasing num_init_children is, so called
"thundering herd problem". When new connection request comes
in, the kernel wake up any sleeping child process to issue
accept() system call. This triggers fight of process to get
the socket and could give heavy load to the system. To
mitigate the problem, you could set serialize_accept to on so
that there's only one process to grab the accepting socket.
However notice that the performance may be dropped when the number
of concurrent clients is small.
In Pgpool-II 4.4 or later, it is
possible to use for
more efficient management. By
setting process-management-mode
to dynamic, when the number of concurrent
clients is small, the number of child process
of Pgpool-II can be decreased thus we
can save the resource consumption. On the other hand when the
number of concurrent clients gets larger, the number of child
process increases so that it can respond to the more demand of
connections. However, notice that the time for connection
establishment could be increasing because new process need to be
started to have more child process.
See also for
understanding process-management-mode.
Controlling listen_backlog_multiplier
Another solution would be increasing the connection request
queue. This could be done by
increasing .
When to use reserved_connections
However, none of above solutions guarantees that the
connection accepting the queue would not be filled up. If a
client connection request arrives quicker than the rate of
processing queries, the queue will be filled in someday. For
example, if there are some heavy queries that take long time,
it could easily trigger the problem.
The solution is
setting so that
overflowed connection requests are rejected
as PostgreSQL already does. This
gives visible errors to applications ("Sorry max_connections
already") and force them retrying. So the solution should only
be used when you cannot foresee the upper limit of system
load.
Read Query Load Balancing
If there are multiple PostgreSQL
nodes and Pgpool-II operates in
streaming replication mode, logical replication mode, slony mode
or replication mode (for those running mode
see for more details), it is
possible to distribute read queries among those database nodes
to get more throughput since each database nodes processes
smaller number of queries. To enable the feature you need to
turn on .
At this point vast majority of systems use streaming replication
mode, so from now on we focus on the mode.
Session Level Load Balancing vs. Statement Level Load Balancing
By default load balance mode is "session level" which means
the node read queries are sent is determined when a client
connects to Pgpool-II. For example,
if we have node 0 and node 1, one of the node is selected
randomly each time new session is created. In the long term,
the possibility which node is chosen will be getting closer to
the ratio specified by 0
and
1. If those two values are
equal, the chance each node is chosen will be even.
On the other hand, if
is set to
on, the load balance node is determined at the time each query
starts. This is useful in case that application has its own
connection pooling which keeps on connecting
to Pgpool-II and the load balance
node will not be changed once the application starts. Another
use case is a batch application. It issues tremendous number
of queries but there's only 1 session. With statement level
load balancing it can utilize multiple servers.
Creating Specific Purpose Database Node
In OLAP environment sometimes it is desirable to have a large
read-only database for specific purpose. By creating such a
database is possible by creating a replica database using
streaming replication. In this case it is possible to redirect
read queries to the database in two ways: specifying database
names(s) or specifying application name(s). For former,
use . For
latter use .
In Memory Query Caching
Pgpool-II allows to cache read query
results for later use. This will bring huge benefit for a type
of applications which issue same read queries many times. If
there are two queries and the query strings (parameter for
prepared statements if any) are identical, two queries are
regarded as "same". For the first time the query is
sent, Pgpool-II saves the query
result, and use it for the second query without asking anything
to PostgreSQL. This technique is
explained in .
When not to Use in Memory Query Caching
When a table is modified, query results against the table
could be changed. To avoid
inconsistency, Pgpool-II discards
query cache data when corresponding table is modified. So
frequently updated database will not be suitable to use in
memory query caching. You can check if your database is
suitable to use query caching or not, you could
use . If query cache hit
ration is lower than 70%, probably you want to avoid using the
query cache.
Relation Cache
Except in raw mode (see )
or is set to off,
sometimes Pgpool-II needs to
ask PostgreSQL to get meta
information, such as whether a table is a temporary one or
not. To get those
information, Pgpool-II sends queries
primary PostgreSQL which could be up
to as many as 10 queries (in 4.1 or after, the number of queries
has been decreased, it is not zero, however). To reduce the
overhead, Pgpool-II maintains
"relation cache". Next time same table is included in a
query, Pgpool-II extracts the
information from the cache.
There are some parameters to configure the relation
cache. See , , ,
for more details.
Shared Relation Cache
The relation cache basically lives in process private memory,
which is bound to a process. So even if a relation cache is
created to for a table, in different process the relation
cache might not be created yet. After all, until a relation
cache entry is created in all process, queries continue to
sent to PostgreSQL.
Pgpool-II 4.1 overcomes the issue
by creating relation cache in shared memory. If a session
creates a relation cache entry in the shared memory, other
sessions will get the cache result by looking at the shared
relation
cache. See
configuration parameter section for more details. This feature
is pretty effective and we recommend this feature be enabled.
Other Performance Considerations
This section introduces some other performance considerations.
Thundering Herd Problem
If is large, it is
possible that many Pgpool-II process
are woke up and heavy context switching happens. This leads to
high system load and hurt the overall system performance. This
problem is called "the thundering herd
problem". Enabling could
solve the problem. Please note that for
smaller ,
might make the system performance worse. Please take a look at
the guidance in section.
Disaster recovery settings
To create a disaster recovery setting, it is possible to deploy a
Pgpool-II plus
PostgreSQL primary server, and another
Pgpool-II plus standby
PostgreSQL server in a geographically
distant place. Clients close to the standby server send read only
queries to the Pgpool-II, being close
to the standby server. However, since standby
Pgpool-II sends internal queries to
system catalog of primary PostgreSQL
server, query performance may be getting worse. To avoid the
problem, it is possible to use so that such queries are sent
to the standby. See for
more details.