05月27, 2016

网站部署多服务器实战 —— MySQL 主从复制

由于 Steven's Club 并不是完全由静态网页组成的,经 FireKylin 作者提醒,现已关闭了 CDN 的静态化网页。但这样 CDN 服务器每一次都要回源,对于境外用户来说访问速度并不是那么理想,毕竟还是经过了一堵墙。正好 32service Team 有一组海外服务器,我就架设了一台从服务器在海外,再通过 CDN 向境外的用户加速。

所以现在 Steven's Club 是:

  • 国内用户:用户 > UPYUN CDN > 腾讯云
  • 境外用户:用户 > UPYUN CDN > Vultr (正考虑对境外用户改用其他 CDN )

对于动态网页来说,访问最多的就是数据库了。数据库的连接速度能直接体现在网页的加载速度上。所以不能只是把数据库放在国内的服务器上,境外服务器也要有一个。但如果是完全两个独立的网站,我每一次发布文章都需要发布两次,很不优雅。所以我选择的是设置一个主数据库,一个从数据库。从数据库只能读,它可以实时跟主数据库同步数据。我目前采用的是境外服务器作为从服务器,自动向国内服务器同步数据。

部署主从数据库的大致流程:

  • 主从服务器放行 3306 端口
  • 配置主服务器 my.cnf
  • 配置主服务器的从服务器复制用户
  • 对主数据库进行锁表
  • 导出主服务器数据库
  • 导入数据到从数据库
  • 配置从服务器 my.cnf
  • 配置从服务器 slave
  • 对 salve status 验证
  • 对主数据库进行解锁

所以这是一个挺需要耐心的过程 ...

我们现在正式开始:

假设主服务器 IP 是:192.168.1.2 ; 从服务器 IP 是:192.168.1.3

主从服务器放行 3306 端口

这里以 Ubuntu 为例:

执行 vim /etc/iptables.rules 添加一下内容:

-A INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT

执行iptables-restore < /etc/iptables.rules 使防火墙规则生效。

可以执行 iptables -L -n 查看规则是否生效。

配置主数据库 my.cnf

编辑主 MySQL 服务器的 MySQL 配置文件 vim /etc/my.cnf ,在 [mysqld] 下面添加以下参数:

log-bin=mysql-bin  //开启 MySQL 二进制日志
server-id=1  //服务器 ID 不能重复
binlog-do-db=steven  //需要做主从备份的数据库名字
expire-logs-days = 7  //只保留7天的二进制日志,以防磁盘被日志占满

配置主服务器的从服务器复制用户

登录 MySQL 命令行:mysql -u root -p 执行:

GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO '帐号'@'从服务器IP' IDENTIFIED BY '密码';

例如:帐号是 32ph,密码是 123,IP 是 192.168.1.3,则执行代码为:

GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO '32ph'@'192.168.1.3' IDENTIFIED BY '123';

退出 MySQL 命令行,执行 service mysqld restart 重启 MySQL ,让配置生效。

对主数据库进行锁表

我推荐在部署主从服务器的时候选择一个网站少人访问的时间段,并且让网站进入维护模式。

同样的,登录 MySQL 命令行,执行 FLUSH TABLES WITH READ LOCK; 进行锁表。

导出主服务器数据库

在 SSH 直接执行 mysqldump -u用户名 -p密码 数据库名 > 数据库名.sql 即可导出。

导入数据到从数据库

当我们把 .sql 文件复制到从服务器后,登录 MySQL 命令行。

先新建表:mysql > create database abc;

选中表:mysql > use abc;

设置数据库编码:mysql > set names utf8;

导入 .sql 文件:mysql > source /home/abc/abc.sql;

配置从服务器 my.cnf

编辑 从 MySQL 服务器的 MySQL 配置文件 vim /etc/my.cnf ,在 [mysqld] 下面添加以下参数:

server-id=2 //服务器 ID 不能重复

执行 service mysqld restart 重启 MySQL ,让配置生效。

配置从服务器 slave

主服务器登录 MySQL 命令行,执行:

mysql > show master status;

就会出现一个类似这样的表格:

+------------------+----------+--------------+------------------+  
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |  
+------------------+----------+--------------+------------------+  
| mysql-bin.000020 |      196 |              |                  |  
+------------------+----------+--------------+------------------+

我们记录好 FilePosition 的值,在接下来会用到。(如果之前不进行锁表,那么这两个数值会随着数据写入而改变)

从服务器登录 MySQL 命令行,执行:

mysql > change master to master_host='192.168.1.2',master_user='slave_account',master_password='123456',master_log_file='mysql-bin.000020',master_log_pos=196;

自行对应修改上面 master_host master_user master_password master_password master_log_pos 的值。

对 salve status 验证

在从服务器登录 MySQL 命令行,执行:

mysql > show slave status\G;

出现:

Slave_IO_State: Waiting for master to send event  
Master_Host: 192.168.1.2  
Master_User: slave_account  
Master_Port: 3306  
Connect_Retry: 60  
Master_Log_File: mysql-bin.000020  
Read_Master_Log_Pos: 196  
Relay_Log_File: vicky-relay-bin.000002  
Relay_Log_Pos: 253  
Relay_Master_Log_File: mysql-bin.000009  
Slave_IO_Running: Yes  
Slave_SQL_Running: Yes  
Replicate_Do_DB:  
Replicate_Ignore_DB:  
...

其中 Slave_IO_Running Slave_SQL_Running 都为 Yes 则代表成功了 ~

对主数据库进行解锁

在主服务器登录 MySQL 命令行,执行: mysql > unlock tables; 即可恢复写入。

一些有用的参数

主服务器:

# 不同步哪些数据库  
binlog-ignore-db = mysql  
binlog-ignore-db = test  
binlog-ignore-db = information_schema  

# 只同步哪些数据库,除此之外,其他不同步  
binlog-do-db = game  

# 日志保留时间  
expire_logs_days = 10  

# 控制binlog的写入频率。每执行多少次事务写入一次  
# 这个参数性能消耗很大,但可减小MySQL崩溃造成的损失  
sync_binlog = 5  

# 日志格式,建议mixed  
# statement 保存SQL语句  
# row 保存影响记录数据  
# mixed 前面两种的结合  
binlog_format = mixed

从服务器:

# 停止主从同步  
mysql > stop slave;  

# 连接断开时,重新连接超时时间  
mysql > change master to master_connect_retry=50;  

# 开启主从同步  
mysql > start slave;

本文链接:https://g.32ph.com/post/deployment-multi-server-mysql.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。