持久化
RDB(快照)--二进制文件
- 以下满足一项就会触发生成快照
save 900 1 900s改动一次
save 300 10 300改掉10次
save 60 10000 60s改掉10000次
AOF
将客户端执行的修改数据的命令存储到appendonly.aof
- 策略
- appendfsync always(每修改一次则写入文件)
- appendfsync everysec(每s将缓存中命令写入以上文件)
- appendfsync no
appendonly.aof 文件存储方式为RESP
redis-aof-resp.png
*3-------->set key value (命令字符串个数)
13
family:member
$1
3
ps rdb 和aof区别:rdb恢复较快,aof恢复数据完整(关注数据完整性)
aof 重写:为了优化恢复数据速度
- 重写方式
- auto-aof-rewrite-min-size:64mb(达到64mb重写)
- auto-aof-rewrite-pencentage:100(文件大小增长了100%重写)
- 手动重写:bgrewriteaof(使用fork子进程执行,对其他命令不影响)
混合持久化(redis4.0)
配置:aof-use-rdb-preamble yes
重写时,以rdb形式写入appendonly.aof中。重写完成之后,之后的修改命令以aof形式存储。(resp形式存储)
Redis 集群
主从模式
主从工作原理:
redis主从复制.png
复制原理:
- 2.8版本开始支持部分复制:master和slave都维护了复制数据下标offset和master的进程id,以此进行部分复制。
如果进程id变了或者offset太旧,不在缓存队列里,则进行全量数据复制
-2.8版本之后开始使用PSYNC进行主从复制
主从搭建:
伪主从:在一台机器上搭建多个实例
- 复制redis.conf
- 修改端口号
port 6380 - 修改进程路径
pidfile /var/run/redis_6380.pid(windows下无需修改) - 修改日志路径
logfile "6380.log" - 修改数据存储路径
dir /usr/local/redis/data/6380 - 配置主从信息
replicaof 127.0.0.1 6379(windows 下为slaveof 127.0.0.1 6379)
replica-read-only yes (windows 下为slave-read-only yes )
6.启动从节点
7.连接从节点
哨兵(Sentinel)模式(进程)
- 解决了主从复制:当master宕机之后,需要人工切换主服务器的问题
通常为1主2从3哨兵
主观下线
当一个哨兵发现master不可用时,不会马上进行failover
客观下线
当其他哨兵都检测到master不可用,大于某个值时,哨兵直接进行投票,选出一个slave升级为master。并有一个哨兵将此消息发送给其他slave,致使slave自动修改配置文件
哨兵搭建
- 1主2从搭建和主从搭建一致
- 3哨兵搭建:新建三个文件()
sentinel1.conf
port 26379
bind 127.0.0.1
sentinel monitor mymaster 127.0.0.1 6379 1
sentinel2.conf
port 26380
bind 127.0.0.1
sentinel monitor mymaster 127.0.0.1 6379 1
sentinel3.conf
port 26381
bind 127.0.0.1
sentinel monitor mymaster 127.0.0.1 6379 1
sentinel monitor mymaster 127.0.0.1 6379 2(取哨兵一半+1)
- 启动1主2从3哨兵
哨兵启动方式:
1 redis-server.exe sentinel3.conf --sentinel
2 redis-sentinel redis-sentinel.conf
springboot StringRedisTemplate和RedisTemplate
StringRedisTemplate继承RedisTemplate,区别在于StringRedisTemplate采用string序列化。RedisTemplate采用java序列化
Cluster 集群模式
- 解决哨兵模式:每个服务器保存数据都一致的问题
集群的原理:(集群的主从是不支持主从读写的)
crc16%16384===crc16&(16384-1)
- 客户端发送一条错误指令:服务端发现key的slot不归自己管理,则像客户端发送跳转指令(包括目标地址)。客户端收到后,则连接目标服务器。同时更新映射表缓存,后续所有key将使用新的映射表缓存
- 集群之间通信机制
- 集中式(zookeeper,dubbo)
- gossip 通信协议(集群之间通信协议)最终一致,内部通信的节点端口号+10000
- cluster-node-timeout (设置节点超时时间)
集群选举
- slave 发现master failover
- slave 往其他主从发送,其他master发送ack给从节点。
- 一个slave收到一半以上的ack,则这个slave变为master。
- slave 发送pong 广播给其他节点。
- 如果slave获取到的ack一样,则重新选举。那么如果规避以上情况,redis进行延迟选举公示
- Delay = 500ms+random(0-500ms)+slave_rank*1000ms
slave_rank: 表示复制master的总量范围,越小,说明slave同步更多。这种方式下,持有最新数据的slave将会首先发起选举。
脑裂问题
- 描述: 集群中一主节点a与其从节点或者其他主从网络不通。同时,客户端往a不断请求命令,并且其他节点已经选择出了一个主节点。此时可能导致大部分数据丢失。(同时有两个主节点)
- 规避办法: 在配置添加 min-slave-to-write 1 (当该主节点没有从节点,则没有办法写成功)
集群对批处理命令的执行如下:
mset name zhuge age 18(不成功)
mset {user1}:1:name zhege {user1}:2:age 18