Redis特性

Redis持久化机制

Redis工作时数据都存储在内存中,万一服务器断电,则所有数据都会丢失。针对这种情况,Redis采用持久化机制来增强数据安全性。

RDB

机制描述

每隔一定的时间把内存中的数据作为一个快照保存到硬盘上的文件中。Redis默认开启RDB机制。

触发时机

1)基于默认配置

save 900 1
save 300 10
save 60 10000

2)使用保存命令

save或bgsave

3)使用flushall命令
这个命令也会产生dump.rdb文件,但里面是空的,没有意义
4)服务器关闭
如果执行SHUTDOWN命令让Redis正常退出,那么此前Redis就会执行一次持久化保存。

相关配置
配置项取值作用
save“”禁用RDB机制
dbfilename文件名,例如:dump.rdb设置RDB机制下,数据存储文件的文件名
dirRedis工作目录路径指定存放持久化文件的目录的路径。注意:这里指定的必须是目录不能是文件名

AOF

机制描述

根据配置文件中指定的策略,把生成数据的命令保存到硬盘上的文件中。
1)一个AOF文件的内容可以参照下面的例子:

*2
$6
SELECT
$1
0
*3
$3
set
$3
num
$2
10
*2
$4
incr
$3
num
*2
$4
incr
$3
num
*2
$4
incr
$3
num

2)生成上面文件内容的Redis命令

set num 10
incr num
incr num
incr num

在这里插入图片描述
对比下面两组命令:
在这里插入图片描述
两组命令执行后对于count来说最终的值是一致的,但是进行AOF重写后省略了中间过程,可以让AOF文件体积更小。而Redis会根据AOF文件的体积来决定是否进行AOF重写。参考的配置项如下:

配置项含义
auto-aof-rewrite-percentage 100文件体积增大100%时执行AOF重写
auto-aof-rewrite-min-size 64mb文件体积增长到64mb时执行AOF重写

实际工作中不要进行频繁的AOF重写,因为CPU资源和硬盘资源二者之间肯定是CPU资源更加宝贵,所以不应该过多耗费CPU性能去节省硬盘空间。

持久化文件损坏修复

Redis服务器启动时如果读取了损坏的持久化文件会导致启动失败,此时为了让Redis服务器能够正常启动,需要对损坏的持久化文件进行修复。这里以AOF文件为例介绍修复操作的步骤。
第一步:备份要修复的appendonly.aof文件
第二步:执行修复程序

bin/redis-check-aof --fix ./appendonly.aof

第三步:重启Redis
注意:所谓修复持久化文件仅仅是把损坏的部分去掉,而没法把受损的数据找回。

各自的特点

RDB

1)优势
适合大规模的数据恢复,速度较快
2)劣势
会丢失最后一次快照后的所有修改,不能绝对保证数据的高度一致性和完整性。Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑,但上述成立有条件,Linux也有优化手段

AOF

1)优势
选择appendfsync always方式运行时理论上能够做到数据完整一致,但此时性能又不好。文件内容具备一定可读性,能够用来分析Redis工作情况。
2)劣势
持久化相同的数据,文件体积比RDB大,恢复速度比RDB慢。效率在同步写入时低于RDB,不同步写入时与RDB相同。

RDB和AOF并存

Redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整
RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?作者建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份)、快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。

使用建议

如果Redis仅仅作为缓存可以不使用任何持久化方式。
其他应用方式综合考虑性能和完整性、一致性要求。
RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则。如果Enalbe AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了。代价一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上。默认超过原大小100%大小时重写可以改到适当的数值。如果不开启AOF,仅靠Master-Slave Replication 实现高可用性能也不错。能省掉一大笔IO也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个。新浪微博就选用了这种架构。

Redis事务控制

Redis事务控制相关命令

在这里插入图片描述

命令队列执行失败的两种情况

加入队列时失败
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set age 20
QUEUED
127.0.0.1:6379> incr age
QUEUED
127.0.0.1:6379> incr age www
(error) ERR wrong number of arguments for 'incr' command
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
执行队列时失败
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set age 30
QUEUED
127.0.0.1:6379> incrby age 5
QUEUED
127.0.0.1:6379> incrby age 5
QUEUED
127.0.0.1:6379> incrby age ww
QUEUED
127.0.0.1:6379> incrby age 5
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) (integer) 35
3) (integer) 40
4) (error) ERR value is not an integer or out of range
5) (integer) 45
127.0.0.1:6379> get age
"45"
Redis为什么不支持回滚

官方解释如下:
如果你有使用关系式数据库的经验,那么“Redis在事务失败时不进行回滚,而是继续执行余下的命令”这种做法可能会让你觉得有点奇怪。以下是这种做法的优点:
1)Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。
2)因为不需要对回滚进行支持,所以Redis的内部可以保持简单且快速。有种观点认为 Redis处理事务的做法会产生bug,然而需要注意的是,在通常情况下,回滚并不能解决编程错误带来的问题。举个例子,如果你本来想通过 INCR 命令将键的值加上1,却不小心加上了2,又或者对错误类型的键执行了INCR,回滚是没有办法处理这些情况的。

Watch

案例演示

127.0.0.1:6379> GET salary
"50"
127.0.0.1:6379> WATCH salary
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> INCRBY salary 50
QUEUED
127.0.0.1:6379> INCRBY salary 50
QUEUED
127.0.0.1:6379> INCRBY salary 50
QUEUED
127.0.0.1:6379> INCRBY salary 50
QUEUED

在另一个客户端执行
127.0.0.1:6379> GET salary
"50"
127.0.0.1:6379> SET salary 100
OK
127.0.0.1:6379> get salary
"100"

回到之前的客户端
127.0.0.1:6379> EXEC
(nil)
127.0.0.1:6379> get salary
"100"

悲观锁和乐观锁

在使用WATCH命令监控一个KEY后,当前队列中的命令会由于外部命令的执行而放弃,这是乐观锁的体现。
1)悲观锁:认为当前环境非常容易发生碰撞,所以执行操作前需要把数据锁定,操作完成后释放锁,其他操作才可以继续操作。
2)乐观锁:认为当前环境不容易发生碰撞,所以执行操作前不锁定数据,万一碰撞真的发生了,那么放弃自己的操作。

Redis主从复制机制

在这里插入图片描述

读写分离的好处

性能优化:主服务器专注于写操作,可以用更适合写入数据的模式工作;同样,从服务器专注于读操作,可以用更适合读取数据的模式工作。
强化数据安全,避免单点故障:由于数据同步机制的存在,各个服务器之间数据保持一致,所以其中某个服务器宕机不会导致数据丢失或无法访问。从这个角度说参与主从复制的Redis服务器构成了一个集群。

搭建步骤

思路

Redis集群在运行时使用的是同一个可执行文件,只是对应的配置文件不同。

daemonize yes
dir /opt/module/redis/cluster

不同的参数有:
在这里插入图片描述

步骤

第一步:创建/usr/local/cluster-redis目录
第二步:把原始未经修改的redis.conf复制到/usr/local/cluster-redis目录
第三步:把/usr/local/cluster-redis目录下的redis.conf复制为redis6000.conf
第四步:按照既定计划修改redis6000.conf中的相关配置项

daemonize yes
dir
port
dbfilename
logfile
pidfile

第五步:复制redis6000.conf为redis7000.conf
第六步:修改redis7000.conf中的相关配置项

port
dbfilename
logfile
pidfile

第七步:复制redis6000.conf为redis8000.conf
第八步:修改redis8000.conf中的相关配置项

port
dbfilename
logfile
pidfile
启动
bin/redis-server cluster-redis/redis6000.conf
bin/redis-server cluster-redis/redis7000.conf
bin/redis-server cluster-redis/redis8000.conf
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值