一.单机版redis安装以及企业级redis启动方案

安装:

[root@localhost ~]# tar zxf redis-3.2.3.tar.gz

[root@localhost  ~]# cd redis-3.2.3/

[root@localhost  redis-3.2.3]# make&& make install

[root@localhost  redis-3.2.3]# cd utils/

[root@localhost  utils]# ./install_server.sh

#按照默认位置即可(回车下去就好)

生产环境启动方案:

要把 redis 作为一个系统的daemon进程去运行的,每次系统启动,系统要一起启动

如果不是用我们上面的那种 # ./install_server.sh  的方式安装的就需要做下面的这些操作:

首先我们为redis生成一个配置文件

# cd /usr/local/src/redis-3.2.3/utils/

# cp redis_init_script /etc/init.d/

# vim /etc/init.d/redis_init_script

这里只列出需要修改部分(如果不需要修改就直接默认就可以)

REDISPORT=6379

EXEC=/usr/local/bin/redis-server

CLIEXEC=/usr/local/bin/redis-cli

PIDFILE=/var/run/redis_${REDISPORT}.pid

CONF="/etc/redis/${REDISPORT}.conf"

# mv /etc/init.d/redis_init_script /etc/init.d/redis_6379

# 这里说一下,我们用 ./install_server.sh 的方式安装默认这一步已经帮我们做好了

配置好服务之后测试启动:

# service redis_6379 start

我们来配置他随开机自动启动:

1.首先我们配置两行注释(开头位置):

# vim /etc/init.d/redis_6379

#!/bin/sh

# chkconfig: 2345 90 10

# description: Redis is a persistent key-value database

2.执行开机自启动命令:

# chkconfig redis_6379 on

redis-cli 的使用:

停止redis:

# redis-cli shutdown

连接redis:

# redis-cli -h 127.0.0.1 -p 6379 -a PASSWORD

测试redis端口是否正常

# redis-cli ping

创建一个key:

127.0.0.1:6379> set key1 value1

OK

查看一个key:

127.0.0.1:6379> get key1

"value1"

删除一个key:

127.0.0.1:6379> del key1

(integer) 1

redis的技术,包括4块:

redis各种数据结构和命令的使用

redis一些特殊的解决方案的使用, pub/sub消息系统,分布式锁,输入的自动完成,等等

redis日常管理的相关命令

redis企业级的集群部署和架构

二.redis持久化

1.redis持久化对于生成环境中的灾难恢复的意义:

redis持久化的意义在于故障恢复

比如说你部署了一个redis,做cache缓存,保存了一些比较重要的东西

如果没有持久化,redis遇到灾难性故障的时候,就会丢失所有的数据

如果通过持久化将数据搞到磁盘上去,然后定期同步备份到云存储服务器上去,那么就可以保证所有的数据不丢失全部,还是可以恢复一部分数据的.

redis的持久化分为: RDB,AOF 两种方式

持久化主要是做灾难恢复的,数据恢复,也可以归类到高可用的一个环节里面去.

比如你的redis整个挂了,然后redis不用了,你要做的事情就是让redis变的可用,尽快变得可用

重启redis,可以尽快让它可用,但是如果你redis没有做持久化,可用了也是没用的大量的sql会直接把mysql打死

2.redis的RDB和AOF两种持久化机制的介绍:

RDB持久化机制,对redis中数据执行周期性的持久化

AOF机制对每条数据写入命令作为日志,以append-only的模式写入一个日志文件中,在redis重启的时候,可以通过回放AOF日志中写入的指令来重新构建整个数据集

如果同时使用RDB和AOF两种持久化机制,那么在redis重启的时候,会使用AOF来重新构建数据,因为AOF中的数据更加完整

如果我们想要redis仅仅作为纯内存的缓存来用,那么可以禁止RDB和AOF所有的持久化机制

RDB持久化方式:

可以理解为数据快照方式

每隔一定时间,生成redis内存中数据的一份完整快照

AOF持久化方式:

相当于mysql的binlog日志方式

reids每隔1秒(默认)会强制调用操作系统,写入到文件中去

AOF文件是会无限的往一个文件里面写数据,为了防止这一现象发生redis会等到AOF文件数据量大到一定程度的时候创建一个新的AOF文件,然后把之前膨胀的AOF文件给删除掉

为防止AOF持续膨胀,redis的AOF重写机制:

首先我们在redis规定了redis只能占用1G的内存来存放缓存数据,

大概存了100w数据的时候这1G的数据粘满了,

这时候redis会根据自己的LRU算法清楚一些不常用的数据,

这时候redis内存中的数据为50w条,AOF文件中的数据为100w条,

redis又持续新增数据,当redis内存中的数据又达到100w条的时候,AOF文件中有150w条数据,

这时候redis会出手重写这个持续膨胀的AOF文件,

首先会创建一个新的AOF 文件出来, 把当前redis内存中的100w条数据写入到新的AOF文件中去,

写入完成之后会删除掉之前的那个膨胀的AOF文件

redis的AOF重写机制,保证AOF文件不会持续膨胀,当AOF文件膨胀到一定程度的时候,redis就会出手重写

3.redis的RDB和AOF两种持久化机制的优劣对比:

RDB的优点:

(1)RDB会生成多个数据文件,每个数据文件都代表了某一时刻中redis的数据,这种多个数据文件方式,非常适合做冷备份.

由redis去控制固定时长去生成快照文件

RDB数据最冷备,在最坏的情况下,提供数据恢复的时候,速度比AOF快

(2)RDB对redis对外提供读写服务,影响非常小,可以让redis保持高性能,因为redis主进程只需要fork一个子进程,让子进程执行磁盘的IO操作来进行RDB持久化即可

(3)相对于AOF持久化机制来说,直接基于RDB数据文件来重启和恢复redis进程,更加快速

AOF是存放的指令,需要回放

RDB,就是一份数据文件,恢复的时候直接加载到内存中即可

RDB的缺点:

(1)RDB在发生故障的时候,丢失的数据会比AOF多,因为RDB是定时快照文件,AOF是实时备份数据

这个问题,也是RDB最大的缺点,不适合做第一优先恢复的方案.

(2)RDB在做快照的时候,如果数据量特别大,可能会导致客户端提供的服务暂停数毫秒,甚至数秒

一般不要让RDB的快照间隔时间太长,否则每次生成的RDB文件太大了,对redis本身的性能可能会

有影响

AOF的优点:

(1)AOF可以更好的保护数据不丢失,一般AOF会每个一秒,通过后台线程执行一次fsync操作,最多丢失1秒的数据

(2)AOF日志文件以append-only模式写入,所以没有任何磁盘寻址开销,写入性能非常高,而且文件不容易破损

(3)AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写.因为在rewrite log的时候会对其中的指导进行压缩,创建出一份需要恢复数据的最小日志出来.在创建新日志文件的时候,老的日志文件还是照常写入.当新的日志文件创建成功之后,再交换老的日志文件即可.

(4)AOF通过命令的方式进行记录,非常适合做灾难性的误删除的紧急恢复.只要还没有进行rewrite操作就可以即时恢复数据

最大的优点就是: 更好的保护数据

AOF的缺点:

(1)对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大

(2)AOF开启后,支持redis写的QPS会降低

(3)以前AOF发生过bug,现在通过rewrite的方式会健壮一些

(4)唯一比较大的缺点,做恢复的时候,会比较慢, 不太适合做冷备

RDB和AOF到底该如何选择:

建议RDB和AOF同时开启:

(1)不要仅仅使用RDB,因为会导致你丢失很多的数据

(2)也不要仅仅使用AOF, 因为,AOF不适合做冷备,也没有RDB恢复速度快,AOF是发生过bug的

(3)综合使用AOF和RDB两种持久化机制

AOF尽可能大的保证数据安全

RDB用来做冷备份,在AOF文件损坏不可用的时候,还可以使用RDB来进程快速的数据恢复

4.配置redis的RDB持久化

配置RDB持久化:

# vim /etc/redis/6379.conf

save 60 1000

# 每隔60秒去检测一下,如果有超过1000个key发生了变更就去生成一个新的 dump.rdb文件,

这个dump.rdb文件就是redis内存中完整的数据快照,这个操作也被称之为snapshotting,快照,也可以手动调用save或者bgsave命令,同步或异步执行rdb快照生成

#save可以设置多个,同时生效

dbfilename dump.rdb

# RDB持久化的文件名称(因为名字是用的一个,所以每次快照之后,都会把之前快照的文件给替换掉)

# 意思是dump.rdb 文件只会有一个,新的会覆盖老的

dir /var/lib/redis/6379

# dump.rdb(rdb快照文件)存储的位置

改完配置记得重启:

# redis-cli SHUTDOWN

# service redis_6379 start

RDB持久化机制的工作流程:

(1)redis根据配置自己的尝试去生成rdb快照文件

(2)fork一个子进程出来

(3)子进程尝试将数据dump到临时的rdb快照文件中

(4)完成rdb快照文件的生成之后,就会替换掉之前的旧的快照文件

知识点补充:

通过 redis-cli SHUTDOWN 这种方式去关闭redis,其实是一种安全的退出方式, redis在退出的时候会将内存中的数据立即的生成一份完整的rdb快照

恢复测试:

(1) 写入数据 --- 立即通过 redis-cli SHUTDOWN关闭 -- 查看dump.rdb 文件是否生成 -- 启动redis查看数据是否还在

(2)定义 save 5 1 -- 插入数据,等待5秒 -- kill -9 杀掉redis -- 启动查看数据是否还在

5.配置redis的AOF持久化

默认是打开RDB持久化方式的,AOF默认是关闭的

AOF持久化配置:

# vim /etc/redis/6379.conf

appendonly yes

#打开AOF持久化,在我们生成环境中,AOF是一定要打开的,除非说,你丢几分钟的数据也无所谓

#AOF持久化策略(三种)

# appendfsync always

#每写入一条数据,立即将这个数据对应的写日志fsync到磁盘上去,性能非常差(大概2000QPS)

appendfsync everysec

#默认的AOF持久化策略(生产环境一般这么配置)

#每秒将 os cache中的数据fsync到磁盘(QPS可以到2w)

# appendfsync no

# 仅仅将数据写入到os cache中就撒手不管了,等待系统自动执行fsync操作,不可控

dir /var/lib/redis/6379

# dir即指定了 RDB快照文件的位置,也指定了 aof 日志文件的位置

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

# AOF rewrite操作,说一下这两个参数是什么意思:

比如说上一次AOF rewrite之后是 128mb,然后就会接着往进去写,如果发现超过了之前的100%,256mb, 就会去判读是否超过了 min-size 配置的参数(256>64),如果超过就会重写

改完之后记得重启:

# redis-cli SHUTDOWN

# service redis_6379 start

这里再说一下,RDB 和 AOF同时开启的情况下,启动的时候redis 会加载 AOF中的数据

QPS : 每秒钟的请求数量

AOF rewrite:

这里再说一下为啥要进行AOF rewrite操作:

redis中的数据其实是有限的,很多数据可能会自动过期,可能会被用户删除,可能会被redis自动清理掉

但是AOF文件中还是保存着这部分数据,时间一长数据就会不断膨胀

所有redis会通过rewrite操作来控制 aof文件的不断暴增

我们这边还是用上面的那张图,来看一下,为啥要做AOF rewrite:

AOF rewrite工作原理:

(1)redis fork一个子进程

(2)子进程基于当前内存中的数据,构建日志,开始往一个新的临时的AOF文件中写入日志

(3)redis主进程,接收到client新的写操作之后,在内存中写入日志,同事新的日志也继续写入旧的AOF文件

(4)子进程写完新的日志文件之后,主进程将内存职工的新日志再次追加到新的AOF文件中

(5)用新的日志文件替换掉旧的日志文件

AOF文件修复:

如果AOF文件有破损的话,可以用 redis-check-aof --fix 做修复

# redis-check-aof --fix appendonly.aof

AOF和RDB同时工作:

1.如果RDB在执行快照操作的时候,不会执行AOF的 rewrite操作

反之,如果AOF 在执行rewrite操作的时候,ROD的快照操作也不会执行

总而言之就是,不会同时执行,RDB快照操作 和 AOF rewrite操作

2.如果RDB在执行快照操作,我们手动的去执行 AOF rewrite操作,呢么等RDB的快照操作完成之后AOF  

rewrite操作才会去执行

3.如果同时用RDB和AOF两种持久化机制,重启redis的时候,会优先使用AOF进程数据恢复,因为其中的

日志更完整

知识点补充:

如果RDB中有部分数据,AOF中有部分数据,RDB中的数据不会被加载

三.企业级备份方案

在企业中,RDB的生成策略,用默认的其实也差不多

如果你希望你的RDB最多丢失一分钟的数据,呢么尽量每个一分钟都去生成一个快照

save 60 10000 这个调策略根据自己实际需求去改

AOF一定要打开,用默认设置也差不多:

fsync的策略用 everysec 策略就可以(每隔一秒redis调用系统强刷一次fsync)

auto-aof-rewrote-min-size: 根据自己的数据量来调整一下就好了

几台 redis 承受几十万的 QPS,完全没有问题

数据备份方案:

(1)写crontab定时调度备份脚本去做数据备份

(2)每个小时都copy一份rdb的备份到一个目录中去,仅仅保留最近48小时的备份

(3)每天都保留一份当日的rdb备份,到一个目录中去,仅仅保留最近一个月的备份

(4)每次copy备份的时候,都把太旧的备份给删了

(5)每天晚上将当前服务器上所有的数据备份,发送一份到远程的云服务器上去

每小时copy一次备份,删除48小时前的数据

crontab -e

0 * * * * sh /usr/local/redis/copy/redis_rdb_copy_hourly.sh

#vim /usr/local/redis/copy/redis_rdb_copy_hourly.sh

#!/bin/sh

cur_date=`date +%Y%m%d%k`

rm -rf /usr/local/redis/snapshotting/$cur_date

mkdir -p /usr/local/redis/snapshotting/$cur_date

cp /var/redis/6379/dump.rdb /usr/local/redis/snapshotting/$cur_date

del_date=`date -d -48hour +%Y%m%d%k`

rm -rf /usr/local/redis/snapshotting/$del_date

每天copy一次备份

crontab -e

0 0 * * * sh /usr/local/redis/copy/redis_rdb_copy_daily.sh

# vim /usr/local/redis/copy/redis_rdb_copy_daily.sh

#!/bin/sh

cur_date=`date +%Y%m%d`

rm -rf /usr/local/redis/snapshotting/$cur_date

mkdir /usr/local/redis/snapshotting/$cur_date

cp /var/redis/6379/dump.rdb /usr/local/redis/snapshotting/$cur_date

del_date=`date -d -1month +%Y%m%d`

rm -rf /usr/local/redis/snapshotting/$del_date

每天一次将所有数据上传一次到远程的云服务器上去

crontab -e

0 0 * * * sh /usr/local/redis/copy/redis_rdb_scp.sh

# vim /usr/local/redis/copy/redis_rdb_scp.sh

#!/bin/sh

ssh root@远程主机 "rm -rf /opt/backup/snapshotting/*"

scp /usr/local/redis/snapshotting/* root@远程主机:opt/backup/snapshotting/

数据恢复方案:

(1)如果是redis进程挂掉,那么重启redis进程即可,直接基于AOF日志文件恢复数据

(2)如果是redis进程所在机器挂掉,那么重启机器后,尝试重启redis进程,尝试直接基于AOF日志文件进行数据恢复

AOF没有破损,也是可以直接基于AOF恢复的

AOF append-only,顺序写入,如果AOF文件破损,那么用redis-check-aof fix

(3)如果redis当前最新的AOF和RDB文件出现了丢失/损坏,那么可以尝试基于该机器上当前的某个最新的RDB数据副本进行数据恢复

当前最新的AOF和RDB文件都出现了丢失/损坏到无法恢复,一般不是机器的故障,人为

找到RDB最新的一份备份,小时级的备份可以了,小时级的肯定是最新的,copy到redis里面去,就可以恢复到某一个小时的数据(要注意目录下面不要有 aof 的破损文件,要暂时关闭AOF持久化)

操作:

1.停止redis

2.清除/var/redis/6379/下面的破损文件

3.再配置文件中关闭 AOF持久化

4.把备份的 rdb文件 传到 /var/redis/6379/ 目录下面

5.启动redis,确认数据恢复正常

6.直接在命令行热修改redis配置打开aof,

打开之后redis就会将内存中的数据对应的日志,写入aof文件中

127.0.0.1:6379> config set appendonly yes

7.稍等片刻(等待redis将内存中的数据写入到刚刚生成的AOF文件),之后再次停止redis

8.在配置文件中开启 AOF 持久化

9.启动redis  

(4)如果当前机器上的所有RDB文件全部损坏,那么从远程的云服务上拉取最新的RDB快照回来恢复数据

(5)如果是发现有重大的数据错误,比如某个小时上线的程序一下子将数据全部污染了,数据全错了,那么可以选择某个更早的时间点,对数据进行恢复

举个例子,12点上线了代码,发现代码有bug,导致代码生成的所有的缓存数据,写入redis,全部错了,找到一份11点的rdb的冷备,然后按照上面的步骤,去恢复到11点的数据,不就可以了吗