分享我做的nginx+keepalived做的主主架构(一)

最近帮朋友设计他们公司的系统架构,这是第2次进行帮他设计了,第一个是把他的lanmp架构(所有的应用与服务、数据库都在一个服务器里)改成1+1模式(nginx+mysql),最近由于他公司的名气上升,每天的在线数在4000-6000左右,并发最多能到9000左右,现有的架构有一些支撑不了,所有我又重新的帮他设计了一下。
我新设计的架构为dns(轮询)+nginx+keepalived(主主模式,2台服务器)+web(应用服务器2台服务器)+mysql(采用drbd+hearbeat+mysql,2台服务器),总共6台服务器,系统均为rhel 5.4 x86_64。
此篇文章既可以是一个完整性的架构,也可以是nginx+keepalived单主、双主模式负载均衡,nginx的反向代理,msyql的drbd+heartbeat+msyql的高可用,以及通过nfs来实现web服务器间的数据共享,分开与结合都是一篇很有深度的文章(个人认为),所以我没有把这些用到的技术分开来写,通过一篇文章写能够给大家更好的理解,否则单个的描述可能会造成大家对单个技术能更好的理解,但对整体的不会有太好的了解(虽然我也想分开写,这样能多几个推荐)。
下面是我做的架构图:
【分享我做的nginx+keepalived做的主主架构(一)】
网络通信的过程如下: 1、用户想进行浏览www.netnvo.com网站的内容,先进行本地dns查看,是否有此网站的ip,如果没有则去上级dns进行查找; 2、如果找到,则跳转到相应的ip上; 3、请求到达负载均衡层时,根据相应的策略把请求分发到web服务器里; 4、web服务器接收到请求,进行处理并发送读写操作请求给数据库; 5、数据库收到读写操作请求,完成此项操作并反馈给web服务器; 6、web服务器收到反馈并发送处理完成的数据到负载均衡里; 7、负载均衡收到数据并发送给用户; 8、用户收到了数据,以一定的方式进行查看(不限于浏览器); 下面是我具体的安装过程 一、负载均衡层 1、在test1与test2里安装nginx 可以使用我之前发的文章“ 模块化的安装lnmp脚本”来进行自动化安装nginx,博客地址为:http://dl528888.blog.51cto.com/2382721/816542。 先进行下载lnmp脚本


  1. [root@test1 tmp]# wget http://202.96.42.117/soft/install_lnmp.tar.gz
先解压

  1. [root@nginx1 tmp]# tar zxf install_lnmp.tar.gz
  2. [root@nginx1 tmp]# ll
  3. total 64456
  4. -rwxr-xr-x 1 root root13767 Mar 25 01:23 install_lnmp.sh
  5. -rw-r--r-- 1 root root 65910919 Mar 25 01:24 install_lnmp.tar.gz
  6. drwxr-xr-x 5 root root4096 Mar 23 09:54 soft
然后在检测是否安装lnmp

  1. [root@test1 tmp]# sh install_lnmp.sh install_check
  2. Sat Apr7 03:29:46 MDT 2012 Start install!
  3. ========================== Check install ================================
  4. Error: /usr/local/nginx not found!!!
  5. Error: /usr/local/php not found!!!
  6. Error: /usr/local/mysql not found!!!
  7. ========================== Check install ================================
  8. Sorry,Failed to install LNMP!
  9. Please check errors and logs.
  10. Sat Apr7 03:29:46 MDT 2012 Finish install!
  11. Total runtime: 0 Seconds
从输出看到没有安装lnmp软件 那现在我们进行nginx安装,在安装之前,先进行依赖库的安装

  1. [root@test1 tmp]# sh install_lnmp.sh init
然后在安装nginx

  1. [root@test1 tmp]# sh install_lnmp.sh install_nginx
完成之后进行检测

  1. [root@test1 tmp]#sh install_lnmp.sh install_check
  2. Sat Apr7 04:48:05 MDT 2012 Start install!
  3. ========================== Check install ================================
  4. /usr/local/nginx [found]
  5. Error: /usr/local/php not found!!!
  6. Error: /usr/local/mysql not found!!!
  7. ========================== Check install ================================
  8. Sorry,Failed to install LNMP!
  9. Please check errors and logs.
  10. Sat Apr7 04:48:05 MDT 2012 Finish install!
  11. Total runtime: 0 Seconds
可以发现nginx是安装完成

  1. [root@test1 sbin]# curl -i 127.0.0.1
  2. HTTP/1.1 200 OK
  3. Server: YWS/1.0
  4. Date: Sat, 07 Apr 2012 10:08:39 GMT
  5. Content-Type: text/html
  6. Content-Length: 151
  7. Last-Modified: Sat, 07 Apr 2012 09:38:53 GMT
  8. Connection: keep-alive
  9. Accept-Ranges: bytes
  10. Welcome to nginx! - 锐客网
  11. Welcome to nginx!
能打开nginx的首页了 下面是我为nginx负载均衡做的配置 nginx的配置为


  1. userwww www;
  2. worker_processes 8;
  3. error_log/usr/local/nginx/logs/nginx_error.logcrit;
  4. pid/usr/local/nginx/nginx.pid;
  5. #Specifies the value for maximum file descriptors that can be opened by this process.
  6. worker_rlimit_nofile 65535;
  7. events
  8. {
  9. use epoll;
  10. worker_connections 65535;
  11. }
  12. http
  13. {
  14. includemime.types;
  15. default_typeapplication/octet-stream;
  16. #charsetgb2312;
  17. server_names_hash_bucket_size 128;
  18. client_header_buffer_size 32k;
  19. large_client_header_buffers 4 32k;
  20. client_max_body_size 8m;
  21. sendfile on;
  22. tcp_nopushon;
  23. keepalive_timeout 60;
  24. tcp_nodelay on;
  25. fastcgi_connect_timeout 300;
  26. fastcgi_send_timeout 300;
  27. fastcgi_read_timeout 300;
  28. fastcgi_buffer_size 64k;
  29. fastcgi_buffers 4 64k;
  30. fastcgi_busy_buffers_size 128k;
  31. fastcgi_temp_file_write_size 128k;
  32. gzip on;
  33. gzip_min_length1k;
  34. gzip_buffers4 16k;
  35. gzip_http_version 1.0;
  36. gzip_comp_level 2;
  37. gzip_typestext/plain application/x-javascript text/css application/xml;
  38. gzip_vary on;
  39. #limit_zonecrawler$binary_remote_addr10m;
  40. upstream web1##定义负载均衡组为web1
  41. {
  42. ip_hash;
  43. server 10.1.88.168:80;
  44. server 10.1.88.177:80;
  45. }
  46. server
  47. {
  48. listen80;
  49. server_namewww.netnov.com;
  50. location / {
  51. root /data/www;
  52. index index.php index.htm index.html;
  53. proxy_redirect off;
  54. proxy_set_header Host $host;
  55. proxy_set_header X-Real-IP $remote_addr;
  56. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  57. proxy_pass http://web1;
  58. }
  59. access_logoff;
  60. }
  61. location ~ .*\.(php|php5)?$
  62. {
  63. #fastcgi_passunix:/tmp/php-cgi.sock;
  64. fastcgi_pass127.0.0.1:9000;
  65. fastcgi_index index.php;
  66. include fastcgi.conf;
  67. }
  68. location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
  69. {
  70. expires30d;
  71. }
  72. location ~ .*\.(js|css)?$
  73. {
  74. expires1h;
  75. }
  76. location /###当后端服务器遇到500、502、504、错误与超时,自动将请求转发给web1组的另一台服务器,达到故障转移
  77. {
  78. proxy_passhttp://web1;
  79. proxy_next_upstream http_500 http_502 http_504 error timeout invalid_header;
  80. include/usr/local/nginx/conf/proxy.conf;
  81. }
  82. log_formataccess'$remote_addr - $remote_user [$time_local] "$request" '
  83. '$status $body_bytes_sent "$http_referer" '
  84. '"$http_user_agent" $http_x_forwarded_for';
  85. access_log/usr/local/nginx/logs/access.logaccess;
  86. }
  87. server
  88. {
  89. listen80;
  90. server_namestatus.netnov.com;
  91. location / {
  92. stub_status on;
  93. access_logoff;
  94. }
  95. }
  96. }
test2也跟test1一样安装,就不在进行重复演示了 2、安装 keepalived 先下载 master端的(也就是test1)

  1. [root@test1 src]# wget http://www.keepalived.org/software/keepalived-1.2.2.tar.gz
  2. [root@test1 src]# tar zxvf keepalived-1.2.2.tar.gz
  3. [root@test1 src]# cd keepalived-1.2.2
  4. [root@test1 keepalived-1.2.2]# ./configure --prefix=/usr/local/keepalived
  5. [root@test1 keepalived-1.2.2]# make
  6. [root@test1 keepalived-1.2.2]# make install
  7. [root@test1 keepalived-1.2.2]# cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
  8. [root@test1 keepalived-1.2.2]# cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
  9. [root@test1 keepalived-1.2.2]# cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
  10. [root@test1 keepalived-1.2.2]# mkdir /etc/keepalived
  11. [root@test1 tmp]# chkconfig --add keepalived
  12. [root@test1 tmp]# chmod 755 /etc/init.d/keepalived
  13. [root@test1 tmp]# chkconfig keepalived on
  14. [root@test1 tmp]#vim /etc/keepalived/keepalived.conf
  15. global_defs {
  16. notification_email {
  17. denglei@ctfo.com
  18. }
  19. notification_email_from root@test1.com
  20. smtp_server 127.0.0.1
  21. smtp_connect_timeout 30
  22. router_id LVS_DEVEL
  23. }
  24. vrrp_script chk_http_port {
  25. script "/tmp/monitor_nginx.sh"
  26. interval 2
  27. weight 2
  28. }
  29. vrrp_instance VI_1 {
  30. state MASTER
  31. interface eth0
  32. virtual_router_id 51
  33. priority 101
  34. authentication {
  35. auth_type PASS
  36. auth_pass eric
  37. }
  38. track_script {
  39. chk_http_port
  40. }
  41. virtual_ipaddress {
  42. 10.1.88.200
  43. }
  44. }
下面是监控nginx的脚本

  1. [root@test1 tmp]# cat monitor_nginx.sh
  2. #!/bin/bash
  3. A=`ps -C nginx --no-header |wc -l`
  4. if [ $A -eq 0 ]; then
  5. /usr/local/nginx/sbin/nginx
  6. sleep 3
  7. if [ `ps -C nginx --no-header |wc -l` -eq 0 ]; then
  8. killall keepalived
  9. fi
  10. fi
  11. [root@test1 tmp]#service keepalived restart
BACKUP端的

  1. [root@test2 src]# wget http://www.keepalived.org/software/keepalived-1.2.2.tar.gz
  2. [root@test2 src]# tar zxvf keepalived-1.2.2.tar.gz
  3. [root@test2 src]# cd keepalived-1.2.2
  4. [root@test2 keepalived-1.2.2]# ./configure --prefix=/usr/local/keepalived
  5. [root@test2 keepalived-1.2.2]# make
  6. [root@test2 keepalived-1.2.2]# make install
  7. [root@test2 keepalived-1.2.2]# cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
  8. [root@test2 keepalived-1.2.2]# cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
  9. [root@test2 keepalived-1.2.2]# cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
  10. [root@test2 keepalived-1.2.2]# mkdir /etc/keepalived
  11. [root@test2 keepalived-1.2.2]# vim /etc/keepalived/keepalived.conf
  12. [root@test2 tmp]# chkconfig --add keepalived
  13. [root@test2 tmp]# chmod 755 /etc/init.d/keepalived
  14. [root@test2 tmp]# chkconfig keepalived on
  15. [root@test2 tmp]#vim /etc/keepalived/keepalived.conf
  16. global_defs {
  17. notification_email {
  18. denglei@ctfo.com
  19. }
  20. notification_email_from root@test2.com
  21. smtp_server 127.0.0.1
  22. smtp_connect_timeout 30
  23. router_id LVS_DEVEL
  24. }
  25. vrrp_script chk_http_port {
  26. script "/tmp/monitor_nginx.sh"
  27. interval 2
  28. weight 2
  29. }
  30. vrrp_instance VI_1 {
  31. stateBACKUP
  32. interface eth0
  33. virtual_router_id 51
  34. priority 100
  35. authentication {
  36. auth_type PASS
  37. auth_pass eric
  38. }
  39. track_script {
  40. chk_http_port
  41. }
  42. virtual_ipaddress {
  43. 10.1.88.200
  44. }
  45. }
  46. [root@test2 tmp]# cat monitor_nginx.sh
  47. #!/bin/bash
  48. A=`ps -C nginx --no-header |wc -l`
  49. if [ $A -eq 0 ]; then
  50. /usr/local/nginx/sbin/nginx
  51. sleep 3
  52. if [ `ps -C nginx --no-header |wc -l` -eq 0 ]; then
  53. killall keepalived
  54. fi
  55. fi
  56. [root@test2 tmp]#service keepalived restart
现在test1与test2的keepalived都安装完成,是单主模式的负载均衡,由于我想把网站做成负载均衡双主模式,所以我在test1与test2的keepalived.conf里做了修改:
test1里的

  1. global_defs {
  2. notification_email {
  3. denglei@ctfo.com
  4. }
  5. notification_email_from root@test1.com
  6. smtp_server 127.0.0.1
  7. smtp_connect_timeout 30
  8. router_id LVS_DEVEL
  9. }
  10. vrrp_script chk_http_port {
  11. script "/tmp/monitor_nginx.sh"
  12. interval 2
  13. weight 2
  14. }
  15. vrrp_instance VI_1 {
  16. state MASTER
  17. interface eth0
  18. virtual_router_id 51
  19. priority 101
  20. authentication {
  21. auth_type PASS
  22. auth_pass eric
  23. }
  24. track_script {
  25. chk_http_port
  26. }
  27. virtual_ipaddress {
  28. 10.1.88.200
  29. }
  30. }
  31. vrrp_instance VI_2 {
  32. state BACKUP
  33. interface eth0
  34. virtual_router_id 52
  35. priority 90
  36. authentication {
  37. auth_type PASS
  38. auth_pass eric
  39. }
  40. track_script {
  41. chk_http_port
  42. }
  43. virtual_ipaddress {
  44. 10.1.88.201
  45. }
  46. }
test2里的

  1. global_defs {
  2. notification_email {
  3. denglei@ctfo.com
  4. }
  5. notification_email_from root@test1.com
  6. smtp_server 127.0.0.1
  7. smtp_connect_timeout 30
  8. router_id LVS_DEVEL
  9. }
  10. vrrp_script chk_http_port {
  11. script "/tmp/monitor_nginx.sh"
  12. interval 2
  13. weight 2
  14. }
  15. vrrp_instance VI_1 {
  16. state BACKUP
  17. interface eth0
  18. virtual_router_id 51
  19. priority 90
  20. authentication {
  21. auth_type PASS
  22. auth_pass eric
  23. }
  24. track_script {
  25. chk_http_port
  26. }
  27. virtual_ipaddress {
  28. 10.1.88.200
  29. }
  30. }
  31. vrrp_instance VI_2 {
  32. state MASTER
  33. interface eth0
  34. virtual_router_id 52
  35. priority 101
  36. authentication {
  37. auth_type PASS
  38. auth_pass eric
  39. }
  40. track_script {
  41. chk_http_port
  42. }
  43. virtual_ipaddress {
  44. 10.1.88.201
  45. }
  46. }
这样主主模式的负载均衡就部署完成 二、 web层的部署 1、安装 nginx+php(fastcgi) 可以使用源码安装,也可以使用我的 lnmp脚本进行安装 先下载模块化安装lnmp脚本

  1. [root@test4 tmp]# wget http://202.96.42.117/soft/install_lnmp.tar.gz
然后解压

  1. [root@test4 tmp]# tar zxf install_lnmp.tar.gz
然后安装nginx

  1. [root@test4 tmp]# sh install_lnmp.sh install_nginx
安装完成在进行php的安装

  1. [root@test4 tmp]# sh install_lnmp.sh install_php
都安装完成之后,进行检查

  1. [root@test4 tmp]#sh install_lnmp.sh install_check
  2. Sat Apr7 04:48:05 MDT 2012 Start install!
  3. ========================== Check install ================================
  4. /usr/local/nginx [found]
  5. /usr/local/php[found]
  6. Error: /usr/local/mysql not found!!!
  7. ========================== Check install ================================
  8. Sorry,Failed to install LNMP!
  9. Please check errors and logs.
  10. Sat Apr7 04:55:05 MDT 2012 Finish install!
  11. Total runtime: 0 Seconds
可以看到nginx与php都安装完成 现在开始安装数据库层 三、数据库层 安装drbd 1、修改hosts文件 test6的

  1. [root@test6 /]# cat /etc/hosts
  2. # Do not remove the following line, or various programs
  3. # that require network functionality will fail.
  4. 127.0.0.1localhost.localdomain localhost
  5. ::1localhost6.localdomain6 localhost6
  6. 10.1.88.175 test6
  7. 10.1.88.179 test7

test7的

  1. [root@test7 /]# cat /etc/hosts
  2. # Do not remove the following line, or various programs
  3. # that require network functionality will fail.
  4. 127.0.0.1localhost.localdomain localhost
  5. ::1localhost6.localdomain6 localhost6
  6. 10.1.88.175 test6
  7. 10.1.88.179 test7


  1. [root@test6 ~]# yum install -y drbd83 kmod-drbd83 heartbeat*
  2. [root@test6 ~]# rpm -qa|grep heartbeat
  3. heartbeat-pils-2.1.3-3.el5.centos
  4. heartbeat-stonith-2.1.3-3.el5.centos
  5. heartbeat-gui-2.1.3-3.el5.centos
  6. heartbeat-devel-2.1.3-3.el5.centos
  7. heartbeat-ldirectord-2.1.3-3.el5.centos
加载模块

  1. [root@test6 ~]# modprobe drbd
在test6与test7都查看是否加载成功

  1. [root@test6~]# lsmod |grep drbd
  2. drbd2987603
  3. [root@test7~]# lsmod |grep drbd
  4. drbd2987605
  5. [root@test6/]# cat /etc/drbd.conf
  6. #
  7. # please have a a look at the example configuration file in
  8. # /usr/share/doc/drbd83/drbd.conf
  9. #
  10. #
  11. # please have a a look at the example configuration file in
  12. # /usr/share/doc/drbd83/drbd.conf
  13. global {
  14. # minor-count 64;
  15. # dialog-refresh 5; # 5 seconds
  16. # disable-ip-verification;
  17. usage-count no;
  18. }
  19. common {
  20. syncer { rate 100M; }
  21. }
  22. resource db {
  23. protocolC;
  24. handlers {
  25. pri-on-incon-degr "echo o > /proc/sysrq-trigger ; halt -f";
  26. pri-lost-after-sb "echo o > /proc/sysrq-trigger ; halt -f";
  27. local-io-error "echo o > /proc/sysrq-trigger ; halt -f";
  28. fence-peer "/usr/lib64/heartbeat/drbd-peer-outdater -t 5";
  29. pri-lost "echo pri-lost. Have a look at the log files. | mail -s 'DRBD Alert' denglei@ctfo.com";
  30. split-brain "/usr/lib/drbd/notify-split-brain.sh denglei@ctfo.com";
  31. out-of-sync "/usr/lib/drbd/notify-out-of-sync.sh denglei@ctfo.com";
  32. }
  33. net {
  34. # timeout60;
  35. # connect-int10;
  36. # ping-int10;
  37. # max-buffers2048;
  38. # max-epoch-size2048;
  39. cram-hmac-alg "sha1";
  40. shared-secret "MySQL-HA";
  41. }
  42. disk {
  43. on-io-error detach;
  44. fencing resource-only;
  45. }
  46. startup {
  47. wfc-timeout 120;
  48. degr-wfc-timeout 120;
  49. }
  50. device/dev/drbd1;
  51. on test6 {
  52. disk/dev/sda2;
  53. address10.1.88.175:7788;
  54. meta-diskinternal;
  55. }
  56. on test7 {
  57. disk/dev/sda6;
  58. address10.1.88.179:7788;
  59. meta-diskinternal;
  60. }
  61. }
把配置文件另传给test7一份

  1. [root@test6 ~]# scp /etc/drbd.conf 10.1.88.179:/etc/
  2. root@10.1.88.179's password:
  3. drbd.conf100%6870.7KB/s00:00
  4. 初始化meta-data area:
  5. [root@test6 ~]# drbdadm create-md db
  6. md_offset 2730786816
  7. al_offset 2730754048
  8. bm_offset 2730668032
  9. Found ext3 filesystem
  10. 2666788 kB data area apparently used
  11. 2666668 kB left usable by current configuration
  12. Device size would be truncated, which
  13. would corrupt data and result in
  14. 'access beyond end of device' errors.
  15. You need to either
  16. * use external meta data (recommended)
  17. * shrink that filesystem first
  18. * zero out the device (destroy the filesystem)
  19. Operation refused.
  20. Command 'drbdmeta 1 v08 /dev/sda2 internal create-md' terminated with exit code 40
  21. drbdadm create-md db: exited with code 40
出现这个问题使用 dd 指令将一些资料塞到 /dev/sda2后再执行 drbdadm create-md db(db是drbd.conf里设置的资源名称) 指令即可顺利执行

  1. [root@test6 ~]# drbdadm create-md db
  2. Writing meta data...
  3. initializing activity log
  4. NOT initialized bitmap
  5. New drbd meta data block successfully created.
  6. success
成功的完成了初始化meta-data area,在test7里进行初始化

  1. [root@test7 /]# drbdadm create-md db
  2. --==Thank you for participating in the global usage survey==--
  3. The server's response is:
  4. you are the 2845th user to install this version
  5. md_offset 2730754048
  6. al_offset 2730721280
  7. bm_offset 2730635264
  8. Found some data
  9. ==> This might destroy existing data! <==
  10. Do you want to proceed?
  11. [need to type 'yes' to confirm] yes
  12. You want me to create a v08 style flexible-size internal meta data block.
  13. There appears to be a v08 flexible-size internal meta data block
  14. already in place on /dev/sda6 at byte offset 2730754048
  15. Do you really want to overwrite the existing v08 meta-data?
  16. [need to type 'yes' to confirm] yes
  17. Writing meta data...
  18. initializing activity log
  19. NOT initialized bitmap
  20. New drbd meta data block successfully created.
然后在test6与test7里都启动drbd

  1. [root@test6 ~]# /etc/init.d/drbd start
  2. Starting DRBD resources: [ d(db) s(db) n(db) ]........
  3. [root@test7 /]# /etc/init.d/drbd start
  4. Starting DRBD resources: [ d(db) s(db) n(db) ].
通过端口查看drbd是否启动

  1. [root@test6 ~]# netstat -antl|grep 7789
  2. tcp00 10.1.88.175:778910.1.88.179:50990ESTABLISHED
  3. tcp00 10.1.88.175:4032310.1.88.179:7789ESTABLISHED
  4. [root@test7 /]# netstat -antl|grep 7789
  5. tcp00 10.1.88.179:778910.1.88.175:40323ESTABLISHED
  6. tcp00 10.1.88.179:5099010.1.88.175:7789ESTABLISHED
查看test6与test7的drbd状态

  1. [root@test6 ~]# cat /proc/drbd
  2. version: 8.3.12 (api:88/proto:86-96)
  3. GIT-hash: e2a8ef4656be026bbae540305fcb998a5991090f build by mockbuild@builder10.centos.org, 2012-01-28 13:52:25
  4. 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----
  5. ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:2666636
  6. [root@test7 /]# cat /proc/drbd
  7. version: 8.3.12 (api:88/proto:86-96)
  8. GIT-hash: e2a8ef4656be026bbae540305fcb998a5991090f build by mockbuild@builder10.centos.org, 2012-01-28 13:52:25
  9. 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----
  10. ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:2666636
对输出的含义解释如下:
ro表示角色信息,第一次启动drbd时,两个drbd节点默认都处于Secondary状态,
ds是磁盘状态信息,“Inconsistent/Inconsisten”,即为“不一致/不一致”状态,表示两个节点的磁盘数据处于不一致状态。
Ns表示网络发送的数据包信息。
Dw是磁盘写信息
Dr是磁盘读信息 途中中显示了drbd两台主机都是"备机"状态.DRBD无法判断哪一方为主机,以哪一方的磁盘数据作为标准数据.所以,我们需要初始化,比如我选择test6作为主机

  1. [root@test6 ~]# drbdsetup /dev/drbd1 primary -o
此命令只在主机里输入 然后在查看test6与test7的drbd状态

  1. [root@test6 ~]# cat /proc/drbd
  2. version: 8.3.12 (api:88/proto:86-96)
  3. GIT-hash: e2a8ef4656be026bbae540305fcb998a5991090f build by mockbuild@builder10.centos.org, 2012-01-28 13:52:25
  4. 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
  5. ns:29696 nr:0 dw:0 dr:29696 al:0 bm:1 lo:0 pe:7 ua:0 ap:0 ep:1 wo:b oos:2637836
  6. [>....................] sync'ed:1.3% (2637836/2666636)K
  7. finish: 0:03:00 speed: 14,400 (14,400) K/sec
  8. [root@test7 /]# cat /proc/drbd
  9. version: 8.3.12 (api:88/proto:86-96)
  10. GIT-hash: e2a8ef4656be026bbae540305fcb998a5991090f build by mockbuild@builder10.centos.org, 2012-01-28 13:52:25
  11. 1: cs:SyncTarget ro:Secondary/Primary ds:Inconsistent/UpToDate C r-----
  12. ns:0 nr:1328128 dw:1328128 dr:0 al:0 bm:81 lo:0 pe:8 ua:0 ap:0 ep:1 wo:b oos:1338508
  13. [=========>..........] sync'ed: 50.0% (1338508/2666636)K
  14. finish: 0:02:10 speed: 10,224 (10,216) want: 10,240 K/sec
从test6的drbd状态看出:“ro状态现在变为“Primary/Secondary”,“ds”状态也变为“UpToDate/Inconsistent”,也就是“实时/不一致”状态,现在数据正在主备两个主机的磁盘间进行同步,且同步进度为1.3%,同步速度每秒14M左右。
等一会在查看drbd的状态:

  1. [root@test6 /]# cat /proc/drbd
  2. version: 8.3.12 (api:88/proto:86-96)
  3. GIT-hash: e2a8ef4656be026bbae540305fcb998a5991090f build by mockbuild@builder10.centos.org, 2012-01-28 13:52:25
  4. 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
  5. ns:2666636 nr:0 dw:0 dr:2666636 al:0 bm:163 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
  6. [root@test7 /]# cat /proc/drbd
  7. version: 8.3.12 (api:88/proto:86-96)
  8. GIT-hash: e2a8ef4656be026bbae540305fcb998a5991090f build by mockbuild@builder10.centos.org, 2012-01-28 13:52:25
  9. 1: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r-----
  10. ns:0 nr:2666636 dw:2666636 dr:0 al:0 bm:163 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
从test6与test7的drbd输出可知,磁盘状态都是"实时",表示数据同步完成了.现在把主机的drbd挂载到一个目录上进行使用.备机的DRBD设备无法被挂载,因为它是用来接收主机数据的,由drbd负责操作,也就是说如果test6为主机时,可以用/dev/drbd1挂载到一个目录,然后你可以进入那个目录里进行各种操作,test7为备机,那么test7就不能把/dev/drbd1挂载到一个目录,必须等得test7为主机的时候,才能把/dev/drbd1挂载到一个目录。 在挂载/dev/drbd1的时候,需要先给/dev/drbd1格式化文件系统

  1. [root@test6 /]# mkfs.ext3 /dev/drbd1
  2. mke2fs 1.39 (29-May-2006)
  3. Filesystem label=
  4. OS type: Linux
  5. Block size=4096 (log=2)
  6. Fragment size=4096 (log=2)
  7. 333984 inodes, 666659 blocks
  8. 33332 blocks (5.00%) reserved for the super user
  9. First data block=0
  10. Maximum filesystem blocks=683671552
  11. 21 block groups
  12. 32768 blocks per group, 32768 fragments per group
  13. 15904 inodes per group
  14. Superblock backups stored on blocks:
  15. 32768, 98304, 163840, 229376, 294912
  16. Writing inode tables: done
  17. Creating journal (16384 blocks): done
  18. Writing superblocks and filesystem accounting information: done
  19. This filesystem will be automatically checked every 35 mounts or
  20. 180 days, whichever comes first.Use tune2fs -c or -i to override.
然后把/dev/drbd1挂载到/mnt目录下(这个目录可以随便指定)

  1. [root@test6 /]# mount /dev/drbd1 /mnt
然后进入目录查看内容

  1. [root@test6 /]# cd /mnt/
  2. [root@test6 mnt]# ll
  3. total 16
  4. drwx------ 2 root root 16384 Mar8 22:28 lost+found
然后我们可以在mnt里创建个文件,看看是否能保存到备机test7的drbd里

  1. [root@test6 mnt]# touch create_by_test6
  2. [root@test6 mnt]# ll
  3. total 16
  4. -rw-r--r-- 1 root root0 Mar8 22:32 create_by_test6
  5. drwx------ 2 root root 16384 Mar8 22:28 lost+found
然后到备机test7里查看是否有这个文件,这个操作也是drbd的主备机切换,你需要将drbd的主备机互换一下.如果不执行这个操作,你到备机test7里查看会发现/mnt目录里什么都没有

  1. [root@test7 /]# cd /mnt/
  2. [root@test7 mnt]# ll
  3. total 0
在主机test6上,先要卸载掉drbd设备,或者卸载/dev/drbd1挂载的/mnt目录 需要先退出mnt目录,然后在执行卸载,否则会出现umount: /mnt: device is busy

  1. [root@test6 mnt]# cd ..
  2. [root@test6 /]# umount /mnt
然后使用drbdadm secondary db把主机变为备机

  1. [root@test6 /]# drbdadm secondary db
  2. [root@test6 /]# cat /proc/drbd
  3. version: 8.3.12 (api:88/proto:86-96)
  4. GIT-hash: e2a8ef4656be026bbae540305fcb998a5991090f build by mockbuild@builder10.centos.org, 2012-01-28 13:52:25
  5. 1: cs:Connected ro:Secondary/Secondary ds:UpToDate/UpToDate C r-----
  6. ns:2775056 nr:0 dw:108420 dr:2666773 al:38 bm:163 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
现在test6变成了备机,我们接下来到test7里操作,使用drbdadm primary db,使test7变成主机

  1. [root@test7 /]# drbdadm primary db
  2. [root@test7 /]# cat /proc/drbd
  3. version: 8.3.12 (api:88/proto:86-96)
  4. GIT-hash: e2a8ef4656be026bbae540305fcb998a5991090f build by mockbuild@builder10.centos.org, 2012-01-28 13:52:25
  5. 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
  6. ns:0 nr:2775056 dw:2775056 dr:0 al:0 bm:163 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
从test7的drbd输出可以看到,test7成为了主机 然后把drbd挂载到mnt目录下,查看是否有test6里建立的文件

  1. [root@test7 /]# mount /dev/drbd1 /mnt
  2. [root@test7 /]# cd /mnt
  3. [root@test7 mnt]# ll
  4. total 16
  5. -rw-r--r-- 1 root root0 Mar8 22:32 create_by_test6
  6. drwx------ 2 root root 16384 Mar8 22:28 lost+found
可以看出,test7成为主机时,收到了之前主机test6建立的文件夹。 现在drbd安装完成,我们继续安装heartbeat与mysql 2、安装 heartbeat与mysql 前文已经yum安装了heartbeat所以现在就不安装了 1、查看heartbeat的配置文件ha.cf

  1. [root@test6 ~]# grep -v "^#" /etc/ha.d/ha.cf
  2. debugfile /var/log/ha-debug#错误的日志
  3. logfile /var/log/ha-log#日志
  4. logfacility local0#这个是设置heartbeat的日志,这里是用的系统日志
  5. keepalive 2#心跳的频率
  6. deadtime 10#死亡时间,如果其他节点10s回应,则认为死亡
  7. warntime 5#如果死亡之后,5s还没有连接则把警告信息写入日志里
  8. initdead 120#在其他节点死掉之后,系统启动前需要等待的时间,一般为deadtime的两倍
  9. udpport 694#用udp协议的694端口通信
  10. ucast eth0 10.1.88.179#另外一个节点的ip
  11. auto_failback off#设置当死亡节点恢复正常之后是否重新启用;容易发生数据不一致的情况,必须项,不然后面hb_standby命令无法使用;
  12. nodetest6#节点名(通过uname -n查询)
  13. nodetest7#节点名(通过uname -n查询)
  14. ping 10.1.88.254#ping网关查看网络情况(当网络或者heartbeat失效是使用)
  15. respawn hacluster /usr/lib/heartbeat/ipfail#这里是配置ip绑定和切换的功能, ipfail就是控制ip切换的程序
  16. apiauth ipfail gid=haclient uid=hacluster#控制ip切换的时候所使用的用户
2、设置节点之间的通信密钥

  1. [root@test6 ~]# grep -v "^#" /etc/ha.d/authkeys
  2. auth 1
  3. 1 crc
3、使用heartbeat的haresources来定义资源

  1. [root@test6 ~]# grep -v "^#" /etc/ha.d/haresources
  2. test6 IPaddr::10.1.88.199/24/eth0:1 mysqld_umount mysqld
解释: 1) test6做为默认的drbd的primary机器(如果想指定哪个主机为drbd的primary则这里输入那台主机的uname -n的名字) 2) Ipaddr为/etc/ha.d/resource.d目录里面的一个可执行文件。resource.d里面的所有文件都是可执行的,如果不行,执行下面的指令 #chmod 755 -R /etc/ha.d/resource.d 3) 10.1.88.199/24/eth0:1是指定的 heartbeat的VIP 4) mysqld_umount 定义的脚本 5) mysqld:这个也是/etc/ha.d/resource.d目录下的内容,就是mysql的启动程序。如果没有,可以执行下面指令 #ln -s /etc/init.d/mysqld /etc/ha.d/resource.d/mysqld 三、安装mysql 可以使用源码安装,也可以使用yum安装,下面我使用的是源码安装(生产环境一定要是有最新稳定版的源码安装) 先下载模块化安装lnmp脚本

  1. [root@test6 tmp]# wget http://202.96.42.117/soft/install_lnmp.tar.gz
然后解压

  1. [root@test6 tmp]# tar zxf install_lnmp.tar.gz
然后安装nginx

  1. [root@test6 tmp]# sh install_lnmp.sh install_mysql
test7也是一样 在启动heartbeat

  1. [root@test6 /]# service heartbeat start
  2. logd is already running
  3. Starting High-Availability services:
  4. 2012/03/14_21:36:50 INFO:Resource is stopped
  5. [FAILED]
  6. heartbeat[6579]: 2012/03/14_21:36:50 ERROR: Client child command [/usr/lib/heartbeat/ipfail] is not executable
  7. heartbeat[6579]: 2012/03/14_21:36:50 ERROR: Heartbeat not started: configuration error.
  8. heartbeat[6579]: 2012/03/14_21:36:50 ERROR: Configuration error, heartbeat not started.
如果发生这个问题,先查看你的系统是32还是64位的,如果是64位的,则在ha.cf 里respawn hacluster /usr/lib/heartbeat/ipfail吧这个lib改成lib64;32位的不变。 启动之后,进入mysql,建立数据库db,然后建立表t,插入数据

  1. [root@test6 resource.d]# mysql
  2. Welcome to the MySQL monitor.Commands end with ; or \g.
  3. Your MySQL connection id is 2
  4. Server version: 5.0.95 Source distribution
  5. Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  6. Oracle is a registered trademark of Oracle Corporation and/or its
  7. affiliates. Other names may be trademarks of their respective
  8. owners.
  9. Type 'help; ' or '\h' for help. Type '\c' to clear the current input statement.
  10. mysql> show databases;
  11. +--------------------+
  12. | Database|
  13. +--------------------+
  14. | information_schema |
  15. | 2051|
  16. | lost+found|
  17. | mysql|
  18. | test|
  19. +--------------------+
  20. 5 rows in set (0.04 sec)
  21. mysql> create database db;
  22. Query OK, 1 row affected (0.01 sec)
  23. mysql> use db
  24. Database changed
  25. mysql> create table t (id int(10),name char(10));
  26. Query OK, 0 rows affected (0.05 sec)
  27. mysql> insert into t values(001,"test1"),(002,"test2");
  28. Query OK, 2 rows affected (0.00 sec)
  29. Records: 2Duplicates: 0Warnings: 0
  30. mysql> select * from t;
  31. +------+----------+
  32. | id| name|
  33. +------+----------+
  34. |1 | test1|
  35. |2 | test2 |
  36. +------+----------+
  37. 2 rows in set (0.00 sec)
  38. mysql> exit
  39. Bye
之后停止heartbeat,查看其它节点(test7)里是否有mysql的数据

  1. [root@test6 /]# service heartbeat stop
drbd已经变为从了,drbd1已经从database里卸载了

  1. [root@test6 /]# cat /proc/drbd
  2. version: 8.3.12 (api:88/proto:86-96)
  3. GIT-hash: e2a8ef4656be026bbae540305fcb998a5991090f build by mockbuild@builder10.centos.org, 2012-01-28 13:52:25
  4. 1: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r-----
  5. ns:712 nr:316 dw:972 dr:6142 al:8 bm:3 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
  6. [root@test6 /]# df -h
  7. FilesystemSizeUsed Avail Use% Mounted on
  8. /dev/sda3375G2.9G353G1% /
  9. /dev/sda1122M18M98M16% /boot
  10. tmpfs2.0G02.0G0% /dev/shm
在test7里查看drbd是否为主,drbd1是否装载了database

  1. [root@test7 /]# cat /proc/drbd
  2. version: 8.3.12 (api:88/proto:86-96)
  3. GIT-hash: e2a8ef4656be026bbae540305fcb998a5991090f build by mockbuild@builder10.centos.org, 2012-01-28 13:52:25
  4. 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
  5. ns:316 nr:712 dw:1028 dr:3174 al:5 bm:3 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
  6. [root@test7 /]# df -h
  7. FilesystemSizeUsed Avail Use% Mounted on
  8. /dev/sda2349G3.9G327G2% /
  9. /dev/sda8122M18M98M16% /boot
  10. tmpfs2.0G02.0G0% /dev/shm
  11. /dev/drbd12.6G89M2.3G4% /database
从上面可以看到,test7已经变为主,drbd1已经挂载到了database了 进入mysql里查看db数据库、t表是否已交传过来

  1. [root@test7 /]# mysql
  2. Welcome to the MySQL monitor.Commands end with ; or \g.
  3. Your MySQL connection id is 2
  4. Server version: 5.0.95 Source distribution
  5. Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  6. Oracle is a registered trademark of Oracle Corporation and/or its
  7. affiliates. Other names may be trademarks of their respective
  8. owners.
  9. Type 'help; ' or '\h' for help. Type '\c' to clear the current input statement.
  10. mysql> show databases;
  11. +--------------------+
  12. | Database|
  13. +--------------------+
  14. | information_schema |
  15. | 2051|
  16. | db|
  17. | lost+found|
  18. | mysql|
  19. | test|
  20. +--------------------+
  21. 6 rows in set (0.04 sec)
  22. mysql> use db;
  23. Reading table information for completion of table and column names
  24. You can turn off this feature to get a quicker startup with -A
  25. Database changed
  26. mysql> select * from t;
  27. +------+----------+
  28. | id| name|
  29. +------+----------+
  30. |1 | test1|
  31. |2 | test2 |
  32. +------+----------+
  33. 2 rows in set (0.00 sec)
可以看到mysql已经收到了数据。这样我们的drbd+heartbeat+mysql已经实现了高可用的mysql数据库了。 注意:由于本文内容过多,超出了8万字限制,所以分出2章来描述,下面是第二章的地址:http://dl528888.blog.51cto.com/2382721/835339

    推荐阅读