redis 配置
常用配置
# 允许连接redis的ip,配置0.0.0.0责允许所有ip连接redis,支持配置多个,用空格分开
#bind 127.0.0.1
bind 0.0.0.0
# 端口号
port 6379
#
protected-mode yes
# 客户端多久空间就断开连接,单位秒,0:关闭
timeout 300
# 用来指定redis是否要用守护线程的方式启动,并将进程pid号写入至redis.conf选项pidfile设置的文件中
daemonize yes
# pid文件的路径
pidfile /var/run/redis_6379.pid
# 日志级别 debug verbose notice warning
loglevel notice
# 日志文件路径
logfile /log/redis.log
# 持久化配置 写入RDB文件的规则 save <seconds> <changes>
# 900秒至少1个key更新
save 900 1
# 300秒至少10个key更新
save 300 10
# 60秒至少10000个key更新
save 60 10000
# rdb文件压缩,开启会增加cpu消耗,减少文件大小
rdbcompression yes
# 日志文件名
dbfilename dump.rdb
# 配置dbfilename,组成日志文件存放路径
dir /data
# 等同于 slaveof masterip masterport ,主从场景下,这里配置master节点的ip和port
replicaof <masterip> <masterport>
# 主节点的密码,从节点连接主节点会用到
masterauth ydyx
# 从节点跟主节点断开之后,是否单独提供服务
# 配置为yes,提供的很可能是过期数据
# 配置为no,会直接报错
replica-serve-stale-data yes
# 从节点只读
replica-read-only yes
redis 持久化
RDB
BGSAVE
命令来创建快照,redis会创建一个子进程来持久化,原进程仅需处理请求。创建快照需要一定的时间,如果在创建快照期间,发生异常(软件或者硬件故障),那么本次快照创建失败,系统只能从上次创建成功的快照进行恢复。RDB模式,只适用于丢失一部分数据不受影响的应用程序。不能接受的应用程序应选用AOF。
RDB配置举例
# 60s内有1000个key发生改变,执行bgsave
save 60 1000
# bgsave 失败后继续写入
stop-writes-on-bgsave-error no
# 是否压缩
rdbcompression yes
# rdb文件名
dbfilename dump.rdb
AOF
默认情况下,Redis异步将数据集转储到磁盘上。 此模式是在许多应用程序中都足够好,但是Redis流程或停电可能会导致几分钟的写入丢失(取决于配置的save points)
AOF是一种替代的持久化模式,可以提供更好的支持
AOF和RDB可以同时存在,如果配置了AOF,那么redis启动的时候回从aof文件恢复数据。
# 开启 aof
appendonly yes
# aof 文件名
appendfilename "appendonly.aof"
# no:让操作系统决定什么时候写入磁盘(性能消耗最小)
# always:每次事务动作都会写入磁盘(性能消耗最大,但是最安全)
# everysec:一秒一次 (折中)
# appendfsync always
appendfsync everysec
# appendfsync no
redis 主从同步
从节点向主节点发送psync请求
- 从服务器通过psync命令发送服务器已有的同步进度(同步源ID、同步进度offset)
- master收到请求,同步源为当前master,则根据偏移量增量同步
- 同步源非当前master,则进入全量同步:master生成rdb,传输到slave,加载到slave内存
核心内容
- Redis 默认使用异步复制,slave 和 master 之间异步地确认处理的数据量
- 一个 master 可以拥有多个 slave
- slave 可以接受其他 slave 的连接。 slave 可以有下级sub slave
- 主从同步过程在 master 侧是非阻塞的
- slave初次同步需要删除旧数据,加载新数据,会阻塞到来的连接请求
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X94or9LY-1592385883348)(C:\Users\zhaoj\AppData\Roaming\Typora\typora-user-images\image-20200609091942214.png)]
应用场景
- 主从复制可以用来支持读写分离
- slave服务器设定为只读,可以用在数据安全的场景下
- 可以使用主从复制来避免 master 持久化造成的开销。master 关闭持久化,slave 配置为不定期 保存或是启用 AOF。(注意:重新启动的 master 程序将从一个空数据集开始,如果一个 slave 试图与它同步,那么这个 slave 也会被清空。 )
注意事项
- 读写分离场景
- 数据复制延时导致读到过期数据或者读不到数据(网络原因、slave阻塞)
- 从节点故障(多个client如何迁移)
- 全量复制情况下
- 第一次建立主从关系或者runid不匹配会导致全量复制
- 故障转移的时候也会出现全量复制
- 复制风暴
- master故障重启,如果slave节点较多,所有slave都要复制,对服务器的性能,网络的压力都有很大影响
- 如果一个机器部署了多个master
- 写能力有限
- 主从复制还是只有一台master,提供的写能力有限
- master故障情况下
- 如果是master无持久化,slave开启持久化来保留数据的场景,建议不要配置redis自动重启
- 启动redis自动重启,master启动后,无备份数据,可能导致集群数据丢失的情况
- 带有效期的key
- slave不会让key过期,而是等待 master 让 key 过期
- 在Lua脚本执行期间,不执行任何 key 过期操作
redis 哨兵机制
我这里的环境有3个redis,3个哨兵
redis的端口号分别是6379, 6380, 6381
sentinel的端口号分别是6382, 26380, 26381
PS C:\Users\zhaoj> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aa0578585c2a redis:latest "docker-entrypoint.s…" 22 hours ago Up 7 hours 6379/tcp, 0.0.0.0:26380->26380/tcp redis-26380
46b2e329c294 redis:latest "docker-entrypoint.s…" 22 hours ago Up 7 hours 6379/tcp, 0.0.0.0:26381->26381/tcp redis-26381
3ead3246ea36 redis:latest "docker-entrypoint.s…" 22 hours ago Up 7 hours 6379/tcp, 0.0.0.0:6382->6382/tcp redis-6382
394e69f6563b redis:latest "docker-entrypoint.s…" 26 hours ago Up 8 hours 6379/tcp, 0.0.0.0:6381->6381/tcp redis-6381
ae6ee635cd89 redis:latest "docker-entrypoint.s…" 26 hours ago Up 8 hours 6379/tcp, 0.0.0.0:6380->6380/tcp redis-6380
b949098bb0b3 redis:latest "docker-entrypoint.s…" 26 hours ago Up 8 hours 0.0.0.0:6379->6379/tcp redis
哨兵配置
# 配置文件在sentinel运行期间是会被动态修改的
# sentinel如果重启时,就可以根据这个配置来恢复其之前所监控的redis集群的状态
# 绑定IP
bind 0.0.0.0
# 默认yes,没指定密码或者指定IP的情况下,外网无法访问
protected-mode yes
# 哨兵的端口,客户端通过这个端口来发现redis
port 26380
# sentinel监控的master的名字叫做mymaster,地址为 60.205.209.106 6380,两个及以上哨兵认定为死亡,才认为是真的死亡
sentinel monitor mymaster 172.25.4.11 6380 2
# 发送心跳PING来确认master是否存活
# 如果master在“一定时间范围”内不回应ping 或者是回复了一个错误消息,那么这个sentinel会主观地(单方面地)认为这个master已经不可用了
sentinel down-after-milliseconds mymaster 1000
# 如果在该时间(ms)内未能完成failover操作,则认为该failover失败
sentinel failover-timeout mymaster 3000
# master密码是ydyx
sentinel auth-pass mymaster ydyx
被自动修改后的配置
# sentinel监控的master的名字叫做mymaster,地址为 172.25.4.11 6379,两个及以上哨兵认定为死亡,才认为是真的死亡
sentinel myid b5d5b9eb15e700232c8eb94eb54f2801af7ee064
# 发送心跳PING来确认master是否存活
# 如果master在“一定时间范围”内不回应ping 或者是回复了一个错误消息,那么这个sentinel会主观地(单方面地)认为这个master已经不可用了
sentinel deny-scripts-reconfig yes
# 如果在该时间(ms)内未能完成failover操作,则认为该failover失败
sentinel monitor mymaster 172.25.4.11 6379 2
# 指定了在执行故障转移时,最多可以有多少个从Redis实例在同步新的主实例,在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长
sentinel down-after-milliseconds mymaster 1000
# Generated by CONFIG REWRITE
user default on #7dbd65975b16b7d8ab525b047118ad68ea8ef635dcdf61f3123c6f3fe1d521a3 ~* +@all
sentinel failover-timeout mymaster 3000
sentinel auth-pass mymaster ydyx
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
sentinel known-replica mymaster 172.17.0.1 6380
sentinel known-replica mymaster 172.17.0.1 6381
sentinel known-sentinel mymaster 172.17.0.7 26381 25c80c2b3befb3f41477dc4f5c4d32f8211d1391
sentinel known-sentinel mymaster 172.17.0.5 6382 f73661bc0596a267ef38636f57bb2dc6f44fb1c1
sentinel current-epoch 0
服务都启动起来
先看下master节点 6379 配置
127.0.0.1:6379> info replication
# Replication
role:master # master节点
connected_slaves:2 # 2个从节点
slave0:ip=172.17.0.1,port=6380,state=online,offset=5447694,lag=0
slave1:ip=172.17.0.1,port=6381,state=online,offset=5447694,lag=0
master_replid:7fb35d451d7a246a2dad34ffc36a349a69647b84 # 数据同步的时候需要这个id
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:5447694 # 偏移量
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:4399119
repl_backlog_histlen:1048576
看一个从节点的配置 6380
127.0.0.1:6380> info replication
# Replication
role:slave # 从节点
master_host:172.25.4.11 # 主节点ip
master_port:6379 # 主节点端口
master_link_status:up # 状态up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:5486897 # 当前偏移量
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:7fb35d451d7a246a2dad34ffc36a349a69647b84 # 同步数据的主节点id
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:5486897
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:4438322
repl_backlog_histlen:1048576
再看下哨兵 26380 的配置
# Sentinel
sentinel_masters:1 # 1个主节点
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=172.25.4.11:6379,slaves=2,sentinels=3 # 主节点ip,2个从节点,3个哨兵
我们现在关掉6379,看下哨兵能不能自动指定新的主节点
PS C:\Users\zhaoj> docker stop redis
redis
PS C:\Users\zhaoj> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aa0578585c2a redis:latest "docker-entrypoint.s…" 22 hours ago Up 8 hours 6379/tcp, 0.0.0.0:26380->26380/tcp redis-26380
46b2e329c294 redis:latest "docker-entrypoint.s…" 22 hours ago Up 8 hours 6379/tcp, 0.0.0.0:26381->26381/tcp redis-26381
3ead3246ea36 redis:latest "docker-entrypoint.s…" 22 hours ago Up 8 hours 6379/tcp, 0.0.0.0:6382->6382/tcp redis-6382
394e69f6563b redis:latest "docker-entrypoint.s…" 26 hours ago Up 8 hours 6379/tcp, 0.0.0.0:6381->6381/tcp redis-6381
ae6ee635cd89 redis:latest "docker-entrypoint.s…" 26 hours ago Up 8 hours 6379/tcp, 0.0.0.0:6380->6380/tcp redis-6380
再看下哨兵 26380 的配置
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=172.17.0.1:6380,slaves=2,sentinels=3 # address已经改成了6380,现在6380是主了,这里的slaves=2是一共2个从节点,并不是2个都可用
看下6380的配置
127.0.0.1:6380> info replication
# Replication
role:master # 主节点
connected_slaves:1 # 1个从节点,6381
slave0:ip=172.17.0.1,port=6381,state=online,offset=5519056,lag=0
master_replid:ef948684350a7b09ef0e739e99f0789eccf21cc1
master_replid2:7fb35d451d7a246a2dad34ffc36a349a69647b84
master_repl_offset:5519460
second_repl_offset:5504796
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:4470885
repl_backlog_histlen:1048576
再次启动6379
PS C:\Users\zhaoj> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aa0578585c2a redis:latest "docker-entrypoint.s…" 22 hours ago Up 8 hours 6379/tcp, 0.0.0.0:26380->26380/tcp redis-26380
46b2e329c294 redis:latest "docker-entrypoint.s…" 22 hours ago Up 8 hours 6379/tcp, 0.0.0.0:26381->26381/tcp redis-26381
3ead3246ea36 redis:latest "docker-entrypoint.s…" 22 hours ago Up 8 hours 6379/tcp, 0.0.0.0:6382->6382/tcp redis-6382
394e69f6563b redis:latest "docker-entrypoint.s…" 26 hours ago Up 9 hours 6379/tcp, 0.0.0.0:6381->6381/tcp redis-6381
ae6ee635cd89 redis:latest "docker-entrypoint.s…" 26 hours ago Up 9 hours 6379/tcp, 0.0.0.0:6380->6380/tcp redis-6380
b949098bb0b3 redis:latest "docker-entrypoint.s…" 26 hours ago Up 2 seconds 0.0.0.0:6379->6379/tcp redis
看下6379的配置
127.0.0.1:6379> info replication
# Replication
role:slave # 现在是从节点了
master_host:172.17.0.1
master_port:6380 # 主节点是6380
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:5586117
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:ef948684350a7b09ef0e739e99f0789eccf21cc1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:5586117
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:5578498
repl_backlog_histlen:7620
哨兵自动帮我们把主节点切换到了6380,之前的主6379重启后,变成了从节点
最后再看一下,哨兵的配置文件被修改成了什么
sentinel myid b5d5b9eb15e700232c8eb94eb54f2801af7ee064
sentinel deny-scripts-reconfig yes
# 现在主节点变成了6380
sentinel monitor mymaster 172.17.0.1 6380 2
sentinel down-after-milliseconds mymaster 1000
# Generated by CONFIG REWRITE
user default on #7dbd65975b16b7d8ab525b047118ad68ea8ef635dcdf61f3123c6f3fe1d521a3 ~* +@all
sentinel failover-timeout mymaster 3000
sentinel auth-pass mymaster ydyx
sentinel config-epoch mymaster 1
sentinel leader-epoch mymaster 1
sentinel known-replica mymaster 172.25.4.11 6379
sentinel known-replica mymaster 172.17.0.1 6379
sentinel known-replica mymaster 172.17.0.1 6381
sentinel known-sentinel mymaster 172.17.0.7 26381 25c80c2b3befb3f41477dc4f5c4d32f8211d1391
sentinel known-sentinel mymaster 172.17.0.5 6382 f73661bc0596a267ef38636f57bb2dc6f44fb1c1
# 纪元 就是版本号 集群每发生一次变化 +1
sentinel current-epoch 1