用 VPS 给博客做镜像

对于一个每日 PV 不超过1万的小博客来说,性能不是问题,一般的 VPS 都可以搞定,稳定性远比性能要重要。服务器 down 掉,会导致博客不能访问,不能更新,长时间 down 的话会失去读者,影响自己的写作计划/情绪,影响pagerank等等。前段时间 Hyperv 报漏洞,导致 FsckVPS 的很多客户丢失重要数据,长时间都不能恢复。小博客/网站的性能不是那么重要,每天没有那么多的访问压力。

为了给博客增加可靠性,给博客做个简单镜像是必要的,幸运的是我们的要求不高,不需要那些什么实时热备份,均衡负载,透明切换等高科技,只需要每隔一段时间同步一下博客以及数据库就可以了,很少有人能坚持每天写一篇博客,能每天写两篇就算牛博了,所以每天同步一次就够了。这里将讨论如何用 rsyn,ssh 和 mysqldump 来同步博客和数据库。

约定

为了更好的描述细节,这里作以下约定:

主服务器:blog.vpsee.com
备份服务器:mirror.vpsee.com
博客文件都存放在:/var/www/
数据库:MySQL

在 mirror.vpsee.com 进行同步操作,每隔一段时间同步 blog.vpsee.com 上的博客数据和数据库。

2台服务器互相访问

要想同步操作自动化,首先得让 mirror 服务器能直接从 blog 服务器上拷贝,不需要输入密码等信息,不需要人工干预,这个可以通过 ssh keys 来解决。用 root 安全登录 VPS 的方法一文提到了如何不输入密码进行远程访问的方法。这里再提一下:

1、在 mirror.vpsee.com 上创建一对 ssh keys:

ssh-keygen -t dsa

按回车接受默认文件名,得到 2 个文件:id_dsa 和 id_dsa.pub,前一个是 private key,后一个是 public key。注意:创建 key 的时候会提示输入 passphrase,直接回车不要输入任何 passphrase,这点很重要,将保证今后同步时不需要人工输入 passphrase。

2、保护好生成的 private key,不要让外界访问到。

3、在 blog.vpsee.com 上创建一个 /root/.ssh/authorized_keys 文件,把 mirror.vpsee.com 上生成的publice key(id_dsa.pub)的内容 copy+paste 到 blog.vpsee.com 的 authorized_keys 里,完整 copy,不能有空格/空行。

4、在 blog.vpsee.com上 禁止 root 直接 ssh 登录,修改 /etc/ssh/sshd_config,加上/修改这一行:

# vi /etc/ssh/sshd_config

PermitRootLogin without-password

5、重启 sshd

/etc/init.d/sshd restart

在FreeBSD上:

/etc/rc.d/sshd restart

6、安装 rsync
检查一下系统有没有安装 rsync,没有的话就安装:

# whereis rsync

# yum install rsync

7、上述操作是在 mirror.vpsee.com 上执行的,现在反过来需要在 blog.vpsee.com 上重复步骤1—6,把mirror 和 blog反过来在 blog 上生成 ssh keys 就可以了。因为下面的同步脚本会在 blog.vpsee.com 上运行命令拷贝文件到 mirror.vpsee.com.

同步博客

登录 mirror.vpsee.com 进行同步操作,用 rsync 同步博客文件夹。–delete 选项是指在 blog.vpsee.com 上删除文件也同时在 mirror.vpsee.com 上删除。–exclude 选项是指把选定的文件/文件夹排除在外不参加同步。最后注意把 /var/www/ 及其子目录所有文件的所有者改成 web 服务器用户。

# rsync -avz --delete -e "ssh" [email protected]:/var/www/ /var/www/
receiving file list ... done
access_blog1.log
access_blog2.log

sent 27784 bytes  received 54809 bytes  23598.00 bytes/sec
total size is 51414782  speedup is 622.51

chown -R nginx:nginx /var/www/

同步数据库

登录 mirror.vpsee.com 后在 mirror 上操作,远程执行 mysqldump 命令把 blog 的数据库备份出来,打包压缩,然后拷贝到 mirror.vpsee.com 上。

# ssh [email protected] "mysqldump -u root -p'blog数据库密码' 
--all-databases | gzip > /tmp/db.gz;
scp /tmp/db.gz [email protected]:/tmp/"

在mirror.vpsee.com 上解开数据文件,并且导入 mirror 的数据库。

# gunzip -c /tmp/db.gz | mysql -u root -p'mirror数据库密码'"

自动化

为了让以上操作自动执行,先做个同步的脚本:

# vi /root/sync.sh

#!/bin/bash
main="blog.vpsee.com"
mirror="mirror.vpsee.com"
rsync -avz --delete -e "ssh" [email protected]:/var/www/ /var/www/;
ssh [email protected] "mysqldump -u root -p'blog数据库密码' 
--all-databases | gzip > /tmp/db.gz; 
scp /tmp/db.gz [email protected]:/tmp/";
gunzip -c /tmp/db.gz | mysql -u root -p'mirror数据库密码';

别忘了把 sync.sh 改成可执行文件:

# chmod 755 /root/sync.sh

在 mirror.vpsee.com上 创建一个 cron job 每天凌晨2点执行同步:

# crontab -e

* /2 * * * root /root/sync.sh

如果使用的是 Linux 的话,可以直接拷贝 sync.sh 到 /etc/cron.daily/:

# cp /root/sync.sh /etc/cron.daily/

大功告成,以后只要更改了主服务器(blog.vpsee.com),备份服务器(mirror.vpsee.com)每天会自动去主服务器那里同步复制。

修改 DNS

现在有了一个博客的完全镜像,如果发现主服务器不能用了,及时把 DNS 指向备用服务器就可以了。这种方法要需要人工修改 DNS 记录,不高明,不过对于小博客来说总比 down 几天要好多了,算上主服务器 down 的几率,这个方案还凑合。

更自动的方法是做 DNS round robin,一个域名指向多个 IP(主服务器和备份服务器),一个 IP 不能访问了,就访问另外一个。

更更好的方法是做个小 cluster,load balance + redundancy,不过这 mysql 的 redundancy 功能只能在一个网段做,这意味着2台服务器的小 cluster 必须在一个网段里,如果用 VPS 的话,这就只能用一家 VPS 公司的产品(保证2个 VPS 在同一网段内),如果依赖单一公司,那么公司倒闭或者服务器报漏洞,数据丢失,VPS 不能用怎么办?VPSee 建议博客或者中小规模的网站使用不同 VPS 服务商提供的产品,不要绑在单一公司上,尤其在 web hosting 这个行业,变化太快,服务器 down 掉,服务商跑路/倒闭太正常了。

评论 (5 Comments)

  1. 同一个网段的问题,可以用vpn解决吧

  2. MySQL那里的话,用Master-Slave来搞还简单很多,我在这里废话了一下:http://starfly.me/mysql-n机热备.jsp

  3. 用 master-slave 来弄博客有点太夸张了吧,master-slave 可用在中大型网站上分担数据库压力,把读操作分散到2个数据库上可以减轻数据库负担。

  4. 学习了,试一下利用下多余的vps。

  5. 晕,禁止 root 直接 ssh 登录。直接导致ssh登录不上vps,还好有Serial Console这个东西,不然就惨了。

发表评论