Docker部署Redis哨兵
哨兵,英文名 Sentinel,是一个分布式系统,用于对主从结构中的每一台服务器进行监控,当主节点出现故障后通过投票机制来挑选新的主节点,并且将所有的从节点连接到新的主节点上。
Redis Sentinel 包含若干个 Sentinel 节点和 Redis 数据节点,每个 Sentinel 节点会对数据节点和其余 Sentinel 节点进行监控,当它发现节点不可达时,会对节点做下线标识。如果被标识的是主节点,它还会和其他 Sentinel 节点进行“协商”,当大多数 Sentinel 节点都认为主节点不可达时,它们会选举出一个 Sentinel 节点来完成自动故障转移的工作,同时会将这个变化实时通知给 Redis 应用方。整个过程完全是自动的,不需要人工来介入,所以这套方案很有效地解决了 Redis 的高可用问题
1. 快速部署主从复制
请参考之前的文章搭建
Docker部署Redis主从复制-CSDN博客文章浏览阅读1.5k次,点赞38次,收藏18次。Redis主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点。默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。docker部署redis,docker部署redis主从复制https://blog.csdn.net/ddf128/article/details/143606905
依照之前的步骤搭建完主从复制后,我们需要再增加一个redis从服务器
创建映射数据卷
[root@192 ~]# mkdir -p /redis/slave2/data
[root@192 ~]# mkdir -p /redis/slave2/conf
[root@192 ~]# cd ..
[root@192 /]# cd redis
[root@192 redis]# ls
master slave slave2
配置文件
vi /redis/slave2/conf/redis.conf# 内容
[root@192 redis]# cat /redis/slave2/conf/redis.conf
# 开启密码验证(可选)
# requirepass xxx# 允许redis外地连接,需要注释掉绑定的IP
bind 0.0.0.0# 关闭保护模式(可选)
protected-mode no# 注释掉daemonize yes,或者配置成 daemonize no。因为该配置和 docker run中的 -d 参数冲突,会导致容器一直启动失败
daemonize no# 开启redis数据持久化, (可选)
appendonly yes# 设置主从复制密码
# redis auth与主从复制密码需要一致
# masterauth xxx# 主从配置 最为重要
replicaof 192.168.1.42 6371
[root@192 redis]#
创建新的redis从容器,并将之前的redis容器启动
docker run --name redis-slave2 --privileged=true \
> -p 6373:6379 \
> -v /redis/slave2/data:/data \
> -v /redis/slave2/conf/redis.conf:/etc/redis/redis.conf \
> -d redis redis-server /etc/redis/redis.conf
测试数据
主机:
从1:
从2:
测试通过后,一主双从的redis复制就部署完成了。流程与之前博文的介绍一样,大家依照操作,很快就能搭建完成。
2.哨兵准备
角色 | IP | 端口 | 服务运行模式 |
哨兵1 | 192.168.1.42 | 26371 | sentinel |
哨兵2 | 192.168.1.42 | 26372 | sentine2 |
哨兵3 | 192.168.1.42 | 26373 | sentine3 |
redis-master | 192.168.1.42 | 6371 | Master |
redis-slave | 192.168.1.42 | 6372 | Slave |
redis-slave2 | 192.168.1.42 | 6373 | Slave |
3.部署哨兵
3.1 创建映射数据卷
mkdir -p /redis/sentine/data_26371
mkdir -p /redis/sentine/data_26372
mkdir -p /redis/sentine/data_26372
vi /redis/sentine/sentinel-26371.conf
vi /redis/sentine/sentinel-26372.conf
vi /redis/sentine/sentinel-26373.conf
修改配置文件
# 设置绑定地址,使之可以被外部访问(绑定哨兵所在机器的ip地址)
bind 0.0.0.0#默认端口
port 26379 # 是否是后台应用程序,默认是no,修改成yes后台启动
daemonize yes #指定别名 主节点地址 端口 哨兵个数(有几个哨兵监控到主节点宕机执行转移)
sentinel monitor mymaster 192.168.1.42 6371 1# 如果哨兵3s内没有收到主节点的心跳,哨兵就认为主节点宕机了,默认是30秒
sentinel down-after-milliseconds mymaster 30000# 选举出新的主节点之后,可以同时连接从节点的个数
sentinel parallel-syncs mymaster 1# 如果10秒后,master仍没活过来,则启动failover,默认180s
sentinel failover-timeout mymaster 180000# 配置连接redis主节点密码(如果需要的话进行配置)
# sentinel auth-pass <master-name> <password>
创建哨兵容器
docker run --privileged=true -p 26371:26379 --name sentinel1 -v /redis/sentine/sentinel-26371.conf:/etc/redis/sentinel.conf -v /redis/sentine/data_26371:/data -it redis /bin/bash
查看配置
root@bd21df7135d7:/etc/redis# cat sentinel.conf
# 设置绑定地址,使之可以被外部访问(绑定哨兵所在机器的ip地址)
bind 0.0.0.0#默认端口
port 26379 # 是否是后台应用程序,默认是no,修改成yes后台启动
daemonize yes #指定别名 主节点地址 端口 哨兵个数(有几个哨兵监控到主节点宕机执行转移)
sentinel monitor mymaster 192.168.1.42 6371 1# 如果哨兵3s内没有收到主节点的心跳,哨兵就认为主节点宕机了,默认是30秒
sentinel down-after-milliseconds mymaster 30000# 选举出新的主节点之后,可以同时连接从节点的个数
sentinel parallel-syncs mymaster 1# 如果10秒后,master仍没活过来,则启动failover,默认180s
sentinel failover-timeout mymaster 180000# 配置连接redis主节点密码(如果需要的话进行配置)
# sentinel auth-pass <master-name> <password>
启动哨兵
root@bd21df7135d7:/etc/redis# redis-sentinel /etc/redis/sentinel.conf
root@bd21df7135d7:/etc/redis# redis-cli -p 26379
127.0.0.1:26379> info
# Server
redis_version:7.4.1
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:2d9a3ca9eee6c85b
redis_mode:sentinel
os:Linux 3.10.0-1160.119.1.el7.x86_64 x86_64
arch_bits:64
monotonic_clock:POSIX clock_gettime
multiplexing_api:epoll
atomicvar_api:c11-builtin
gcc_version:12.2.0
process_id:15
process_supervised:no
run_id:61f76b493e875ccdf7f4feadb62d525f4f1de5e1
tcp_port:26379
server_time_usec:1731421048546568
uptime_in_seconds:20
uptime_in_days:0
hz:16
configured_hz:10
lru_clock:3367800
executable:/etc/redis/redis-sentinel
config_file:/etc/redis/sentinel.conf
io_threads_active:0
listener0:name=tcp,bind=0.0.0.0,port=26379# Clients
connected_clients:1
cluster_connections:0
maxclients:10000
client_recent_max_input_buffer:20480
client_recent_max_output_buffer:0
blocked_clients:0
tracking_clients:0
pubsub_clients:0
watching_clients:0
clients_in_timeout_table:0
total_watched_keys:0
total_blocking_keys:0
total_blocking_keys_on_nokey:0# Stats
total_connections_received:1
total_commands_processed:1
instantaneous_ops_per_sec:0
total_net_input_bytes:41
total_net_output_bytes:30465
total_net_repl_input_bytes:0
total_net_repl_output_bytes:0
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
instantaneous_input_repl_kbps:0.00
instantaneous_output_repl_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_subkeys:0
expired_keys:0
expired_stale_perc:0.00
expired_time_cap_reached_count:0
expire_cycle_cpu_milliseconds:0
evicted_keys:0
evicted_clients:0
evicted_scripts:0
total_eviction_exceeded_time:0
current_eviction_exceeded_time:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
pubsubshard_channels:0
latest_fork_usec:0
total_forks:0
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0
total_active_defrag_time:0
current_active_defrag_time:0
tracking_total_keys:0
tracking_total_items:0
tracking_total_prefixes:0
unexpected_error_replies:0
total_error_replies:0
dump_payload_sanitizations:0
total_reads_processed:2
total_writes_processed:1
io_threaded_reads_processed:0
io_threaded_writes_processed:0
client_query_buffer_limit_disconnections:0
client_output_buffer_limit_disconnections:0
reply_buffer_shrinks:1
reply_buffer_expands:0
eventloop_cycles:341
eventloop_duration_sum:147077
eventloop_duration_cmd_sum:101
instantaneous_eventloop_cycles_per_sec:16
instantaneous_eventloop_duration_usec:446
acl_access_denied_auth:0
acl_access_denied_cmd:0
acl_access_denied_key:0
acl_access_denied_channel:0# CPU
used_cpu_sys:0.057703
used_cpu_user:0.103866
used_cpu_sys_children:0.000000
used_cpu_user_children:0.000000
used_cpu_sys_main_thread:0.057600
used_cpu_user_main_thread:0.103680# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_tilt_since_seconds:-1
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.1.42:6371,slaves=1,sentinels=1
127.0.0.1:26379>
最后我们查看容器状态
现在已经启动一个哨兵了,解下来启动其他2个哨兵
# 第二个哨兵容器
docker run --privileged=true -p 26372:26379 --name sentinel2 -v /redis/sentine/sentinel-26372.conf:/etc/redis/sentinel.conf -v /redis/sentine/data_26372:/data -it redis /bin/bash# 启动操作
root@e3bb6f451ded:/data# redis-sentinel /etc/redis/sentinel.conf
root@e3bb6f451ded:/data# redis-cli -p 26379
127.0.0.1:26379> info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_tilt_since_seconds:-1
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.1.42:6371,slaves=1,sentinels=2
127.0.0.1:26379> # 第三个哨兵容器
docker run --privileged=true -p 26373:26379 --name sentinel3 -v /redis/sentine/sentinel-26373.conf:/etc/redis/sentinel.conf -v /redis/sentine/data_26373:/data -it redis /bin/bash# 启动操作
root@631f954f9a9d:/data# redis-sentinel /etc/redis/sentinel.conf
root@631f954f9a9d:/data# redis-cli -p 26379
127.0.0.1:26379> info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_tilt_since_seconds:-1
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.1.42:6371,slaves=1,sentinels=3
127.0.0.1:26379>
整体容器实例:
4.数据测试
主节点查看复制状态
[root@192 /]# docker exec -it 0e8e2a258de6 /bin/bash
root@0e8e2a258de6:/data# redis-cli
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.17.0.1,port=6379,state=online,offset=177865,lag=0
slave1:ip=172.17.0.1,port=6379,state=online,offset=177865,lag=1
master_failover_state:no-failover
master_replid:430c1d4754e1a4b6ab6cba7bd78194d8511823a7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:177865
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:177865
127.0.0.1:6379>
从节点查看复制状态
[root@192 /]# docker exec -it 09fc1a30508b /bin/bash
root@09fc1a30508b:/data# redis-cli
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.1.42
master_port:6371
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_read_repl_offset:194143
slave_repl_offset:194143
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:430c1d4754e1a4b6ab6cba7bd78194d8511823a7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:194143
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:194143
127.0.0.1:6379>
查看哨兵状态
root@bd21df7135d7:/etc/redis# redis-cli -p 26379
127.0.0.1:26379> info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_tilt_since_seconds:-1
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.1.42:6371,slaves=1,sentinels=3
127.0.0.1:26379>
测试数据复制同步:
主机写入数据
2个从机同步复制数据
故障转移测试
#停止主机
docker stop redis-master
5.常用命令说明
绑定ip地址
bind 0.0.0.0
监听端口
port 26379 -- 默认是26379,可以修改
监听主服务器IP及端口
告诉sentinel去监听地址为ip:port的一个master,这里的master-name可以自定义,quorum是一个数字,指明当有多少个sentinel认为一个master失效时,master才算真#正失效。master-name只能包含英文字母,数字,和“.-_”这三个字符需要注意的是
master-ip 要写真实的ip地址而不要用回环地址(127.0.0.1)。
sentinel monitor <master-name> <ip> <redis-port> <quorum>
# 配置示例:
sentinel monitor mymaster 192.168.0.5 6
设置密码
设置连接master和slave时的密码,注意的是sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同。
注意:主从auth密码需要一致,且主从复制配置模块密码都要配置并与auth相同
sentinel auth-pass <master-name> <password>
# 配置示例:
sentinel auth-pass mymaster 0123passw
5.主观下线时效
这个配置项指定了需要多少失效时间,一个master才会被这个sentinel主观地认为是不可用的。 单位是毫秒,默认为30秒
sentinel down-after-milliseconds <master-name> <milliseconds>
配置示例:
sentinel down-after-milliseconds mymaster 300
主备切换,slave同步个数
这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越# 大,就意味着越多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。
sentinel parallel-syncs <master-name> <numslaves>
配置示例:
sentinel parallel-syncs mymaster 1
故障转移的超时时间
failover-timeout 可以用在以下这些方面:
- 同一个sentinel对同一个master两次failover之间的间隔时间。
- 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那 里同步数据时。
- 当想要取消一个正在进行的failover所需要的时间。
- 当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时, slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了
- 默认三分钟
sentinel failover-timeout <master-name> <milliseconds>
配置示例:
sentinel failover-timeout mymaster 180000
6.最后
感谢大家,请大家多多支持!