Cluster pgpool

From Tuxunix
Jump to: navigation, search

Matrice de Comparaison

Vous pouvez retrouver la source sur le site suivant : [1]

Program License Maturity Replication Method Sync Connection Pooling Load Balancing Query Partitioning
PGCluster BSD See version details on site Master-Master Synchronous No Yes No
pgpool-I BSD Stable Statement-Based Middleware Synchronous Yes Yes No
pgpool-II BSD Recent release Statement-Based Middleware Synchronous Yes Yes Yes
slony-I BSD Stable Master-Slave Asynchronous No No No
Bucardo BSD Stable Master-Master, Master-Slave Asynchronous No No No
Londiste BSD Stable Master-Slave Asynchronous No No No
Mammoth BSD Stable Master-Slave Asynchronous No No No
rubyrep MIT Recent Release Master-Master, Master-Slave Asynchronous No No No

PGpool II

pgpool-II est un middleware qui se place entre les serveurs PostgreSQL et les clients de ces derniers. Ce projet à l'avantage d'être suivi et régulierement mise à jour.

Voici ses différentes fonctionalités:

  • Pooling de connexions

pgpool-II maintient les connexions établies aux serveurs PostgreSQL et les réutilise dès qu'une nouvelle connexion partageant les mêmes propriétés (c'est-à-dire même utilisateur, même base de données et même version de protocole) arrive. Il réduit ainsi le coût de la connexion et améliore les performances générales du système.

  • Réplication

pgpool-II peut gérer plusieurs serveurs PostgreSQL. En activant le mode réplication, il devient possible de créer une sauvegarde continue sur d'autres instances PostgreSQL, afin que le service puisse continuer sans interruption si l'une de ces instances était défaillante.

  • Répartition de charge

Si une base de données est répliquée, exécuter une requête en SELECT sur n'importe lequel de ceux-ci retournera le même résultat. pgpool-II profite ainsi avantageusement de la réplication pour réduire la charge sur chacun des serveurs PostgreSQL. Il parvient à cela en distribuant les requêtes SELECT entre tous les serveurs disponibles, ce qui qui améliore les performances générales du système. Dans un scénario idéal, les performances en lecture s'améliorent proportionnellement au nombre de serveurs PostgreSQL. La répartition de charge avec pgpool-II fonctionne au mieux dans un scénario où il y a beaucoup d'utilisateurs qui exécutent beaucoup de requêtes en lecture au même moment.

  • Limitation des connexions excédentaires

Dans PostgreSQL, il y a une limite maximum du nombre de connexions concurrentes au serveur (NDT: paramètre max_connections), et toutes les nouvelles connexions sont rejettées une fois que ce nombre est atteint. Augmenter ce nombre est possible mais accroît la consommation de ressources par le serveur et a un impact négatif sur les performances générales du système. Bien que pgpool-II ait aussi une limite sur le nombre de connexions maximum, il va mettre toute connexion excédentaire dans une file d'attente au lieu de retourner immédiatement une erreur.

  • Requêtes parallèlisées

En utilisant la fonctionalité des requêtes parallèlisées, les données peuvent être réparties sur plusieurs serveurs afin que les requêtes puissent être exécutées sur tous les serveurs à la fois, en réduisant ainsi le temps d'exécution global de la requête. Cette fonctionalité donne les meilleurs résultats lorsqu'on cherche à extraire un très grand ensemble de données.


Installation PGPool-II (RH 6)

Pré-requis

installer postgresql-libs.x86_64

  • Télécharger la dernier version de PGpool2 : [2]

Ou

Installer via le repository rpmforge : "pgpool-2.0.1-1.el6.rf.x86_64.rpm"

Installation

  • package rpm.
#> yum install pgpool.x86_64
  • Compilation (avantage vous obtiendrez les dernieres fonctionnalités de PGPOOL-II

Attention sur une plateforme RH6 en 64bits, vous devrez installer "postgresql-devel.i686"

#> ./configure && make && make install

Configuration

  • Fichier de référence : "/usr/local/etc/pgpool.conf"
PCP

Interface d'administration avec PGpool. Creer le md5 pour PCP de l'utilisateur "postgres", en saisissant le mdp.

#> ./pg_md5 postgres
e8a48645651238578c69d0506508fb27fc5

Puis Ajouter dans le fichier de conf

#> echo 'postgres:e8a48645651238578c69d0506508fb27fc5' >> /usr/local/etc/pcp.conf

Ensuite vous pourrez avoir accés à un certain nombre d'information comme le status des pools via la commande "SHOW pool_status", etc...

Mode Réplication

  • Activer le mode replication via le fichier de configuration pgpool :
replication_mode = true
Fichier Configuration PGpool II en mode réplication
# ----------------------------
# pgPool-II configuration file
# ----------------------------
#
# This file consists of lines of the form:
#
#   name = value
#
# Whitespace may be used.  Comments are introduced with "#" anywhere on a line.
# The complete list of parameter names and allowed values can be found in the
# pgPool-II documentation.
#
# This file is read on server startup and when the server receives a SIGHUP
# signal.  If you edit the file on a running system, you have to SIGHUP the
# server for the changes to take effect, or use "pgpool reload".  Some
# parameters, which are marked below, require a server shutdown and restart to
# take effect.
#

#------------------------------------------------------------------------------
# CONNECTIONS
#------------------------------------------------------------------------------

# - pgpool Connection Settings -

listen_addresses = '*'
                                  # Host name or IP address to listen on:
                                  # '*' for all,  for no TCP/IP connections
                                  # (change requires restart)
port = 9999
                                  # Port number
                                  # (change requires restart)
socket_dir = '/tmp'
                                  # Unix domain socket path
                                  # The Debian package defaults to
                                  # /var/run/postgresql
                                  # (change requires restart)


# - pgpool Communication Manager Connection Settings -

pcp_port = 9898
                                  # Port number for pcp
                                  # (change requires restart)
pcp_socket_dir = '/tmp'
                                  # Unix domain socket path for pcp
                                  # The Debian package defaults to
                                  # /var/run/postgresql
                                  # (change requires restart)
# - Backend Connection Settings -

backend_hostname0 = 'Server1'
                                  # Host name or IP address to connect to for backend 0
backend_port0 = 5432
                                  # Port number for backend 0
backend_weight0 = 1
                                  # Weight for backend 0 (only in load balancing mode)
backend_data_directory0 = '/var/lib/pgsql/data'
                                  # Data directory for backend 0
backend_flag0 = 'ALLOW_TO_FAILOVER'
                                  # Controls various backend behavior
                                  # ALLOW_TO_FAILOVER or DISALLOW_TO_FAILOVER
backend_hostname1 = 'Server2'
backend_port1 = 5432
backend_weight1 = 1
backend_data_directory1 = '/var/lib/pgsql/data'
backend_flag1 = 'ALLOW_TO_FAILOVER'

# - Authentication -

enable_pool_hba = off
                                  # Use pool_hba.conf for client authentication
authentication_timeout = 60
                                  # Delay in seconds to complete client authentication
                                  # 0 means no timeout.

# - SSL Connections -

ssl = off
                                  # Enable SSL support
                                  # (change requires restart)
#ssl_key = './server.key'
                                  # Path to the SSL private key file
                                  # (change requires restart)
#ssl_cert = './server.cert'
                                  # Path to the SSL public certificate file
                                  # (change requires restart)
#ssl_ca_cert = 
                                  # Path to a single PEM format file
                                  # containing CA root certificate(s)
                                  # (change requires restart)
#ssl_ca_cert_dir = 
                                  # Directory containing CA root certificate(s)
                                  # (change requires restart)
#------------------------------------------------------------------------------
# - Pool size -

num_init_children = 5
                                  # Number of pools
                                  # (change requires restart)
max_pool = 4
                                  # Number of connections per pool
                                  # (change requires restart)

# - Life time -

child_life_time = 300
                                  # Pool exits after being idle for this many seconds
child_max_connections = 0
                                  # Pool exits after receiving that many connections
                                  # 0 means no exit
connection_life_time = 0
                                  # Connection to backend closes after being idle for this many seconds
                                  # 0 means no close
client_idle_limit = 0
                                  # Client is disconnected after being idle for that many seconds
                                  # (even inside an explicit transactions!)
                                  # 0 means no disconnection


#------------------------------------------------------------------------------
# LOGS
#------------------------------------------------------------------------------

# - Where to log -

log_destination = 'stderr'
                                  # Where to log
                                  # Valid values are combinations of stderr,
                                  # and syslog. Default to stderr.

# - What to log -

print_timestamp = on
                                  # Print timestamp on each line
                                  # (change requires restart)

log_connections = on
                                  # Log connections
log_hostname = on
                                  # Hostname will be shown in ps status
                                  # and in logs if connections are logged
log_statement = on
                                   # Log all statements
log_per_node_statement = on
                                  # Log all statements
                                  # with node and backend informations
log_standby_delay = 'none'
                                  # Log standby delay
                                  # Valid values are combinations of always,
                                  # if_over_threshold, none

# - Syslog specific -

syslog_facility = 'LOCAL0'
                                  # Syslog local facility. Default to LOCAL0
syslog_ident = 'pgpool'
                                  # Syslog program identification string
                                  # Default to 'pgpool'

# - Debug -

debug_level = 1
                                  # Debug message verbosity level
                                  # 0 means no message, 1 or more mean verbose


#------------------------------------------------------------------------------
# FILE LOCATIONS
#------------------------------------------------------------------------------

pid_file_name = '/var/run/pgpool/pgpool.pid'
                                  # PID file name
                                  # (change requires restart)
logdir = '/tmp'
                                  # Directory of pgPool status file
                                  # (change requires restart)


#------------------------------------------------------------------------------
# CONNECTION POOLING
#------------------------------------------------------------------------------

connection_cache = on
                                  # Activate connection pools
                                  # (change requires restart)

                                  # Semicolon separated list of queries
                                  # to be issued at the end of a session
                                  # The default is for 8.3 and later
reset_query_list = 'ABORT; DISCARD ALL'
                                  # The following one is for 8.2 and before
#reset_query_list = 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT'
#------------------------------------------------------------------------------
# REPLICATION MODE
#------------------------------------------------------------------------------

replication_mode = on
                                  # Activate replication mode
                                  # (change requires restart)
replicate_select = off
                                  # Replicate SELECT statements
                                  # when in replication or parallel mode
                                  # replicate_select is higher priority than
                                  # load_balance_mode.

insert_lock = on
                                  # Automatically locks a dummy row or a table
                                  # with INSERT statements to keep SERIAL data
                                  # consistency
                                  # Without SERIAL, no lock will be issued
lobj_lock_table = 
                                  # When rewriting lo_creat command in
                                  # replication mode, specify table name to
                                  # lock

# - Degenerate handling -

replication_stop_on_mismatch = off
                                  # On disagreement with the packet kind
                                  # sent from backend, degenerate the node
                                  # which is most likely "minority"
                                  # If off, just force to exit this session

failover_if_affected_tuples_mismatch = off
                                  # On disagreement with the number of affected
                                  # tuples in UPDATE/DELETE queries, then
                                  # degenerate the node which is most likely
                                  # "minority".
                                  # If off, just abort the transaction to
                                  # keep the consistency


#------------------------------------------------------------------------------
# LOAD BALANCING MODE
#------------------------------------------------------------------------------

load_balance_mode = on
                                  # Activate load balancing mode
                                  # (change requires restart)
ignore_leading_white_space = on
                                   # Ignore leading white spaces of each query
white_function_list = 
                                  # Comma separated list of function names
                                  # that don't write to database
                                  # Regexp are accepted
black_function_list = 'nextval,setval'
                                  # Comma separated list of function names
                                  # that write to database
                                  # Regexp are accepted


#------------------------------------------------------------------------------
# MASTER/SLAVE MODE
#------------------------------------------------------------------------------

master_slave_mode = off
                                  # Activate master/slave mode
                                  # (change requires restart)
master_slave_sub_mode = 'slony'
                                  # Master/slave sub mode
                                  # Valid values are combinations slony or
                                  # stream. Default is slony.
                                  # (change requires restart)

# - Streaming -

sr_check_period = 0
                                  # Streaming replication check period
                                  # Disabled (0) by default
sr_check_user = 'nobody'
                                  # Streaming replication check user
                                  # This is neccessary even if you disable streaming
                                  # replication delay check by sr_check_period = 0
sr_check_password = 
                                  # Password for streaming replication check user
delay_threshold = 0
                                  # Threshold before not dispatching query to standby node
                                  # Unit is in bytes
                                  # Disabled (0) by default

# - Special commands -

follow_master_command = 
                                  # Executes this command after master failover
                                  # Special values:
                                  #   %d = node id
                                  #   %h = host name
                                  #   %p = port number
                                  #   %D = database cluster path
                                  #   %m = new master node id
                                  #   %H = hostname of the new master node
                                  #   %M = old master node id
                                  #   %P = old primary node id
                                  #   %% = '%' character


#------------------------------------------------------------------------------
# PARALLEL MODE AND QUERY CACHE
#------------------------------------------------------------------------------

parallel_mode = off
                                  # Activates parallel query mode
                                  # (change requires restart)
enable_query_cache = off
                                  # Activates query cache
                                  # (change requires restart)

pgpool2_hostname = 
                                  # Set pgpool2 hostname
                                  # (change requires restart)

# - System DB info -

system_db_hostname  = 'localhost'
                                  # (change requires restart)
system_db_port = 5432
                                  # (change requires restart)
system_db_dbname = 'pgpool'
                                  # (change requires restart)
system_db_schema = 'pgpool_catalog'
                                  # (change requires restart)
system_db_user = 'pgpool'
                                  # (change requires restart)
system_db_password = 
                                  # (change requires restart)


#------------------------------------------------------------------------------
# HEALTH CHECK
#------------------------------------------------------------------------------

health_check_period = 0
                                  # Health check period
                                  # Disabled (0) by default
health_check_timeout = 20
                                  # Health check timeout
                                  # 0 means no timeout
health_check_user = 'nobody'
                                  # Health check user
health_check_password = 
                                   # This parameter is not yet implemented.
                                  # Password for health check user


#------------------------------------------------------------------------------
# FAILOVER AND FAILBACK
#------------------------------------------------------------------------------

failover_command = 'echo  -e " Pgpool II failover executed successfully at $(hostname):$(hostname -i) for backend node %d down on the $(date).\n\n Details of Backend Node %d :-\n Host = %h \n Port = %p \n Cluster Path =  %D \n\nFor Pgpool II at $(hostname):$(hostname -i) current master node is Backend_node%m (Old master node was Backend_node%M)">/var/log/pgpool_failover.log;'
                                  # Executes this command at failover
                                  # Special values:
                                  #   %d = node id
                                  #   %h = host name
                                  #   %p = port number
                                  #   %D = database cluster path
                                  #   %m = new master node id
                                  #   %H = hostname of the new master node
                                  #   %M = old master node id
                                  #   %P = old primary node id
                                  #   %% = '%' character
failback_command = 'echo  -e " Pgpool II failback done successfully at $(hostname):$(hostname -i) for backend node %d down on the $(date).\n\n Details of Backend Node %d :-\n Host = %h \n Port = %p \n Cluster Path =  %D \n\nFor Pgpool II at $(hostname):$(hostname -i) current master node is Backend_node%m (Old master node was Backend_node%M)">/var/log/pgpool_failback.log'
                                  # Executes this command at failback.
                                  # Special values:
                                  #   %d = node id
                                  #   %h = host name
                                  #   %p = port number
                                  #   %D = database cluster path
                                  #   %m = new master node id
                                  #   %H = hostname of the new master node
                                  #   %M = old master node id
                                  #   %P = old primary node id
                                  #   %% = '%' character

fail_over_on_backend_error = on
                                  # Initiates failover when writing to the
                                  # backend communication socket fails
                                  # This is the same behaviour of pgpool-II
                                  # 2.2.x and previous releases
                                  # If set to off, pgpool will report an
                                  # error and disconnect the session.

#------------------------------------------------------------------------------
# ONLINE RECOVERY
#------------------------------------------------------------------------------
recovery_user = 'nobody'
                                  # Online recovery user
recovery_password = 
                                  # Online recovery password
recovery_1st_stage_command = 
                                  # Executes a command in first stage
recovery_2nd_stage_command = 
                                  # Executes a command in second stage
recovery_timeout = 90
                                  # Timeout in seconds to wait for the
                                  # recovering node's postmaster to start up
                                  # 0 means no wait
client_idle_limit_in_recovery = 0
                                  # Client is disconnected after being idle
                                  # for that many seconds in the second stage
                                  # of online recovery
                                  # 0 means no disconnection
                                  # -1 means immediate disconnection 

#------------------------------------------------------------------------------
# OTHERS
#------------------------------------------------------------------------------

relcache_expire = 0
                                  # Life time of relation cache in seconds.
                                  # 0 means no cache expiration(the default).
                                  # The relation cache is used for cache the
                                  # query result against PostgreSQL system
                                  # catalog to obtain various information
                                  # including table structures or if it's a
                                  # temporary table or not. The cache is
                                  # maintained in a pgpool child local memory
                                  # and being kept as long as it survives.
                                  # If someone modify the table by using
                                  # ALTER TABLE or some such, the relcache is
                                  # not consistent anymore.
                                  # For this purpose, cache_expiration
                                  # controls the life time of the cache.
Type d'erreur rencontré
ERROR: pid 6115: read_message_length: length does not match between backends master(26) secondary(25)
  • Solution :

Vérifier si vous être sur la même version de postgres entre le master et le slave.

Limite du mode réplication
  • pgPool-II envoie les requêtes sur les deux serveurs. Du coup, si cette requête contient un appel à une fonction dont le résultat n’est pas reproductible dans les mêmes conditions, il est possible de voir des différences. Les fonctions now() et random() sont des cas typiques pouvant révéler ce problème.
  • La réplication ne fonctionne que si vous passez par le pooler !!

Mode Répartition de charge

  • Pré-requis pour la répartition de charge

Pour qu'une requête soit répartie, les pré-requis suivants doivent être respectés :

- Version 7.4 ou ultérieure de PostgreSQL

- La requête ne doit pas être déclarée explicitement (c'est-à-dire qu'on ne doit pas être dans un bloc BEGIN ~ END)

- Il ne s'agit pas d'un SELECT nextval ou d'un SELECT setval

- Il ne s'agit pas d'un SELECT INTO

- Il ne s'agit pas d'un SELECT FOR UPDATE ou FOR SHARE

- La requête commence par un SELECT ou COPY TO STDOUT, EXPLAIN, EXPLAIN ANALYZE SELECT... le paramètre ignore_leading_white_space = true permettra d'ignorer tous les éventuels espaces présents avant la requête.


Configuration Répartition de charge

Ce mode permet de gérer les différents noeuds de la base de données, il ne fonctionne que si la replication est active.

  • Activer le mode répartition de charge via le fichier de configuration pgpool :
load_balance_mode = true
  • Possibilité de définir des poids pour chaque noeud via le paramétre suivant :

Il suffit pour cela d'ajouter le numéro du serveur à la fin du nom du paramètre (par exemple backend_weight0)

backend_weight1 = 0.2 #repartition à hauteur de 20% sur le backend 1
Configuration Réplication des selects
  • Ce mode permet de distribuées les requêtes SELECT sur les différents noeuds de la base de données, il ne fonctionne que si la replication est active.
replicate_select = off

Recovery

Dans le cas ou un noeud n'est plus accessible PGpool sort le noeud défaillant du pool, vous obtiendrez ainsi ce genre de message :

log: pid 10321: SimpleForwardToFrontend: length does not match between backends master(223) secondary(119)
ERROR: pid 10321: pool_read: EOF encountered
log: pid 10321: notice_backend_error: fail over request from pid 10321
DEBUG: pid 9933: failover_handler called
log: pid 9933: starting degenration. shutdown secondary host X.X.X.X(5432)
DEBUG: pid 16092: I am 16092
DEBUG: pid 16092: I am 16092 accept fd 6
DEBUG: pid 16094: I am 16094
DEBUG: pid 16092: Protocol Major: 3 Minor: 0 database: test user: postgres
log: pid 9933: degenration done. shutdown secondary host X.X.X.X(5432)


Online Recovery

  • Comment réintégré le noeud défaillant ?
Configuration du « online recovery »
Pré-requis

Les serveurs doivent pouvoir communiquer entre eux via le partage de clé ssh

#> yum install openssh-clients  glibc-devel.i686 libgcc.i686


  • Installation des fonctions en langage C

Les fonctions en langage C suivantes doivent être installées dans la base template1 de tous les serveurs PostgreSQL pour que le « online recovery » fonctionne. Leur code source est dans le répertoire suivant de l'archive de pgpool-II :

 pgpool-II-x.x.x/sql/pgpool-recovery/

Il convient de changer le nom du répertoire ci-dessus pour l'ajuster à votre version précise de pgpool-II. On se place dans ce dernier et on lance la commande « make install » :

 % cd pgpool-II-x.x.x/sql/pgpool-recovery/
 % make install

À présent, il faut installer les fonctions SQL correspondantes :

 % cd pgpool-II-x.x.x/sql/pgpool-recovery/
 % psql -f pgpool-recovery.sql template1


  • Copie des clés SSH (a faire sur les 2 serveurs) :
[postgres@Server2 lib]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/postgres/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /postgres/.ssh/id_rsa.
Your public key has been saved in /postgres/.ssh/id_rsa.pub.
The key fingerprint is:
63:5d:5f:96:aa:56:d6:2f:af:15:9d:92:06:b4:db:b4 postgres@EcritelTest2
The key's randomart image is:
+--[ RSA 2048]----+
|           .     |
|          . .   .|
|           o.. .o|
|         . .=.=oo|
|        S .. E.+.|
|       . .  = . o|
|           o  . o|
|          .    + |
|              ...|
+-----------------+
[postgres@Server2 lib]# ssh-copy-id
Usage: /usr/bin/ssh-copy-id [-i [identity_file]] [user@]machine
[root@Server2 lib]# ssh-copy-id postgres@EcritelTest1
 The authenticity of host 'Server1 (X.X.X.X)' can't be established.
RSA key fingerprint is 39:c7:71:9b:6c:b0:9d:2e:7c:9b:d2:d1:3d:fb:e0:02.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'Server1,X.X.X.X' (RSA) to the list of known hosts.
root@Server1's password:
Now try logging into the machine, with "ssh 'postgres@Server1'", and check in:

 .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

[postgres@Server2 lib]# ssh Server1
Last login: Mon Jun  4 19:09:24 2012 from test.xxxx.net
[postgres@Server1 ~]# exit
logout
Connection to Server1 closed.
Configuration PGpool

Commande PGpool

  • pool_status, donne la configuration
  • pool_nodes, donne les informations sur les noeuds
  • pool_processes, donne les informations sur les processus
  • pool_pools, donne les informations sur les pools
  • pool_version, donne la version

ex :

# show pool_status;
             item              |              value              |                           description                            
-------------------------------+---------------------------------+------------------------------------------------------------------
listen_addresses              | 127.0.0.1                       | host name(s) or IP address(es) to listen to
port                          | 9999                            | pgpool accepting port number
socket_dir                    | /tmp                            | pgpool socket directory
num_init_children             | 5                               | # of children initially pre-forked
child_life_time               | 300                             | if idle for this seconds, child exits
# show pool_processes;
   pool_pid |     start_time      | database | username  |     create_time     | pool_counter 
----------+---------------------+----------+-----------+---------------------+--------------
8465     | 2010-08-14 08:35:40 |          |           |                     | 
8466     | 2010-08-14 08:35:40 | test     | pierre    | 2010-08-14 08:35:43 | 1
8467     | 2010-08-14 08:35:40 |          |           |                     | 
8468     | 2010-08-14 08:35:40 |          |           |                     | 
8469     | 2010-08-14 08:35:40 |          |           |                     | 
(5 lines)


Monitoring

Documentation

Voici un lien vers une documentation en francais sur le middleware PGpool => [3]