双机高可用负载均衡MySQL(读写分离主从自动切换)架构设计

Posted 竹山一叶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双机高可用负载均衡MySQL(读写分离主从自动切换)架构设计相关的知识,希望对你有一定的参考价值。

架构简介

 

前几天网友来信说帮忙实现这样一个架构:只有两台机器,需要实现其中一台死机之后另一台能接管这台机器的服务,并且在两台机器正常服务时,两台机器都能用上。于是设计了如下的架构。
双机ha架构图
此架构主要是由keepalived实现双机高可用,维护了一个外网VIP,一个内网VIP。正常情况时,外网VIP和内网VIP都绑定在server1服务器,web请求发送到server1的nginx,nginx对于静态资源请求就直接在本机检索并返回,对于php的动态请求,则负载均衡到server1和server2。对于SQL请求,会将此类请求发送到Atlas mysql中间件,Atlas接收到请求之后,把涉及写操作的请求发送到内网VIP,读请求操作发送到mysql从,这样就实现了读写分离。

 

当主服务器server1宕机时,keepalived检测到后,立即把外网VIP和内网VIP绑定到server2,并把server2的mysql切换成主库。此时由于外网VIP已经转移到了server2,web请求将发送给server2的nginx。nginx检测到server1宕机,不再把请求转发到server1的php-fpm。之后的sql请求照常发送给本地的atlas,atlas把写操作发送给内网VIP,读操作发送给mysql从,由于内网VIP已经绑定到server2了,server2的mysql同时接受写操作和读操作。

 

当主服务器server1恢复后,server1的mysql自动设置为从,与server2的mysql主同步。keepalived不抢占server2的VIP,继续正常服务。

 

架构要求

 

要实现此架构,需要三个条件:

  • 1、服务器可以设置内网IP,并且设置的内网IP互通;
  • 2、服务器可以随意绑定IDC分配给我们使用的外网IP,即外网IP没有绑定MAC地址;
  • 3、MySQL服务器支持GTID,即MySQL-5.6.5以上版本。

 

环境说明

 

server1

  • eth0: 10.96.153.110(对外IP)
  • eth1: 192.168.1.100(对内IP)

server2

  • eth0: 10.96.153.114(对外IP)
  • eth1: 192.168.1.101(对内IP)

系统都是CentOS-6。

 

对外VIP: 10.96.153.239
对内VIP: 192.168.1.150

 

hosts设置

 

/etc/hosts:
192.168.1.100 server1
192.168.1.101 server2

 

Nginx PHP MySQL Memcached安装

 

这几个软件的安装推荐使用EZHTTP来完成。

 

解决session共享问题

 

php默认的session存储是在/tmp目录下,现在我们是用两台服务器作php请求的负载,这样会造成session分布在两台服务器的/tmp目录下,导致依赖于session的功能不正常。我们可以使用memcached来解决此问题。
上一步我们已经安装好了memcached,现在只需要配置php.ini来使用memcached,配置如下,打开php.ini配置文件,修改为如下两行的值:

  1. session.save_handler = memcache
  2. session.save_path = "tcp://192.168.1.100:11211,tcp://192.168.1.101:11211"

之后重启php-fpm生效。

 

Nginx配置

 

Server1配置

  1. http {
  2. [...]
  3.     upstream php-server {
  4.            server 192.168.1.101:9000;
  5.            server 127.0.0.1:9000;
  6.            keepalive 100;
  7.     }
  8. [...]
  9.  server {
  10.     [...]
  11.         location ~ \\.php$ {
  12.                         fastcgi_pass   php-server;
  13.                         fastcgi_index  index.php;
  14.                         fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
  15.                         include        fastcgi_params;
  16.         }
  17.     [...]
  18.  }
  19. [...]
  20. }

 

Server2配置

  1. http {
  2. [...]
  3.     upstream php-server {
  4.            server 192.168.1.100:9000;
  5.            server 127.0.0.1:9000;
  6.            keepalive 100;
  7.     }
  8. [...]
  9.  server {
  10.     [...]
  11.         location ~ \\.php$ {
  12.                         fastcgi_pass   php-server;
  13.                         fastcgi_index  index.php;
  14.                         fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
  15.                         include        fastcgi_params;
  16.         }
  17.     [...]
  18.  }
  19. [...]
  20. }

这两个配置主要的作用是设置php请求的负载均衡。

 

MySQL配置

 

mysql util安装

我们需要安装mysql util里的主从配置工具来实现主从切换。

  1. cd /tmp
  2. wget http://dev.mysql.com/get/Downloads/MySQLGUITools/mysql-utilities-1.5.3.tar.gz
  3. tar xzf mysql-utilities-1.5.3.tar.gz
  4. cd mysql-utilities-1.5.3
  5. python setup.py build
  6. python setup.py install

 

mysql my.cnf配置

server1:

  1. [mysql]
  2. [...]
  3. protocol=tcp
  4. [...]
  5. [...]
  6. [mysqld]
  7. [...]
  8. # BINARY LOGGING #
  9. log-bin = /usr/local/mysql/data/mysql-bin
  10. expire-logs-days = 14
  11. binlog-format= row
  12. log-slave-updates=true
  13. gtid-mode=on
  14. enforce-gtid-consistency =true
  15. master-info-repository=TABLE
  16. relay-log-info-repository=TABLE
  17. server-id=1
  18. report-host=server1
  19. report-port=3306
  20. [...]

server2:

  1. [mysql]
  2. [...]
  3. protocol=tcp
  4. [...]
  5. [mysqld]
  6. [...]
  7. # BINARY LOGGING #
  8. log-bin = /usr/local/mysql/data/mysql-bin
  9. expire-logs-days = 14
  10. binlog-format= row
  11. log-slave-updates=true
  12. gtid-mode=on
  13. enforce-gtid-consistency =true
  14. master-info-repository=TABLE
  15. relay-log-info-repository=TABLE
  16. server-id=2
  17. report-host=server2
  18. report-port=3306
  19. [...]

这两个配置主要是设置了binlog和启用gtid-mode,并且需要设置不同的server-id和report-host。

 

开放root帐号远程权限

我们需要在两台mysql服务器设置root帐号远程访问权限。

  1. mysql> grant all on *.* to \'root\'@\'192.168.1.%\' identified by \'Xp29at5F37\' with grant option;
  2. mysql> grant all on *.* to \'root\'@\'server1\' identified by \'Xp29at5F37\' with grant option;
  3. mysql> grant all on *.* to \'root\'@\'server2\' identified by \'Xp29at5F37\' with grant option;
  4. mysql> flush privileges;

 

设置mysql主从

在任意一台执行如下命令:

  1. mysqlreplicate --master=root:Xp29at5F37@server1:3306 --slave=root:Xp29at5F37@server2:3306 --rpl-user=rpl:o67DhtaW

# master on server1: … connected.
# slave on server2: … connected.
# Checking for binary logging on master…
# Setting up replication…
# …done.

 

显示主从关系

  1. mysqlrplshow --master=root:Xp29at5F37@server1 --discover-slaves-login=root:Xp29at5F37

# master on server1: … connected.
# Finding slaves for master: server1:3306

# Replication Topology Graph
server1:3306 (MASTER)
|
+— server2:3306 – (SLAVE)

 

检查主从状态

  1. mysqlrplcheck --master=root:Xp29at5F37@server1 --slave=root:Xp29at5F37@server2

# master on server1: … connected.
# slave on server2: … connected.
Test Description Status
—————————————————————————
Checking for binary logging on master [pass]
Are there binlog exceptions? [pass]
Replication user exists? [pass]
Checking server_id values [pass]
Checking server_uuid values [pass]
Is slave connected to master? [pass]
Check master information file [pass]
Checking InnoDB compatibility [pass]
Checking storage engines compatibility [pass]
Checking lower_case_table_names settings [pass]
Checking slave delay (seconds behind master) [pass]
# …done.

 

Keepalived配置

 

keepalived安装(两台都装)

  1. yum -y install keepalived
  2. chkconfig keepalived on

 

keepalived配置(server1)

  1. vi /etc/keepalived/keepalived.conf