redis实战:redis自动备份与备份管理
使用redis开启多个服务
在实际的部署中redis需要开启多个端口来向外提供服务,不仅要设置不同的启动参数,还需要我们及时做好备份的相关操作,这就需要借助shell或者python等脚本来进行管理配置。接下来我们以一个实际的例子来介绍工作中对于redis的相关操作。
需求:
1.我们需要自动开启多个redis服务;
2.需要定时对redis进行备份;
3.考虑到磁盘的容量,我们需要将备份的规模限制在一个范围,以防磁盘容量不足;
4.对于不同的redis服务,备份文件也需要分目录管理;
在/data目录下创建redis服务所在目录以及redis备份目录:
[root@server1 data]# pwd
/data
[root@server1 data]# ls
redis-backup redis-file
在redis-file中我们开启了4个redis服务,他们绑定了不同的端口,并且指定了不同的目录、备份文件、pid文件:
[root@server1 redis-file]# ls
allredisrun.sh redis_test1 redis_test2 redis_test3 redis_test4
[root@server1 redis-file]# cd redis_test1
[root@server1 redis_test1]# ls
redis.conf redis-server redis_test1.pid redis_test1.rdb run_redis_test1.sh
我们以redis_test1服务为例,可以查看其启动脚本
[root@server1 redis_test1]# cat run_redis_test1.sh
#!/bin/bash
rootdir=/data/redis-file/redis_test1
${rootdir}/redis-server ${rootdir}/redis.conf --port 6381 --dbfilename redis_test1.rdb --save 900 1000 -save 300 10000 --pidfile redis_test1.pid &
其他的redis服务与redis_test1类似,所以我们设置一个总的启动脚本:
[root@server1 redis-file]# cat allredisrun.sh
#!/bin/bash
redis_root_dir="/data/redis-file"
bash="/bin/bash"
for i in `seq 1 4`
do
cd ${redis_root_dir}/redis_test${i}
${bash} ${redis_root_dir}/redis_test${i}/run_redis_test${i}.sh
done
执行了该脚本后查看服务器上的redis服务:
[root@server1 redis-file]# ps aux |grep redis
root 1602 0.1 0.5 133544 7864 pts/0 Sl 06:45 0:00 /data/redis-file/redis_test1/redis-server 192.168.1.8:6381
root 1604 0.1 0.5 133544 7868 pts/0 Sl 06:45 0:00 /data/redis-file/redis_test2/redis-server 192.168.1.8:6382
root 1606 0.1 0.5 133544 7868 pts/0 Sl 06:45 0:00 /data/redis-file/redis_test3/redis-server 192.168.1.8:6383
root 1612 0.0 0.5 133544 7868 pts/0 Sl 06:45 0:00 /data/redis-file/redis_test4/redis-server 192.168.1.8:6384
root 1619 0.0 0.0 103256 868 pts/0 S+ 06:45 0:00 grep redis
多个redis服务备份
服务正常开启后,我们需要设置自动备份的脚本,该脚本在/data/redis-backup下,脚本的内容如下所示(redis_backup.py ):
#encoding:utf-8
#!/usr/bin/env python
import os
import tarfile
import time
backupFrom="/data/redis-file"
backupTo="/data/redis-backup"
redisFileSuffix=(".rdb", ".aof")
sourceRedisFile={}
sourceRedisFilePath={}
targetBackupFolder={}
#设置日志级别,以小时为单位还是以天为单位
#0:don't create folder
#1:create folder every hour
#2:create folder every day
folderCut = 2
def now_time():
return time.strftime("%Y%m%d%H%M", time.localtime(time.time()))
def mkdir(dirpath):
if(os.path.exists(dirpath)):
return
os.mkdir(dirpath)
def cutFolder(type):
if type == 0:
return
elif type == 1:
return time.strftime("%Y%m%d", time.localtime(time.time()))
elif type == 2:
return time.strftime("%Y%m%d%H", time.localtime(time.time()))
#压缩文件
def compressFile(localPath, targetPath, filename):
localfullPath = os.path.join(localPath, filename)
targetfullPath = os.path.join(targetPath, filename + now_time() + ".tar.gz")
tar = tarfile.open(targetfullPath, "w:gz")
tar.add(localfullPath)
tar.close()
print ("compress file: %s ====> %s" % (localfullPath, targetfullPath))
def genRedisBackupFolder():
mkdir(backupTo)
for i in range(0, len(sourceRedisFile)):
targetName = sourceRedisFile[i].split(".")[0]
mkdir(os.path.join(backupTo, targetName))
targetFolder = os.path.join(os.path.join(backupTo, targetName), cutFolder(folderCut))
mkdir(targetFolder)
targetBackupFolder[i] = targetFolder
#找出所要压缩的文件及其所在的目录
def findRedisFile():
index = 0
for parent, dirnames, filenames in os.walk(backupFrom):
for filename in filenames:
for suffix in redisFileSuffix:
if suffix in filename:
sourceRedisFile[index] = filename
sourceRedisFilePath[index] = parent
index = index + 1
#对redis的每个服务进行压缩
def compressRedisFiles():
if not (len(sourceRedisFilePath) == len(targetBackupFolder) and
len(targetBackupFolder) == len(sourceRedisFile)):
print "error occured in function compressRedisFiles()!"
for i in range(0, len(sourceRedisFile)):
compressFile(sourceRedisFilePath[i], targetBackupFolder[i], sourceRedisFile[i])
if __name__ == "__main__":
print "================================begin backup redis file=================================="
findRedisFile()
genRedisBackupFolder()
compressRedisFiles()
print "=======================================finished=========================================="
执行了该脚本后,可以看到将备份文件打包到了备份目录(/data/redis-backup),不同的服务有一个独立的目录:
[root@server1 redis-backup]# python redis_backup.py
================================begin backup redis file==================================
compress file: /data/redis-file/redis_test4/redis_test4.rdb ====> /data/redis-backup/redis_test4/2016071106/redis_test4.rdb201607110646.tar.gz
compress file: /data/redis-file/redis_test1/redis_test1.rdb ====> /data/redis-backup/redis_test1/2016071106/redis_test1.rdb201607110646.tar.gz
compress file: /data/redis-file/redis_test3/redis_test3.rdb ====> /data/redis-backup/redis_test3/2016071106/redis_test3.rdb201607110646.tar.gz
compress file: /data/redis-file/redis_test2/redis_test2.rdb ====> /data/redis-backup/redis_test2/2016071106/redis_test2.rdb201607110646.tar.gz
=======================================finished==========================================
为了让备份自动进行,我们需要将该备份脚本的执行命令写入crontab中,达到定时执行的目的:
#每个小时的1分和31分时进行备份
[root@server1 redis-backup]# crontab -l
01,31 * * * * python /data/redis-backup/redis_backup.py
如果持续的进行备份,我们还需要考虑磁盘的容量,这个可以采用zabbix服务进行监控,等磁盘容量达到一定百分比的时候进行手动删除,这样是一种比较low的方法,最好的方法是让脚本可以自己发现问题,所以我们需要编写另外的脚本定期删除redis的备份文件,只保留最“新“的备份信息。该脚本希望大家可以自己动手进行书写。