Info16.fr

Le blog de B@rtounet

#Gnu/Linux

Mise en place d'un forum en cluster ( equilibrage de charge, LVM2 + DRBD + OCFS2)

27 juillet 2011 Rédigé par bartounet

Il y avait un moment que j'avais pas écris un petit billet. J'en profiste pour faire un petit mémo sur la mise en place d'un forum en cluster sur 2 serveurs dédiés type Dédibox. je dresse rapidement le tableau. Etant beta-testeur Dedibox, j'ai la chance de disposer de pas mal de serveurs dédiés de tests. Je me suis donc amusé à installé un Forum PunBB sur un cluster Actif/Actif répliqué par DRBD, et permettant les écritures concurentes grace au systeme de fichier cluster OCFS2. Un schéma vaut mieux qu'un grand discours.

Comme vous pouvez le constater, je suis parti sur le principe que pour redonder un forum, tel que punbb il faut redonder /var/www et /var/lib/mysql. Il y a pas mal de moyen pour redonder un block device, j'ai otper pour DRBD DRBD (Distributed Replicated Block Device) est un outil qui permet de synchroniser (par réplication) des périphériques de stockage (disque dur, partition, volume logique, etc.) entre deux ordinateurs via le réseau. Cette synchronisation se fait : en temps réel : elle se fait à la volée, pendant que les données sont modifiées de manière transparente : les applications, qui enregistrent leurs données sur le périphérique de stockage répliqué, le font sans même savoir qu'il s'agit d'une unité de stockage spéciale. de manière synchrone ou asynchrone : en fonctionnement synchrone, l'écriture est déclarée terminée lorsque les données sont écrites localement ET que la synchronisation est terminée. En fonctionnement asynchrone, l'écriture est déclarée terminée lorsque les données sont écrites localement (sur le serveur primaire et pas sur le serveur de réplique) uniquement. (cf ubuntu.fr) Plantons le tableau. Je suis parti de deux dédibox XL (raid0 pour le stockage) Mon partitionement:

Node1= Disk /dev/md0: 131 MB, 131530752 bytes (/boot) Disk /dev/md1: 42.9 GB, 42935779328 bytes (/)(raid0) Disk /dev/md2: 952.6 GB, 952684642304 bytes (vg0) (raid0) Node2= Disk /dev/md0: 131 MB, 131530752 bytes (/boot) Disk /dev/md1: 42.9 GB, 42935779328 bytes (/)(raid0) Disk /dev/md2: 952.6 GB, 952684642304 bytes (vg0) (raid0) /// On peut déjà apprécier l'éfficacité de Raid logiciel sous linux sur /dev/md2 /// Disk /dev/md2: 952.6 GB, 952684642304 bytes root@node1:~# dd if=/dev/md2 of=/dev/zero bs=1M iflag=direct 1111+0 records in 1110+0 records out 1163919360 bytes (1,2 GB) copied, 6,55167 s, 178 MB/s

Ca peut aller. Je suis parti d'une distribution Ubuntu 8.04 LTS 64bit kernel 2.6.24-24-server sur les 2 noeuds. - Création des LVM.

root@node1:~# apt-get install lvm2

verifier bien que le module dm_mod est chargé, sinon chargez le

dm_mod 78200 7 dm_mirror,dm_snapshot
root@node1:~# pvcreate /dev/md2
root@node1:~# lvcreate -L2G -nlv0 vg0 Logical volume "lv0" created
root@node1:~# lvcreate -L2G -nlv1 vg0 Logical volume "lv1" created

nos deux Logcial volume sont crées. destinés à contenir respectivement drbd0 et drbd1 soit /var/www et /var/lib/mysql Creer la même arborescence lv sur les 2 noeuds.

  • Installation de DRBD

Afin que l'installation de DRBD se passe bien, il faut vérifier quelques petits prérequis. Tout d'abord avoir les outils de compilation.

root@node1:~# apt-get install build-essential

Vérifier aussi d'avoir les sources de votre kernel ou du moins les header.

root@node1:~#apt-get install kernel-headers-$(uname -r) root@node1:~#apt-get install flex

Télécharger les sources de drbd sur le site http://oss.linbit.com/drbd

root@node1:/usr/src# tar xvfz drbd-8.3.1.tar.gz
root@node1:/usr/src# cd drbd-8.3.1 root@node1:/usr/src/drbd-8.3.1# make clean all

Véirifier que tout se compile bien. Installer maintenant DRBD

root@node1:/usr/src#make install -j4 root@node1:/usr/src#make install-tools -j4

attaquons nous au fichier de configuration de drbd situé dans /etc/drbd.conf

common { protocol C; startup { #become-primary-on both; wfc-timeout 30; degr-wfc-timeout 30; } disk { on-io-error detach; no-disk-flushes; no-md-flushes; no-disk-barrier; no-disk-drain; } net { max-buffers 16384; max-epoch-size 16384; unplug-watermark 128; sndbuf-size 8M; ko-count 6; allow-two-primaries; after-sb-0pri discard-zero-changes; after-sb-1pri violently-as0p; after-sb-2pri violently-as0p; rr-conflict violently; } syncer { rate 100M; al-extents 1801; verify-alg crc32c; } } resource r0 { on node1 { device /dev/drbd0; disk /dev/vg0/lv0; address 88.191.84.35:7789; meta-disk internal; } on node2 { device /dev/drbd0; disk /dev/vg0/lv0; address 88.191.84.36:7789; meta-disk internal; } } resource r1 { on node1 { device /dev/drbd1; disk /dev/vg0/lv1; address 88.191.84.35:7790; meta-disk internal; } on node2 { device /dev/drbd1; disk /dev/vg0/lv1; address 88.191.84.36:7790; meta-disk internal; } }

Pareil sur le node2

root@node2#drbdadm create-md r0 r1
root@node2#drbdadm up r0 r1

Puis nous synchronisons les ressources. Sur le node 1 nous lançons

root@node1#drbdadm -- --overwrite-data-of-peer primary r0 r1

On peut alors voir les ressources en cours de synchronisation.

Every 1,0s: cat /proc/drbd version: 8.3.1 (api:88/proto:86-89) GIT-hash: fd40f4a8f9104941537d1afc8521e584a6d3003c build by root@sd-15181, 2009-06-21 20:22:50 0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r---- ns:3157114 nr:98131 dw:1082377 dr:2373543 al:226 bm:133 lo:0 pe:1464 ua:998 ap:1 ep:1 wo:n oos:2027040 [>....................] sync'ed: 3.6% (2027040/2097052)K finish: 0:05:07 speed: 6,452 (5,832) K/sec 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r---- ns:2640518 nr:125231 dw:593569 dr:5326403 al:92 bm:133 lo:0 pe:1472 ua:1006 ap:1 ep:1 wo:n oos:2027760 [>....................] sync'ed: 3.4% (2027760/2097052)K finish: 0:05:07 speed: 6,448 (5,772) K/sec

On peut remarquer qu'entre les 2 dedibox la synchronisation se fait 11Mo/s on sature le lien 100Mb/s ( rien ne nous empeche de limiter ce débit dans le drbd.conf)

  • Passons maintenant à OCFS2.

Si on montait directement nos bases de données et nos sites sur les drbd après les avoir formatés avec un file sytem non clusterisé cela ne fonctionnerait pas. Car le but est que le forum puisque ecrire dans la base des deux cotés que les deux serveurs soient actifs en même temps et aient un accès concurrents au stockage. Pour cela il nous faut un systeme de fichier qui gere les accès concurrents sur un même espace de stockage (es 2 plus connus sont OCFS2 et GFS) installons OCFS2

root@node1#apt-get install ocfs2-tools

On créer le répertoire /etc/ocfs2

root@node1#mkdir /etc/ocfs2

On édite un fichier cluster.conf (identique sur les deux noeuds)

node: ip_port = 7777 ip_address = 88.191.84.35 number = 0 name = node1 cluster = ocfs2 node: ip_port = 7777 ip_address = 88.191.84.36 number = 1 name = node2 cluster = ocfs2 cluster: node_count = 2 name = ocfs2

Changer la valeur “O2CB_ENABLED=false” en “O2CB_ENABLED=true” dans /etc/default/o2cb

On demmarre alors le cluster OCFS2

on peut alors formater nos devices drbd en ocfs2

root@node1#mkfs -t ocfs2 /dev/drbd0
root@node1#mkfs -t ocfs2 /dev/drbd1

Le faire sur un seul noeud suffit puisque drbd à dejà repliqué ce file system de l'autre coté.

Voilà le cluster est prêt à recevoir les données.

Pour ma part j'avais installé lamp avant et j'ai transferé les données sur les nouveaux montages.

root@node1#mount /dev/drbd0 /var/www root@node1#mount /dev/drbd1 /var/lib/mysql

Par contre il est important de désactiver tous les system de cache dans mysql. Car si ocfs2 est capable de gerer la cohérence sur son systeme disk, evidemment il ne peut pas gerer la cohérence entre les caches des deux serveurs Mysql qui tournent en même temps. En tatonnant un peu, j'ai réussi à faire demmarer les deux serveur mysql avec ce fichier de conf.

# # The MySQL database server configuration file. # # You can copy this to one of: # - "/etc/mysql/my.cnf" to set global options, # - "~/.my.cnf" to set user-specific options. # # One can use all long options that the program supports. # Run program with --help to get a list of available options and with # --print-defaults to see which it would actually understand and use. # # For explanations see # http://dev.mysql.com/doc/mysql/en/server-system-variables.html # This will be passed to all mysql clients # It has been reported that passwords should be enclosed with ticks/quotes # escpecially if they contain "#" chars... # Remember to edit /etc/mysql/debian.cnf when changing the socket location. [client] port = 3306 socket = /var/run/mysqld/mysqld.sock # Here is entries for some specific programs # The following values assume you have at least 32M ram # This was formally known as [safe_mysqld]. Both versions are currently parsed. [mysqld_safe] socket = /var/run/mysqld/mysqld.sock nice = 0 [mysqld] # # * Basic Settings # #innodb_data_home_dir = # ## Le fichier de donné doivent contenir vos donné et index. #innodb_data_file_path = /ibdata/ibdata1:2000M; ## ## Utilisez un buffer de taille 50 à 0 % de votre méire serveur ## mais assurez vous sous Linux que l'utilisation totale est inféeure à Go #set-variable = innodb_buffer_pool_size=1G #set-variable = innodb_additional_mem_pool_size=20M #innodb_log_group_home_dir = /dr3/iblogs ## ## innodb_log_arch_dir doit êe le mê que innodb_log_group_home_dir ## (starting from 4.0.6, you can omit it) #innodb_log_arch_dir = /dr3/iblogs #set-variable = innodb_log_files_in_group=2 ## ## Utilisez un fichier de log de taille 15 % du buffer méire #set-variable = innodb_log_file_size=250M #set-variable = innodb_log_buffer_size=8M ## #innodb_flush_log_at_trx_commit=1 #set-variable = innodb_lock_wait_timeout=50 ## ## Démmentez les prochaines lignes, si vous voulez les utiliser ##innodb_flush_method=fdatasync ##set-variable = innodb_thread_concurrency=5 # # # * IMPORTANT # If you make changes to these settings and your system uses apparmor, you may # also need to also adjust /etc/apparmor.d/usr.sbin.mysqld. # user = mysql pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock port = 3306 basedir = /usr datadir = /var/lib/mysql tmpdir = /tmp language = /usr/share/mysql/english skip-external-locking = 0 # # Instead of skip-networking the default is now to listen only on # localhost which is more compatible and is not less secure. bind-address = 127.0.0.1 # # * Fine Tuning # key_buffer = 0 key_buffer_size = 0 max_allowed_packet = 16M thread_stack = 128K thread_cache_size = 0 #max_connections = 100 #table_cache = 64 #thread_concurrency = 10 # # * Query Cache Configuration # query_cache_type = 0 query_cache_limit = 0 query_cache_size = 0 # # * Logging and Replication # # Both location gets rotated by the cronjob. # Be aware that this log type is a performance killer. log = /var/log/mysql/mysql.log # # Error logging goes to syslog. This is a Debian improvement :) # # Here you can see queries with especially long duration #log_slow_queries = /var/log/mysql/mysql-slow.log #long_query_time = 2 #log-queries-not-using-indexes # # The following can be used as easy to replay backup logs or for replication. # note: if you are setting up a replication slave, see README.Debian about # other settings you may need to change. #server-id = 1 #log_bin = /var/log/mysql/mysql-bin.log expire_logs_days = 10 max_binlog_size = 100M #binlog_do_db = include_database_name #binlog_ignore_db = include_database_name # # * BerkeleyDB # # Using BerkeleyDB is now discouraged as its support will cease in 5.1.12. skip-bdb # # * InnoDB # # InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/. # Read the manual for more InnoDB related options. There are many! # You might want to disable InnoDB to shrink the mysqld process by circa 100MB. #skip-innodb # # * Security Features # # Read the manual, too, if you want chroot! # chroot = /var/lib/mysql/ # # For generating SSL certificates I recommend the OpenSSL GUI "tinyca". # # ssl-ca=/etc/mysql/cacert.pem # ssl-cert=/etc/mysql/server-cert.pem # ssl-key=/etc/mysql/server-key.pem [mysqldump] quick quote-names max_allowed_packet = 16M [mysql] #no-auto-rehash # faster start of mysql but no tab completition [isamchk] key_buffer = 0 # # * NDB Cluster # # See /usr/share/doc/mysql-server-*/README.Debian for more information. # # The following configuration is read by the NDB Data Nodes (ndbd processes) # not from the NDB Management Nodes (ndb_mgmd processes). # # [MYSQL_CLUSTER] # ndb-connectstring=127.0.0.1 # # * IMPORTANT: Additional settings that can override those from this file! # The files must end with '.cnf', otherwise they'll be ignored. # !includedir /etc/mysql/conf.d/

J'ai alors installé le forum PunBB sur un noeud, qui s'est bien sur instantanément répliqué sur l'autre.

Quand j'ai parlé d'équilibrage de charge dans le titre, je l'obtient en utilisant simplement un round robin au niveau DNS. C'est à dire 2 enregistrement A avec le meme nom qui pointent sur les 2 ip de mon cluster.

forum.info16.fr. IN A 88.191.84.35 forum.info16.fr. IN A 88.191.84.36

Ainsi aléatoirement un utilisateur cherchant à se connecter au forum forum.info16.fr sera diriger vers 88.191.84.35 ou 88.191.84.36 Attention on ne gere pas du tout le failover. Si un serveur plante l'utilisateur aura une chance sur 2 d'etre dirigé vers le site innaccessible.

Et même si on essait de gerer le DNS afin qu'il detecte si un serveur est innaccessible et modifie ces enregistrements en conséquence, on ne pourra jamais gérer le cache DNS des clients qui se connectent... Ils auront une ip innaccessible jusqu'au TTL. d'ou l'importance de mettre des TTL bas pour les round robin.

Information sur bartounet auteur de l'article

1 commentaire

#1 

Hello, Felicitations pour votre bel explication ! J'attend avec impatience la suite. Cordialement, Estelle Commentaire de mahjong gratuit

Répondre

Fil RSS des commentaires de cet article

Les commentaires sont fermés.