扫码订阅《 》或入驻星球,即可阅读文章!

GOLANG ROADMAP

阅读模式

  • 沉浸
  • 自动
  • 日常
首页
Go友会
  • 城市
  • 校园
Go学院
  • Go小课
  • Go小考
  • Go实战
  • 精品课
Go求职
  • 求职辅导🔥
  • Offer收割社群
  • 企业题库
  • 面试宝典
Go宝典
  • 在线宝典
  • B站精选
  • 推荐图书
  • 每日博文
Go仓库
实验区
  • Go周边
  • Go下载
  • Go月刊
消息
更多
  • 用户中心

    • 我的信息
    • 推广返利
  • 玩转星球

    • 星球介绍
    • 角色体系
    • 星主权益
  • 支持与服务

    • 联系星主
    • 成长记录
    • 常见问题
    • 吐槽专区
  • 合作交流

    • 渠道合作
    • 课程入驻
    • 友情链接
author-avatar

GOLANG ROADMAP


首页
Go友会
  • 城市
  • 校园
Go学院
  • Go小课
  • Go小考
  • Go实战
  • 精品课
Go求职
  • 求职辅导🔥
  • Offer收割社群
  • 企业题库
  • 面试宝典
Go宝典
  • 在线宝典
  • B站精选
  • 推荐图书
  • 每日博文
Go仓库
实验区
  • Go周边
  • Go下载
  • Go月刊
消息
更多
  • 用户中心

    • 我的信息
    • 推广返利
  • 玩转星球

    • 星球介绍
    • 角色体系
    • 星主权益
  • 支持与服务

    • 联系星主
    • 成长记录
    • 常见问题
    • 吐槽专区
  • 合作交流

    • 渠道合作
    • 课程入驻
    • 友情链接
  • Go语言Web编程

    • 课程介绍
  • Web基础

  • 表单

  • 访问数据库

  • session和数据存储

  • 文本处理

  • Web服务

  • 安全与加密

  • 国际化和本地化

  • 错误处理,调试和测试

  • 部署与维护

    • 第1节:部署与维护
    • 第2节:应用日志
    • 第3节:网站错误处理
    • 第4节:应用部署
    • 第5节:备份和恢复
    • 第6节:小结
  • 如何设计一个Web框架

  • 扩展Web框架

扫码订阅《 》或入驻星球,即可阅读文章!

第5节:备份和恢复


ASTA谢

这小节我们要讨论应用程序管理的另一个方面:生产服务器上数据的备份和恢复。我们经常会遇到生产服务器的网络断了、硬盘坏了、操作系统崩溃、或者数据库不可用了等各种异常情况,所以维护人员需要对生产服务器上的应用和数据做好异地灾备,冷备热备的准备。在接下来的介绍中,讲解了如何备份应用、如何备份/恢复 Mysql 数据库和 redis 数据库。

# 应用备份

在大多数集群环境下,Web 应用程序基本不需要备份,因为这个其实就是一个代码副本,我们在本地开发环境中,或者版本控制系统中已经保持这些代码。但是很多时候,一些开发的站点需要用户来上传文件,那么我们需要对这些用户上传的文件进行备份。目前其实有一种合适的做法就是把和网站相关的需要存储的文件存储到云储存,这样即使系统崩溃,只要我们的文件还在云存储上,至少数据不会丢失。

如果我们没有采用云储存的情况下,如何做到网站的备份呢?这里我们介绍一个文件同步工具 rsync:rsync 能够实现网站的备份,不同系统的文件的同步,如果是 windows 的话,需要 windows 版本 cwrsync。

# rsync 安装

rysnc 的官方网站:http://rsync.samba.org/ 可以从上面获取最新版本的源码。当然,因为 rsync 是一款非常有用的软件,所以很多 Linux 的发行版本都将它收录在内了。

软件包安装

# sudo apt-get  install  rsync  注:在debian、ubuntu 等在线安装方法;
# yum install rsync    注:Fedora、Redhat、CentOS 等在线安装方法;
# rpm -ivh rsync       注:Fedora、Redhat、CentOS 等rpm包安装方法;

其它 Linux 发行版,请用相应的软件包管理方法来安装。源码包安装

tar xvf  rsync-xxx.tar.gz
cd rsync-xxx
./configure --prefix=/usr  ;make ;make install   注:在用源码包编译安装之前,您得安装 gcc 等编译工具才行;

# rsync 配置

rsync 主要有以下三个配置文件 rsyncd.conf(主配置文件)、rsyncd.secrets(密码文件)、rsyncd.motd (rysnc 服务器信息)。

关于这几个文件的配置大家可以参考官方网站或者其他介绍 rsync 的网站,下面介绍服务器端和客户端如何开启

  • 服务端开启:

      #/usr/bin/rsync --daemon  --config=/etc/rsyncd.conf
    

    --daemon 参数方式,是让 rsync 以服务器模式运行。把 rsync 加入开机启动

      echo 'rsync --daemon' >> /etc/rc.d/rc.local
    

    设置 rsync 密码

      echo '你的用户名:你的密码' > /etc/rsyncd.secrets
      chmod 600 /etc/rsyncd.secrets
    
  • 客户端同步:

    客户端可以通过如下命令同步服务器上的文件:

      rsync -avzP  --delete  --password-file=rsyncd.secrets   用户名@192.168.145.5::www /var/rsync/backup
    

    这条命令,简要的说明一下几个要点:

    1. -avzP 是啥,读者可以使用 --help 查看
    2. --delete 是为了比如 A 上删除了一个文件,同步的时候,B 会自动删除相对应的文件
    3. --password-file 客户端中 /etc/rsyncd.secrets 设置的密码,要和服务端的 /etc/rsyncd.secrets 中的密码一样,这样 cron 运行的时候,就不需要密码了
    4. 这条命令中的 "用户名" 为服务端的 /etc/rsyncd.secrets中的用户名
    5. 这条命令中的 192.168.145.5 为服务端的 IP 地址
    6. ::www,注意是2个 : 号,www 为服务端的配置文件 /etc/rsyncd.conf 中 的 [www],意思是根据服务端上的 /etc/rsyncd.conf 来同步其中的 [www] 段内容,一个 : 号的时候,用于不根据配置文件,直接同步指定目录。

    为了让同步实时性,可以设置 crontab,保持 rsync 每分钟同步,当然用户也可以根据文件的重要程度设置不同的同步频率。

# MySQL 备份

应用数据库目前还是 MySQL 为主流,目前 MySQL 的备份有两种方式:热备份和冷备份,热备份目前主要是采用 master/slave 方式(master/slave 方式的同步目前主要用于数据库读写分离,也可以用于热备份数据),关于如何配置这方面的资料,大家可以找到很多。冷备份的话就是数据有一定的延迟,但是可以保证该时间段之前的数据完整,例如有些时候可能我们的误操作引起了数据的丢失,那么 master/slave 模式是无法找回丢失数据的,但是通过冷备份可以部分恢复数据。

冷备份一般使用 shell 脚本来实现定时备份数据库,然后通过上面介绍 rsync 同步非本地机房的一台服务器。

下面这个是定时备份 mysql 的备份脚本,我们使用了 mysqldump 程序,这个命令可以把数据库导出到一个文件中。

#!/bin/bash

# 以下配置信息请自己修改
mysql_user="USER" # MySQL备份用户
mysql_password="PASSWORD" # MySQL备份用户的密码
mysql_host="localhost"
mysql_port="3306"
mysql_charset="utf8" #MySQL编码
backup_db_arr=("db1" "db2") # 要备份的数据库名称,多个用空格分开隔开 如("db1" "db2" "db3")
backup_location=/var/www/mysql  #备 份数据存放位置,末尾请不要带"/", 此项可以保持默认,程序会自动创建文件夹
expire_backup_delete="ON" # 是否开启过期备份删除 ON为开启 OFF为关闭
expire_days=3 # 过期时间天数 默认为三天,此项只有在 expire_backup_delete 开启时有效

# 本行开始以下不需要修改
backup_time=`date +%Y%m%d%H%M`  # 定义备份详细时间
backup_Ymd=`date +%Y-%m-%d` # 定义备份目录中的年月日时间
backup_3ago=`date -d '3 days ago' +%Y-%m-%d` # 3 天之前的日期
backup_dir=$backup_location/$backup_Ymd  # 备份文件夹全路径
welcome_msg="Welcome to use MySQL backup tools!" # 欢迎语

# 判断 MYSQL 是否启动, mysql 没有启动则备份退出
mysql_ps=`ps -ef |grep mysql |wc -l`
mysql_listen=`netstat -an |grep LISTEN |grep $mysql_port|wc -l`
if [ [$mysql_ps == 0] -o [$mysql_listen == 0] ]; then
        echo "ERROR:MySQL is not running! backup stop!"
        exit
else
        echo $welcome_msg
fi

# 连接到 mysql 数据库,无法连接则备份退出
mysql -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password <<end
use mysql;
select host,user from user where user='root' and host='localhost';
exit
end

flag=`echo $?`
if [ $flag != "0" ]; then
        echo "ERROR:Can't connect mysql server! backup stop!"
        exit
else
        echo "MySQL connect ok! Please wait......"
        # 判断有没有定义备份的数据库,如果定义则开始备份,否则退出备份
        if [ "$backup_db_arr" != "" ];then
                #dbnames=$(cut -d ',' -f1-5 $backup_database)
                #echo "arr is (${backup_db_arr[@]})"
                for dbname in ${backup_db_arr[@]}
                do
                        echo "database $dbname backup start..."
                        `mkdir -p $backup_dir`
                        `mysqldump -h$mysql_host -P$mysql_port -u$mysql_user -p$mysql_password $dbname --default-character-set=$mysql_charset | gzip > $backup_dir/$dbname-$backup_time.sql.gz`
                        flag=`echo $?`
                        if [ $flag == "0" ];then
                                echo "database $dbname success backup to $backup_dir/$dbname-$backup_time.sql.gz"
                        else
                                echo "database $dbname backup fail!"
                        fi
                        
                done
        else
                echo "ERROR:No database to backup! backup stop"
                exit
        fi
        # 如果开启了删除过期备份,则进行删除操作
        if [ "$expire_backup_delete" == "ON" -a  "$backup_location" != "" ];then
                 #`find $backup_location/ -type d -o -type f -ctime +$expire_days -exec rm -rf {} \;`
                 `find $backup_location/ -type d -mtime +$expire_days | xargs rm -rf`
                 echo "Expired backup data delete complete!"
        fi
        echo "All database backup success! Thank you!"
        exit
fi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

修改 shell 脚本的属性: chmod 600 /root/mysql_backup.sh chmod +x /root/mysql_backup.sh

设置好属性之后,把命令加入 crontab,我们设置了每天 00:00 定时自动备份,然后把备份的脚本目录 /var/www/mysql 设置为 rsync 同步目录。

00 00 * * * /root/mysql_backup.sh
1

# MySQL 恢复

前面介绍 MySQL 备份分为热备份和冷备份,热备份主要的目的是为了能够实时的恢复,例如应用服务器出现了硬盘故障,那么我们可以通过修改配置文件把数据库的读取和写入改成 slave,这样就可以尽量少时间的中断服务。

但是有时候我们需要通过冷备份的 SQL 来进行数据恢复,既然有了数据库的备份,就可以通过命令导入:

mysql -u username -p databse < backup.sql
1

可以看到,导出和导入数据库数据都是相当简单,不过如果还需要管理权限,或者其他的一些字符集的设置的话,可能会稍微复杂一些,但是这些都是可以通过一些命令来完成的。

# redis 备份

redis 是目前我们使用最多的 NoSQL,它的备份也分为两种:热备份和冷备份,redis 也支持 master/slave 模式,所以我们的热备份可以通过这种方式实现,相应的配置大家可以参考官方的文档配置,相当的简单。我们这里介绍冷备份的方式:redis 其实会定时的把内存里面的缓存数据保存到数据库文件里面,我们备份只要备份相应的文件就可以,就是利用前面介绍的 rsync 备份到非本地机房就可以实现。

# redis 恢复

redis 的恢复分为热备份恢复和冷备份恢复,热备份恢复的目的和方法同 MySQL 的恢复一样,只要修改应用的相应的数据库连接即可。

但是有时候我们需要根据冷备份来恢复数据,redis 的冷备份恢复其实就是只要把保存的数据库文件 copy 到 redis 的工作目录,然后启动 redis 就可以了,redis 在启动的时候会自动加载数据库文件到内存中,启动的速度根据数据库的文件大小来决定。

# 小结

本小节介绍了我们的应用部分的备份和恢复,即如何做好灾备,包括文件的备份、数据库的备份。同时也介绍了使用 rsync 同步不同系统的文件,MySQL 数据库和 redis 数据库的备份和恢复,希望通过本小节的介绍,能够给作为开发的你对于线上产品的灾备方案提供一个参考方案。

  • 应用备份
  • rsync 安装
  • rsync 配置
  • MySQL 备份
  • MySQL 恢复
  • redis 备份
  • redis 恢复
  • 小结