Redis的架构运行模式:单机模式、主从模式、哨兵模式、集群模式等。
只有一个Redis,启动起来,业务调用即可,单机在很多场景也是有使用的,例如在一个并非必须保证高可用的情况下。
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。
前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。
主从模式配置很简单,只需要在从节点配置主节点的ip和端口号即可。
slaveof # 例如# slaveof 192.168.1.214 6379
replicaof # 例如# replicaof 192.168.1.214 6379
启动主从节点的所有服务,查看日志即可以看到主从节点之间的服务连接。
从上面很容易就想到一个问题,既然主从复制,意味着master和slave的数据都是一样的,有数据冗余问题。
在程序设计上,为了高可用性和高性能,是允许有冗余存在的。这点希望大家在设计系统的时候要考虑进去,不用为公司节省这一点资源。
对于追求极致用户体验的产品,是绝对不允许有宕机存在的。
主从模式在很多系统设计时都会考虑,一个master挂在多个slave节点,当master服务宕机,会选举产生一个新的master节点,从而保证服务的高可用性。
一旦主节点宕机,从节点作为主节点的备份可以随时顶上来。扩展主节点的读能力,分担主节点读压力。
高可用基石:除了上述作用以外,主从复制还是哨兵模式和集群模式能够实施的基础,因此说主从复制是Redis高可用的基石。也有相应的缺点,比如我刚提到的数据冗余问题:
为了解决主从复制的诸多弊端,Redis出现了哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。
哨兵节点由两部分组成,哨兵节点和数据节点:
访问redis集群的数据都是通过哨兵集群的,哨兵监控整个redis集群。
一旦发现redis集群出现了问题,比如刚刚说的主节点挂了,从节点会顶上来。但是主节点地址变了,这时候应用服务无感知,也不用更改访问地址,因为哨兵才是和应用服务做交互的。
主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。
每个Sentinel以 每秒钟 一次的频率,向它所有的主服务器、从服务器以及其他Sentinel实例 发送一个PING 命令。
如果某一个实例(instance)距离最后一次有效回复PING命令的时间超过 down-after-milliseconds 所指定的值,那么这个实例会被 Sentinel标记为主观下线。
如果一个主服务器被标记为 主观下线,那么正在监视这个主服务器的所有 Sentinel节点,要以每秒一次的频率确认,该主服务器是否的确进入了主观下线状态。
如果一个主服务器 被标记为 主观下线,并且有 足够数量的 Sentinel(至少要达到配置文件指定的数量)在指定的 时间范围内同意这一判断,那么这个该主服务器被标记为 客观下线。
在一般情况下, 每个 Sentinel 会以每10秒一次的频率,向它已知的所有主服务器和从服务器 发送 INFO 命令。
当一个 主服务器被 Sentinel标记为 客观下线 时,Sentinel向下线主服务器的所有从服务器 发送 INFO 命令的频率,会从10秒一次改为每秒一次。
Sentinel和其他 Sentinel 协商 主节点的状态,如果 主节点处于 SDOWN`状态,则投票自动选出新的主节点。将剩余的 从节点 指向 新的主节点 进行 数据复制。
当没有足够数量的 Sentinel 同意 主服务器 下线时, 主服务器 的 客观下线状态就会被移除。当 主服务器 重新向 Sentinel的PING命令返回 有效回复 时,主服务器 的 主观下线状态 就会被移除。
Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:
主:6379 ,sentinel:26379
从:6380 ,sentinel:26380
从:6381 ,sentinel:26381
一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控,各个哨兵之间还会进行监控,这样就形成了多哨兵模式。
当主宕机了从接替主成为新的主,宕机的主启动后自动变成了从,其实它和Mysql的双主模式是一样的互为主从;redis哨兵需要用到redis-sentinel程序和sentinel.conf配置文件。
vim redis.conf
daemonize yes
pidfile /usr/local/redis/6379/redis_6379.pid
port 6379
tcp-backlog 128
timeout 0
tcp-keepalive 0
loglevel notice
logfile ""
databases 16
save 900 1 ###save
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb ###dbfile
dir "/usr/local/redis/6379"
masterauth "123456"
requirepass "123456"
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
bind 0.0.0.0
requirepass "123456"
配置Redis服务器,从服务器比主服务器多一个slaveof/replicaof的配置和密码。
replicaof/slaveof 192.168.11.128 6379
注意:有关replicaof/slaveof的配置只是配置从服务器,主服务器不需要配置
masterauth 123456
protected-mode no
sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,192.168.11.128代表监控的主服务器,6379代表端口,2代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作。
sentinel monitor mymaster 192.168.11.128 6379 2
sentinel auth-pass mymaster 123456
mymaster是服务名称,123456是Redis服务器密码
可以登入哨兵(两台哨兵都需要登入执行),添加主从监控信息
redis-cli -p 6000
sentinel monitor mymaster 192.168.137.40 6379 2
sentinel set mymaster down-after-milliseconds 5000
sentinel set mymaster failover-timeout 15000
sentinel set mymaster auth-pass 123456
vim sentinel.conf
port 6000
dir "/usr/local/redis/sentinel"
# 守护进程模式
daemonize yes
protected-mode no
logfile "/usr/local/sentinel/sentinel.log"
应用程序连接到哨兵端口,通过指定不同的master名称连接到具体的主副本。
哨兵配置文件中只需要配置主从复制中的主副本ip和端口即可,当主从进行切换时哨兵会自动修改哨兵配置文件中的主副本ip为新在主副本ip。
一个哨兵配置文件中可以同时配置监控多个主从复制。
单个哨兵就可以用来进行主从故障监控,但是如果只有一个sentinel进程,如果这个进程运行出错,或者是网络堵塞,那么将无法实现redis集群的主备切换(单点问题);这个2代表投票数,当2个sentinel认为一个master已经不可用了以后,将会触发failover,才能真正认为该master已经不可用了。(sentinel集群中各个sentinel也有互相通信,通过gossip协议);所以合理的配置应该是同时启动多个哨兵进程,并且最好是在不同的服务器中启动。
mymaster的需要在整个网络环境都是唯一的,哨兵之间会自动通过mastername去建立关联关系只要网络环境是相通的。
./redis-server ../redis.conf
./redis-sentinel ../sentinel.conf
Sentinel解决了故障转移,在高可用方面又上升了一个台阶,当然Sentinel还有其他功能。比如,主节点存活检测、主从运行情况检测、主从切换。Redis的Sentinel最小配置是 一主一从。
public class TestSentinels {
@SuppressWarnings("resource")
@Test
public void testSentinel() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(10);
jedisPoolConfig.setMaxIdle(5);
jedisPoolConfig.setMinIdle(5);
// 哨兵信息
Set<String> sentinels = new HashSet<>(Arrays.asList("192.168.11.128:26379",
"192.168.11.129:26379","192.168.11.130:26379"));
// 创建连接池
JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels,jedisPoolConfig,"123456");
// 获取客户端
Jedis jedis = pool.getResource();
// 执行两个命令
jedis.set("mykey", "myvalue");
String value = jedis.get("mykey");
System.out.println(value);
}
}
配置项 | 参数类型 | 作用 |
---|---|---|
port | 整数 | 启动哨兵进程端口 |
dir | 文件夹目录 | 哨兵进程服务临时文件夹,默认为/tmp,要保证有可写入的权限 |
sentinel down-after-milliseconds | <服务名称><毫秒数(整数)> | 指定哨兵在监控Redis服务时,当Redis服务在一个默认毫秒数内都无法回答时,单个哨兵认为的主观下线时间,默认为30000(30秒) |
sentinel parallel-syncs | <服务名称><服务器数(整数)> | 指定可以有多少个Redis服务同步新的主机,一般而言,这个数字越小同步时间越长,而越大,则对网络资源要求越高 |
sentinel failover-timeout | <服务名称><毫秒数(整数)> | 指定故障切换允许的毫秒数,超过这个时间,就认为故障切换失败,默认为3分钟 |
sentinel notification-script | <服务名称><脚本路径> | 指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,比较常用 |
配置项只是一个哨兵在超过规定时间依旧没有得到响应后,会自己认为主机不可用。对于其他哨兵而言,并不是这样认为。
哨兵会记录这个消息,当拥有认为主观下线的哨兵达到sentinel monitor所配置的数量时,就会发起一次投票,进行failover,此时哨兵会重写Redis的哨兵配置文件,以适应新场景的需要。
https://blog.csdn.net/yaooch/article/details/80167571
https://www.cnblogs.com/kerwinC/p/6069864.html
https://www.cnblogs.com/chenmh/p/5578376.html
https://baijiahao.baidu.com/s?id=1675905732497463340&wfr=spider&for=pc