导读:毋庸置疑,数据备份是网站可持续性运营中至关重要的一个工作,如果还没有做任何备份机制的网站,建议尽早完善,莫要等到追悔莫及。本文将分享一个安全稳定、快速可靠、花费廉价的备份方案。
一、优点分析
张戈博客在 2 年前已经分享过一篇关于网站备份的文章:《Linux/vps 本地七天循环备份和七牛远程备份脚本》,今天将再次结合这个脚本,将网站数据通过阿里云内网备份到阿里云 OSS。
对于阿里云 OSS,想必大家都不会陌生,具体功能、特色这里就不赘述了。而利用阿里云 OSS 备份数据的教程方法,网络上已有不少分享,各种开发语言都有,用起来非常方便。
在我看来,用什么语言都是其次,主要还是看重了阿里云 ECS 到阿里云 OSS 可以走内网,相比我之前分享的备份到七牛的方案,速度更快而且流量免费!
我博客之前一直将数据每周一凌晨备份一份到七牛,也不敢每天都备份,因为备份的时候由于服务器上行带宽只有 1M,就算是切片上传也会导致此时网站访问缓慢,影响蜘蛛抓取!所以,当我看到 OSS 可以走内网时,第一个想到的好处就是速度快,不影响服务器公网带宽,对网站的访问毫无影响,超赞!
因此,只建议部署在阿里云 ECS(9 折优惠码:r9itz9,新购可用)的网站使用 OSS 来备份,其他产品还要走外网备份到 OSS 就得不偿失了,还不如用七牛。
二、准备工作
①、开通 OSS,并创建备份 Bucket
访问阿里云 OSS 控制台,点击开通 OSS,然后新建一个 Bucket(名称自定义),注意选择 ECS 相同的区域(比如青岛的 ECS 我就选择华北 1),并且选择私有读写权限:
②、创建认证密钥
在 OSS 控制台的右侧栏,点击安全令牌,创建用于管理 OSS 的密钥对:
2016-10-29 补充:看到倡萌的实践分享,他遇到从 OSS 界面申请的密钥居然不具备 OSS 访问权限,所以这里也“盗图”补充一下,如果密钥没有权限请如图添加即可:
三、SDK 脚本
我根据 OSS 的帮助文件,选择了适用范围最广的 Python SDK 方案,并且额外加入了断点续传和上传百分比功能,测试成功。
①、环境准备
OSS 的 Python SDK 需要用到 oss2 插件,所以我们先安装一下。
如果服务器上已经安装了 pip 工具,可直接执行如下命令安装 oss2 插件:
pip install oss2
若没有,则复制以下命令行到服务器上执行安装:
cd /tmp wget -O master.zip https://codeload.github.com/aliyun/aliyun-oss-python-sdk/zip/master --no-check-certificate tar zxf master.zip cd aliyun-oss-python-sdk-master && python setup.py install && echo "Oss2 install OK" || \ echo "Oss2 install failed"
②、上传脚本
# -*- coding: utf-8 -*- from __future__ import print_function import os, sys import oss2 # # 百分比显示回调函数 # def percentage(consumed_bytes, total_bytes): if total_bytes: rate = int(100 * (float(consumed_bytes) / float(total_bytes))) print('\r{0}% '.format(rate), end=filePath) sys.stdout.flush() # 脚本需要传入 5 个参数 if ( len(sys.argv) > 5 ): AccessKeyId = sys.argv[1] AccessKeySecret = sys.argv[2] Endpoint = sys.argv[3] Bucket = sys.argv[4] filePath = sys.argv[5] fileName = filePath.split("/")[-1] else: print("Example: %s AccessKeyId AccessKeySecret Endpoint Bucket /data/backup.zip" % sys.argv[0]) exit() # OSS 认证并开始上传 auth = oss2.Auth(AccessKeyId , AccessKeySecret) bucket = oss2.Bucket(auth, Endpoint, Bucket) oss2.resumable_upload(bucket, fileName, filePath, progress_callback=percentage) print('\rUpload %s to OSS Success!' % filePath)
使用方法:将上述代码保存为 oss.upload.py,并上传到服务器,执行如下命令可开始上传文件到 OSS:
python /data/oss.upload.py 认证 ID 认证密钥 oss-cn-qingdao-internal.aliyuncs.com Bucket 名称 /data/zhang.ge_1.zip
其中:
- 1~2 个参数是认证 ID 和认证密钥就是前文创建并备忘的密钥对。
- 第 3 个参数是青岛区域的 OSS 内网地址,其他区域请参考OSS 帮助文档,自行选择。
- 第 4 个参数是前文创建的 Bucket 名称,比如 mybackup1
- 第 5 个参数是要上传的本地文件的绝对路径
③、下载脚本
其实只需要有个上传脚本即可,因为备份文件可直接从 Object 界面下载。不过,为了方便在服务器上直接恢复文件,还是弄了一个下载脚本。
# -*- coding: utf-8 -*- from __future__ import print_function import os, sys import oss2 # # 百分比显示回调函数 # def percentage(consumed_bytes, total_bytes): if total_bytes: rate = int(100 * (float(consumed_bytes) / float(total_bytes))) print('\r{0}% '.format(rate), end=saveFile) sys.stdout.flush() # 至少需要 5 个参数,第六个参数是下载文件的保存路径,若不指定,则保存到脚本所在目录 if ( len(sys.argv) > 5 ): AccessKeyId = sys.argv[1] AccessKeySecret = sys.argv[2] Endpoint = sys.argv[3] Bucket = sys.argv[4] fileName = sys.argv[5] try: saveFile = sys.argv[6] + fileName except: saveFile = './' + fileName else: print("Example: %s AccessKeyId AccessKeySecret Endpoint Bucket backup.zip /data/backup.zip" % sys.argv[0]) exit() auth = oss2.Auth(AccessKeyId , AccessKeySecret) bucket = oss2.Bucket(auth, Endpoint, Bucket) oss2.resumable_download(bucket, fileName, saveFile, store=oss2.ResumableDownloadStore(root='/tmp'), multiget_threshold=20*1024*1024, part_size=10*1024*1024, num_threads=5,progress_callback=percentage) print('\rDownload %s to %s Success!' % ( fileName, saveFile))
使用方法:
将上述代码保存为 oss.download.py,并上传到服务器,执行如下命令就可以下载 OSS 文件到本地:
python /data/oss.download.py 认证 ID 认证密钥 oss-cn-qingdao-internal.aliyuncs.com Bucket 名称 zhang.ge_1.zip /data/zhang.ge_1.zip
其中:
- 1~2 个参数是认证 ID 和认证密钥就是前文创建并备忘的密钥对。
- 第 3 个参数是青岛区域的 OSS 内网地址,其他区域请参考OSS 帮助文档,自行选择。
- 第 4 个参数是前文创建的 Bucket 名称,比如 mybackup1
- 第 5 个参数是存储在 OSS 的文件名称
- 第 6 个参数是保存到本地的文件绝对路径,若不指定则以相同名称保存到脚本相同目录。
好了,以上只是一个上传和下载的脚本,如果你之前已经有了成熟的备份方案,并且本地存储了备份文件,则可以使用上传脚本,结合 crontab 定时上传到 OSS,如果没有请继续往下看。
四、定时备份
有了上传脚本,就可以结合之前张戈博客分享的七天循环备份脚本,实现循环备份到 OSS 了,既安全还节省 OSS 空间。
Ps:实际上,一个 Python 脚本就可以搞定备份压缩和远程上传 OSS 了,但是之前已经有一个现成的 Shell 备份脚本了,我就懒得重复造轮子了!
①、适合 OSS 的七天循环备份脚本
2016 年 12 月 16 日更新:
1、完善 crontab 环境变量,解决定时执行中因 mysqldump 不存在导致备份文件为空的问题;
2、重写 Shell 脚本,功能没什么变化,也就是看得更顺眼一些。
#!/bin/sh ################################################################### # Web Backup version 1.0.3 Author: Jager <[email protected]> # # For more information please visit https://zhang.ge/5111.html # #-----------------------------------------------------------------# # Copyright ©2016 zhang.ge. All rights reserved. # ################################################################### test -f /etc/profile && . /etc/profile >/dev/null 2>&1 baseDir=$(cd $(dirname $0) && pwd) zip --version >/dev/null || yum install -y zip ZIP=$(which zip) TODAY=`date +%u` PYTHON=$(which python) MYSQLDUMP=$(which mysqldump) # 新增的 OSS 上传文件函数,请按照实际情况修改参数! uploadToOSS() { $PYTHON $baseDir/oss.upload.py 认证 KEY 认证密钥 oss-cn-qingdao-internal.aliyuncs.com Bucket 名称 $1 } printHelp() { clear printf ' =====================================Help infomation========================================= 1. Use For Backup database: The $1 must be [db] $2: [domain] $3: [dbname] $4: [mysqluser] $5: [mysqlpassword] $6: [back_path] For example:./backup.sh db zhang.ge zhangge_db zhangge 123456 /home/wwwbackup/zhang.ge 2. Use For Backup webfile: The $1 must be [\file]: $2: [domain] $3: [site_path] $4: [back_path] For example:./backup.sh file zhang.ge /home/wwwroot/zhang.ge /home/wwwbackup/zhang.ge =====================================End of Hlep============================================== ' exit 0 } backupDB() { domain=$1 dbname=$2 mysqluser=$3 mysqlpd=$4 back_path=$5 test -d $back_path || (mkdir -p $back_path || echo "$back_path not found! Please CheckOut Or feedback to zhang.ge..." && exit 2) cd $back_path $MYSQLDUMP -u$mysqluser -p$mysqlpd $dbname --skip-lock-tables --default-character-set=binary >$back_path/$domain\_db_$TODAY\.sql test -f $back_path/$domain\_db_$TODAY\.sql || (echo "MysqlDump failed! Please CheckOut Or feedback to zhang.ge..." && exit 2) $ZIP -Pmypassword -m $back_path/$domain\_db_$TODAY\.zip $domain\_db_$TODAY\.sql && \ uploadToOSS $back_path/$domain\_db_$TODAY\.zip } backupFile() { domain=$1 site_path=$2 back_path=$3 test -d $site_path || (echo "$site_path not found! Please CheckOut Or feedback to zhang.ge..." && exit 2) test -d $back_path || (mkdir -p $back_path || echo "$back_path not found! Please CheckOut Or feedback to zhang.ge..." && exit 2) test -f $back_path/$domain\_$TODAY\.zip && rm -f $back_path/$domain\_$TODAY\.zip $ZIP -Pmypassword -9r $back_path/$domain\_$TODAY\.zip $site_path && \ uploadToOSS $back_path/$domain\_$TODAY\.zip } while [ $1 ]; do case $1 in '--db' | 'db' ) backupDB $2 $3 $4 $5 $6 exit ;; '--file' | 'file' ) backupFile $2 $3 $4 exit ;; * ) printHelp exit ;; esac done printHelp
②、使用方法
将上述代码作如下修改:
I、根据实际情况修改上述代码中的 OSS 上传函数代码,比如密钥对和 Bucket 名称(参考前文)
II、替换代码中的 mypassword 为自己设置的压缩包密码,不修改的话压缩文件解压密码为 mypassword
然后,将代码保存为 backup.sh,上传到服务器(建议存放到和前文 python 脚本的相同目录),比如 /data/backup.sh,最后如下添加定时任务:
#编辑 crontab [root@AlyServer ~]# crontab -e #然后添加如下内容: #备份数据库(参数依次为:db、域名、数据库名称、数据库用户名、对应密码、备份路径) 10 3 * * * bash /data/backup.sh db zhang.ge zhangge root 123456 /home/wwwbackup/zhang.ge >/dev/null 2>&1 #备份网站文件(参数依次为:file、域名、网站根目录、备份路径) 15 3 * * * bash /data/backup.sh file zhang.ge /home/wwwroot/zhang.ge /home/wwwbackup/zhang.ge >/dev/null 2>&1 #按下键盘 esc,输入 :wq 保存 crontab 即可
本文就不赘述 7 天循环备份脚本的功能和更详细的使用方法了,若还是不清楚请参考前文:Linux/vps 本地七天循环备份和七牛远程备份脚本
全部完成后,就能实现本地 7 天循环备份和 OSS 远程备份了!如果,之前已经做了七牛远程备份的可以放心取消了。
在文章的最后,为了方便广大代码小白朋友,特提供本文涉及脚本的打包下载:
折腾吧,骚年!好用的话,有钱的可以打赏,没钱的欢迎点赞,不怕一万多,不嫌一块少。。。
关注你哦,欢迎回踩
不介意的可以联系我加个友链!
现在阿里无所不能了,好好的万网搞得乱七八糟
我好像一直没怎么备份啊。
这和阿里云自带的快照 有什么优缺点呢?
比快照更加灵活,快照无法部分恢复,而这个可以随时找到历史的某一个文件。作为快照的补充吧。
咱的博客还用不上阿里云的这个ECS,没法整这块,目前的备份工作使用的是插件。
我都是定期人工备份~~ :sad:
我都没备份,只要自己不误操作,出现问题就找空间商了。
签到成功!签到时间:上午12:28:02,每日签到,生活更精彩哦~
好深奥,我用的是WDCP,设置时间每天自动备份FTP及数据库
感谢分享 欢迎回访
先研究一番
估计弄起来有点麻烦,下次可以试试看。
一般的小网站,就自己定期备份一下就好了
OSS不便宜吧?
学习学习
感觉又学到了新的东西
还不错的样子[color=magenta] :evil: [/color]
谢谢分享,你的站权重挺高的哦。
写的不错,支持一下
支持一下兄弟,特此象征性的赞助一杯咖啡。
谢谢张兄,最近做了几个兼职。网站也都是单点的,本想自己写个类似的代码,由于公司一直忙,就没顾得上写。今天google无疑间就浏览到了。哈哈。
Get.可以试试哈
张哥的网站真是必备站长手册啊哈哈哈
哇塞,这一看博主就是大神,表示真心看不懂,支持大神!!
我在想有没有必要搞个七牛,或者阿里oos呢 :shock:
很赞的一个功能!
好复杂的样子 好好学习。。 :mrgreen:
oss是收费的吧
阿里云还有一个服务叫 归档存储 ,相较于 OSS,价格更便宜,博主有时间的话,不妨看看,用来备份数据的话,这个应该更适合
确实便宜,OSS是4G 1元/月,这个归档只要几毛钱。。。有空折腾下,多谢大神。
看了下,没有青岛区域的。。。还是不折腾了。
最近也终于有了自己的云服务器,不过是腾讯云的学生机,备份到七牛的可以学学。
支持博主
脚本解决了网络备份问题,极大地提高了安全性。Jager大神功德无量。我这里实际操作中就是有一个问题:oss中关于网站部分的压缩包很正常。但是数据库的压缩包字节数是0,也就是说数据库的备份失败,没有找到什么原因。一切按大神的,没有任何其他的更改。系统:centos6.5 wdcp php5.6
QQ 287988783
已经加你了。(/data/backup.sh db zhang.ge zhangge root 123456 /home/wwwbackup/zhang.ge >/dev/null 2>&1)这种单次脚本备份测试正常。
密码里面有百分号吧?
您那篇文章我也看了,密码中没有百分号,都是字母和数字的组合,并且用的是root
在Jager大神的帮助下解决了。问题出在《backup.sh: line 34: mysqldump: command not found》,解决方案就是用大神最新的backup.sh脚本即可。
阿里云可以通过内网挂载oss:https://www.xiaoz.me/archives/7320 ,挂载后写个脚本定时cp备份数据到oss也很方便。
通过oss.upload.py可以上传到bucket下,怎么把文件上传到bucket的一个文件夹下。
应该可以,注意看:第 5 个参数是存储在 OSS 的文件名称
这个参数你加一个斜杠,斜杠前面就是文件夹了,比如 xxxx/xxx.zip
第五个参数是bucket名称,不是文件名称,加斜杠报错。
自己看文档吧,估计是不支持路径定义:https://help.aliyun.com/document_detail/32030.html
或者你将上传代码中的:
改成如下试下:
diy表示文件夹路径,可以多级,比如 diy1/diy2/%s,不能用斜杠开头,%s不能少
张总,问你个问题,你代码中这段是什么意思呀
else:
print("Example: %s AccessKeyId AccessKeySecret Endpoint Bucket /data/backup.zip" % sys.argv[0])
exit()
参数不对,输出帮助提示
大佬就是大佬,备份方式都不一样,像我就只能用宝塔插件备份到oss
上传的时候能不能添加子目录,文件备份到某一个子目录里面这样更完美
发现官方的这个ossutil命令行工具不错,可以直接用哈,不用额外的python环境了,可以集成下。
https://help.aliyun.com/document_detail/50452.html
阿里云的这个ossutil很不错 https://help.aliyun.com/document_detail/50452.html 希望集成进来~