1. redis介绍
1.1. 什么是redis
Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库。它通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止Redis支持的键值数据类型如
下:
字符串类型
散列类型 (对应Java中的Object,它主要用来存储对象)
列表类型 (List)
集合类型 (Set)
有序集合类型。 (TreeSet)
1.2. redis的应用场景
缓存(数据查询、短连接、新闻内容、商品内容等等)。(最多使用)
分布式集群架构中的session分离。
聊天室的在线好友列表。
任务队列。(秒杀、抢购、12306等等)
应用排行榜。
网站访问统计。
数据过期处理(可以精确到毫秒)
2. Redis的安装
2.1 在Windows上安装
2.2 在Linux上安装
redis是C语言开发,建议在linux上运行,示例使用CentOS7作为安装环境。
-
安装redis需要先将官网下载的源码进行编译,编译依赖gcc环境,如果没有gcc环境,需要安装gcc
yum install gcc-c++
阿里云的CentOS7默认已经内置了gcc,可以跳过这一步
-
下载redis
从官网下载
http://download.redis.io/releases/redis-5.0.5.tar.gz
将redis-5.0.5.tar.gz拷贝任意路径下,如 /home/john/opt/
-
解压源码
cd /home/john/opt/ tar -zxvf redis-3.0.0.tar.gz
-
进入解压后的目录进行编译安装
cd /home/john/opt/redis-5.0.5/src make # 编译源代码 make install # 安装 # 上面两步也可以直接通过 make && make install两步并一步执行
Redis默认的安装目录是/usr/local/bin, 我们在执行make install命令时添加prefix参数可修改默认安装位置,如: make PREFIX=/usr/local/redis install
3. redis启动
redis.conf是redis的配置文件,默认在redis源码包解压后的根目录有一份redis.conf文件,我们可将其拷贝一份到上一步中redis的安装目录
cd /home/john/opt/redis-5.0.5/src
cp redis.conf /usr/local/bin
我们装完redis以后,默认的安装路径是/usr/local/bin,系统会自动来此目录寻找命令,所以我们不需要在配置环境变量,在任意目录都可以使用redis相关的命令,如redis-server、redis-cli
3.1. 前端模式启动
启动命令:
redis-server /usr/local/bin/redis.conf
通过上面的命令启动,redis将以前端模式启动,前端模式启动的缺点是ssh命令窗口关闭则redis-server程序结束,不推荐使用此方法。
3.2. 后端模式启动
3.2.1 开启远程连接
- 注释掉 bind 127.0.0.1这行
- 关闭保护模式 将protected-mode yes 改成 protected-mode no
3.2.2 添加密码验证
放开 # requirepass foobared 这行注释,将后面的foobared改成你自己需要设置的密码
客户端连接时,需要添加-a 参数指定密码才能连上来。
3.2.3 开启后台守护进程运行模式
将 # daemonize no 这行放开注释, 并且改成 yes, Redis server将以后台方式运行。
3.2.4 指定日志文件
将 logfile “” 改成 logfile “你需要的redis日志文件名称”, 默认的空字符串代表输出到前端控制台(标准输出)
修改redis.conf配置文件, daemonize yes 以后端模式启动。
3.2.5 启动
启动命令和前端启动一样,只不过控制台不会输出任何信息,而且命令结束,如果没有异常会马上退出。
4. 通过jedis连接redis单机
4.1 SringBoot方式
4.1.1 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
4.1.2 SpringBoot配置
application.yml
spring:
redis:
host: www.taotao.com
# port: 6379
# password:
jedis:
pool:
max-idle: 2
max-wait: 1000ms
4.3. 单实例连接
通过创建单实例jedis对象连接redis服务,如下代码:
@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestRedisClient {
@Autowired
private StringRedisTemplate redisTemplate;
@Test
public void testRedis() {
Set<String> keys = redisTemplate.keys("*");
log.info("操作前存在的keys: " + keys);
String key = "lanou_F4";
redisTemplate.opsForList().rightPushAll(key, new String[]{"宋超", "国胜", "国伟", "高飞"});
long size = redisTemplate.opsForList().size(key);
log.info("当前"+key+"值的数量: " + size);
List<String> values = redisTemplate.opsForList().range(key, 0, size);
log.info("当前" + key +"的值: " + values);
keys = redisTemplate.keys("*");
log.info("操作后存在的keys: " + keys);
}
}
4.3. 外部连接不上redis的解决方法
由于linux防火墙默认开启,redis的服务端口6379并不在开放规则之内,所有需要将此端口开放访问或者关闭防火墙。
查看防火墙状态:sevice iptables status
关闭防火墙命令:sevice iptables stop
如果是修改防火墙规则,可以修改:/etc/sysconfig/iptables文件
5. redis集群
5.1. 集群原理
5.1.1. redis-cluster架构图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uSJ4fLAz-1575983144481)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image013.jpg)]
架构细节:
(1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
(2)节点的fail是通过集群中超过半数的节点检测失效时才生效.
(3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
(4)redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value
Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点
5.1.2. redis-cluster投票:容错
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7a5j0WOt-1575983144482)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image014.jpg)]
(1)领着投票过程是集群中所有master参与,如果半数以上master节点与master节点通信超过(cluster-node-timeout),认为当前master节点挂掉.
(2):什么时候整个集群不可用(cluster_state:fail)?
a:如果集群任意master挂掉,且当前master没有slave.集群进入fail状态,也可以理解成集群的slot映射[0-16383]不完成时进入fail状态. ps : redis-3.0.0.rc1加入cluster-require-full-coverage参数,默认关闭,打开集群兼容部分失败.
b:如果集群超过半数以上master挂掉,无论是否有slave集群进入fail状态.
ps:当集群不可用时,所有对集群的操作做都不可用,收到((error) CLUSTERDOWN The cluster is down)错误
5.2. ruby环境(Redis5以后的版本不需要依赖Ruby环境)
redis集群管理工具redis-trib.rb依赖ruby环境,首先需要安装ruby环境:
安装ruby
yum install ruby
yum install rubygems
安装ruby和redis的接口程序
拷贝redis-3.0.0.gem至/usr/local下
执行:
gem install /usr/local/redis-3.0.0.gem
5.3. 创建集群:
5.3.1. 集群结点规划
这里在同一台服务器用不同的端口表示不同的redis服务器,如下:
主节点:192.168.101.3:7001 192.168.101.3:7002 192.168.101.3:7003
从节点:192.168.101.3:7004 192.168.101.3:7005 192.168.101.3:7006
在/usr/local下创建redis-cluster目录,其下创建7001、7002。。7006目录,如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lafQdbTw-1575983144483)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image016.jpg)]
将redis安装目录bin下的文件拷贝到每个700X目录内,同时将redis源码目录src下的redis-trib.rb拷贝到redis-cluster目录下。
修改每个700X目录下的redis.conf配置文件:
port XXXX
#bind 192.168.101.3
cluster-enabled yes
pidfile /var/run/redis_6379.pid #这里的进程文件也要修改一下,否则会冲突
5.3.2. 启动每个结点redis服务
进入/usr/local/redis_cluster目录下,编写启动集群脚本:start_redis_cluster.sh
cd /usr/local/redis_cluster
vim start_redis_cluster.sh
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DzpXywCQ-1575983144483)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image018.jpg)]
编辑完成后,按ESC切换到命令模式, 输入ZZ 或者 :wq保存退出。
启动Redis集群中所有节点:
./start_redis_cluster.sh
查看redis进程:
ps aux | grep redis
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ed5iBRYl-1575983144484)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image020.jpg)]
5.3.3. 执行创建集群命令
Redis 5以下需要使用redis-trib.rb这个Ruby脚本来管理集群,所以需要事先安装Ruby运行环境
执行redis-trib.rb,此脚本是ruby脚本,它依赖ruby环境。
./redis-trib.rb create --replicas 1 192.168.101.3:7001 192.168.101.3:7002 192.168.101.3:7003 192.168.101.3:7004 192.168.101.3:7005 192.168.101.3:7006
Redis 5开始,集群不需要依赖Ruby,官方直接提供了集群管理支持
注意:如果创建redis集群的时候,ip用的是127.0.0.1,那么你在用Java客户端远程操作Redis集群的时候,会死活连不上,一直是报127.0.0.1:7001无法连接
解决办法:创建Redis集群时,用外部可以访问的IP
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WsbMjHrA-1575983144485)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image022.jpg)]
说明:
redis集群至少需要3个主节点,每个主节点有一个从节点总共6个节点
–cluster-replicas指定为1表示每个主节点有一个从节点
注意:
如果执行时报如下错误:
[ERR] Node XXXXXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0
解决方法是删除生成的配置文件nodes.conf,如果不行则说明现在创建的结点包括了旧集群的结点信息,需要删除redis的持久化文件后再重启redis,比如:appendonly.aof、dump.rdb
创建集群输出如下:
>>> Creating cluster
Connecting to node 192.168.101.3:7001: OK
Connecting to node 192.168.101.3:7002: OK
Connecting to node 192.168.101.3:7003: OK
Connecting to node 192.168.101.3:7004: OK
Connecting to node 192.168.101.3:7005: OK
Connecting to node 192.168.101.3:7006: OK
>>> Performing hash slots allocation on 6 nodes…
Using 3 masters:
192.168.101.3:7001
192.168.101.3:7002
192.168.101.3:7003
Adding replica 192.168.101.3:7004 to 192.168.101.3:7001
Adding replica 192.168.101.3:7005 to 192.168.101.3:7002
Adding replica 192.168.101.3:7006 to 192.168.101.3:7003
M: cad9f7413ec6842c971dbcc2c48b4ca959eb5db4 192.168.101.3:7001
slots:0-5460 (5461 slots) master
M: 4e7c2b02f0c4f4cfe306d6ad13e0cfee90bf5841 192.168.101.3:7002
slots:5461-10922 (5462 slots) master
M: 1a8420896c3ff60b70c716e8480de8e50749ee65 192.168.101.3:7003
slots:10923-16383 (5461 slots) master
S: 69d94b4963fd94f315fba2b9f12fae1278184fe8 192.168.101.3:7004
replicates cad9f7413ec6842c971dbcc2c48b4ca959eb5db4
S: d2421a820cc23e17a01b597866fd0f750b698ac5 192.168.101.3:7005
replicates 4e7c2b02f0c4f4cfe306d6ad13e0cfee90bf5841
S: 444e7bedbdfa40714ee55cd3086b8f0d5511fe54 192.168.101.3:7006
replicates 1a8420896c3ff60b70c716e8480de8e50749ee65
Can I set the above configuration? (type ‘yes’ to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join…
>>> Performing Cluster Check (using node 192.168.101.3:7001)
M: cad9f7413ec6842c971dbcc2c48b4ca959eb5db4 192.168.101.3:7001
slots:0-5460 (5461 slots) master
M: 4e7c2b02f0c4f4cfe306d6ad13e0cfee90bf5841 192.168.101.3:7002
slots:5461-10922 (5462 slots) master
M: 1a8420896c3ff60b70c716e8480de8e50749ee65 192.168.101.3:7003
slots:10923-16383 (5461 slots) master
M: 69d94b4963fd94f315fba2b9f12fae1278184fe8 192.168.101.3:7004
slots: (0 slots) master
replicates cad9f7413ec6842c971dbcc2c48b4ca959eb5db4
M: d2421a820cc23e17a01b597866fd0f750b698ac5 192.168.101.3:7005
slots: (0 slots) master
replicates 4e7c2b02f0c4f4cfe306d6ad13e0cfee90bf5841
M: 444e7bedbdfa40714ee55cd3086b8f0d5511fe54 192.168.101.3:7006
slots: (0 slots) master
replicates 1a8420896c3ff60b70c716e8480de8e50749ee65
[OK] All nodes agree about slots configuration.
>>> Check for open slots…
>>> Check slots coverage…
[OK] All 16384 slots covered.
5.4. 停止Redis集群
在/usr/local/redis_cluster目录下,创建脚本文件:stop_redis_cluster.sh
输入一下内容:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TudPMHio-1575983144486)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image024.jpg)]
5.5. 查询集群信息
集群创建成功登陆任意redis结点查询集群中的节点情况。
客户端以集群方式登陆:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o6C8RUKl-1575983144487)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image026.jpg)]
说明:
./redis-cli -c -h 192.168.101.3 -p 7001 ,其中-c表示以集群方式连接redis,-h指定ip地址,-p****指定端口号
cluster nodes 查询集群结点信息
cluster info 查询集群状态信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JSrcpUO7-1575983144487)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image028.jpg)]
5.6. 添加主节点
集群创建成功后可以向集群中添加节点,下面是添加一个master主节点
添加7007结点,参考集群结点规划章节添加一个“7007”目录作为新节点。
执行下边命令:
./redis-trib.rb add-node 192.168.101.3:7007 192.168.101.3:7001
Redis 5 添加主节点命令:
语法:redis-cli –cluster add-node **要添加节点的ip:端口 集群中当前存在的任何一个节点的ip**和端口
redis-cli --cluster add-node 10.10.14.166:7006 10.10.14.166:7000
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WuZ0MuV6-1575983144488)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image030.jpg)]
查看集群结点发现7007已添加到集群中:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bnrbCZjK-1575983144488)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image032.jpg)]
5.6.1. hash槽重新分配
添加完主节点需要对主节点进行hash槽分配这样该主节才可以存储数据。
redis集群有16384个槽,集群中的每个结点分配自已槽,通过查看集群结点可以看到槽占用情况。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mRo2olGc-1575983144489)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image034.gif)]
给刚添加的7007结点分配槽:
第一步:连接上集群
./redis-trib.rb reshard 192.168.101.3:7001(连接集群中任意一个可用结点都行)
第二步:输入要分配的槽数量
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nH5twikp-1575983144489)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image036.jpg)]
输入 500表示要分配500个槽
第三步:输入接收槽的结点id
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3yV5cFir-1575983144489)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image038.gif)]
这里准备给7007分配槽,通过cluster nodes查看7007结点id为15b809eadae88955e36bcdbb8144f61bbbaf38fb
输入:15b809eadae88955e36bcdbb8144f61bbbaf38fb
第四步:输入源结点id
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lMryizLs-1575983144490)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image040.gif)]
这里输入all
第五步:输入yes开始移动槽到目标结点id
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B5yhFhQQ-1575983144490)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image042.jpg)]
关于Redis 集群的hash slots相关知识,可以参阅:
5.7. 添加从节点
集群创建成功后可以向集群中添加节点,下面是添加一个slave从节点。
添加7008从结点,将7008作为7007****的从结点。
./redis-trib.rb add-node --slave --master-id 主节点id 添加节点的ip****和端口 集群中已存在节点ip****和端口
Redis 5 命令:
语法:redis-cli –cluster add-node 要添加节点的ip:端口 **集群中已有master的ip**和端口 --cluster-slave
示例:redis-cli --cluster add-node 10.10.14.166:7006 10.10.14.166:7001 --cluster-slave
执行如下命令:
./redis-trib.rb add-node --slave --master-id cad9f7413ec6842c971dbcc2c48b4ca959eb5db4 192.168.101.3:7008 192.168.101.3:7001
cad9f7413ec6842c971dbcc2c48b4ca959eb5db4 是7007结点的id,可通过cluster nodes查看。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZW8Di7Wh-1575983144491)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image044.jpg)]
注意:如果原来该结点在集群中的配置信息已经生成cluster-config-file指定的配置文件中(如果cluster-config-file没有指定则默认为nodes.conf),这时可能会报错:
[ERR] Node XXXXXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0
解决方法是删除生成的配置文件nodes.conf,删除后再执行**./redis-trib.rb add-node**指令
查看集群中的结点,刚添加的7008为7007的从节点:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-odVUlZ15-1575983144491)(file:///C:\Users\John\AppData\Local\Temp\msohtmlclip1\01\clip_image046.jpg)]
5.8. 删除结点:
./redis-trib.rb del-node 127.0.0.1:7005 4b45eb75c8b428fbd77ab979b85080146a9bc017
Redis5以后命令:
redis-cli --cluster del-node ip:port node_id
比如:./redis-cli --cluster del-node 10.10.14.166:7006 d3b977fd46386db84fd85b9240deb602087c8617
删除已经占有hash槽的结点会失败,报错如下:
[ERR] Node 127.0.0.1:7005 is not empty! Reshard data away and try again.
需要将该结点占用的hash槽分配出去(参考hash槽重新分配章节)。
5.9. 使用springboot整合RedisCluster
配置文件:application.yml
spring:
redis:
host: www.taotao.com
# port: 6379
# password:
jedis:
pool:
max-idle: 2
max-wait: 1000ms
cluster:
nodes: 10.10.14.166:7001,10.10.14.166:7002,10.10.14.166:7003,10.10.14.166:7004,10.10.14.166:7005,10.10.14.166:7006
测试代码
@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestRedisClient {
@Autowired
private StringRedisTemplate redisTemplate;
@Test
public void testRedis() {
Set<String> keys = redisTemplate.keys("*");
log.info("操作前存在的keys: " + keys);
String key = "lanou_F4";
redisTemplate.opsForList().rightPushAll(key, new String[]{"宋超", "国胜", "国伟", "高飞"});
long size = redisTemplate.opsForList().size(key);
log.info("当前"+key+"值的数量: " + size);
List<String> values = redisTemplate.opsForList().range(key, 0, size);
log.info("当前" + key +"的值: " + values);
keys = redisTemplate.keys("*");
log.info("操作后存在的keys: " + keys);
}
}
6. Redis持久化策略
6.1 RDB快照模式
缺省情况情况下,Redis把数据快照存放在磁盘上的二进制文件中,文件名为dump.rdb。你可以配置Redis的持久化策略,例如数据集中每N秒钟有超过M次更新,就将数据写入磁盘;或者你可以手工调用命令SAVE或BGSAVE。
6.1.1 工作步骤
- Redis forks;
- 子进程开始将数据写到临时RDB文件中;
- 当子进程完成写RDB文件,用新文件替换老文件;
- 当RedisServer重新启动时,读取RDB文件恢复到内存中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LjCEWNHq-1575983144492)(redis-rdb.png)]
6.1.2 配置参数
save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,则dump内存快照。
save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,则dump内存快照。
save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,则dump内存快照。
6.2 AOF模式
快照模式并不十分健壮,当系统停止,或者无意中Redis被kill掉,最后写入Redis的数据就会丢失。这对某些应用也许不是大问题,但对于要求高可靠性的应用来说,
Redis就不是一个合适的选择。
Append-only-file 模式是另一种选择。
你可以在配置文件中打开AOF模式
6.2.1 工作步骤
- Redis客户端发送读写命令
- RedisServer接收并执行命令,同时同步记录命令到AOF文件中
- Redis重新启动时读取AOF文件,执行其中每一条指令完成数据恢复
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZgTXkIAt-1575983144492)(redis-aof.png)]
6.2.2 配置参数
# appendfsync always # 命令过来后,立刻写入AOF文件(会强制flush操作系统IO缓冲)
appendfsync everysec # 默认策略, 每秒钟将缓存的命令写入到AOF文件中
# appendfsync no # 关闭AOF备份
6.3 RDB模式与AOF模式的对比
6.3.1 RDB模式的优点
- 一旦采用该方式,那么你的整个Redis数据库将只包含一个文件,这对于文件备份而言是非常完美的。比如,你可能打算每个小时归档一次最近24小时的数据,同时还要每天归档一次最近30天的数据。通过这样的备份策略,一旦系统出现灾难性故障,我们可以非常容易的进行恢复。
- 对于灾难恢复而言,RDB是非常不错的选择。因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上。
- 性能最大化。对于Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。
- 相比于AOF机制,如果数据集很大,RDB的启动效率会更高。
6.3.2 RDB模式的缺点
- 如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
- 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。
6.3.3 AOF模式的优点
- 该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。至于无同步,无需多言,我想大家都能正确的理解它。
- 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果我们本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据一致性的问题。
- 如果日志过大,Redis可以自动启用rewrite机制。即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性。
- AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完成数据的重建。
6.3.4 AOF模式的缺点
- 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
- 根据同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效。
二者选择的标准,就是看系统是愿意牺牲一些性能,换取更高的缓存一致性(aof),还是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(rdb)。rdb这个就更有些 eventually consistent的意思了。
如果RDB文件和AOF同时存在,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件完整
7. 系统添加缓存逻辑示例
添加缓存逻辑的原则:缓存逻辑不能影响正常的业务逻辑执行。
7.1. 添加缓存后系统架构
来源:CSDN
作者:一个正在成长的程序猿
链接:https://blog.csdn.net/qq_44256606/article/details/103483028