Redis 哨兵高模式搭建及Java代码配置
时间:2021-09-18 08:14:32|栏目:Redis|点击: 次
准备配置文件
# 配置文件进行了精简,完整配置可自行和官方提供的完整conf文件进行对照。端口号自行对应修改 # 后台启动的意思 daemonize yes # 端口号 port 6380 # IP绑定,redis不建议对公网开放,直接绑定0.0.0.0没毛病 bind 0.0.0.0 # redis数据文件存放的目录 dir /usr/local/redis/data # 开启AOF appendonly yes # 开启集群 cluster-enabled yes # 会自动生成在上面配置的dir目录下 cluster-config-file nodes-6381.conf cluster-node-timeout 5000 # 这个文件会自动生成 pidfile /var/run/redis_6381.pid
分别准备三个server的配置文件
[root@hadoop-master conf]# ll |grep redis | grep -v 6379 -rw-r--r-- 1 root root 489 7月 28 14:49 redis-6380.conf -rw-r--r-- 1 root root 571 7月 28 18:09 redis-6381.conf -rw-r--r-- 1 root root 600 7月 28 18:09 redis-6382.conf
启动三个server
#使用 redis-server 命令,并指定配置文件 /mnt/redis/bin/redis-server /mnt/redis/conf/redis-6380.conf /mnt/redis/bin/redis-server /mnt/redis/conf/redis-6381.conf /mnt/redis/bin/redis-server /mnt/redis/conf/redis-6382.conf
配置主从
#通过 redis-cli客户端命令将指定端口下的服务作为指定ip端口下的从属节点 /mnt/redis/bin/redis-cli -p 6381 192.168.16.40 6380 /mnt/redis/bin/redis-cli -p 6382 192.168.16.40 6380 #此时6380为主节点其他节点为从属节点
检查集群是否已经就绪
# 此命令可查看redis集群中的 server/Clients/memory/persistence/stats # replication/cpu/modules/cluster/keyspace等信息 /mnt/redis/bin/redis-cli -p 6380 info # 通过指定replication获取集群信息 /mnt/redis/bin/redis-cli -p 6380 info replication
redis-cli info 命令各数值含义对照
# Server redis_version:3.2.0 #redis 版本 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:85def9ed04ebeee4 redis_mode:cluster #运行模式(standalone,cluster) os:Linux 3.0.13-0.27-default x86_64 #运行系统内核版本 arch_bits:64 #字长 multiplexing_api:epoll #Redis使用的事件处理机制 gcc_version:4.3.4 #编译Redis时所使用的GCC版本 process_id:26327 #Redis进程PID run_id:e833bf79e98daa5b5917c510b4d9f056cfc5059c #Redis服务器的编号(用于集群) tcp_port:7001 #监听的端口 uptime_in_seconds:587882 #已运行秒数 uptime_in_days:6 #已运行天数 hz:10 #用于执行后台任务的函数被调用的频率 lru_clock:10570417 #用于LRU管理的计时器,单位为分钟 executable:/home/rediscluster/7001/redis/./bin/redis-server #bin文件位置 config_file:/home/rediscluster/7001/redis/./config/redis.conf #配置文件位置 # Clients connected_clients:1 #连接的客户端数 client_longest_output_list:0 #当前客户端连接中最长的输出列表 client_biggest_input_buf:0 #当前客户端连接中最大的输入缓存 blocked_clients:0 #阻塞的客户端数 # Memory used_memory:2421816 #消耗的内存 used_memory_human:2.31M used_memory_rss:3973120 #操作系统分配给Redis的内存 used_memory_rss_human:3.79M used_memory_peak:2421816 #内存消耗的峰值 used_memory_peak_human:2.31M total_system_memory:8250241024 #系统总内存 total_system_memory_human:7.68G used_memory_lua:37888 #Lua脚本消耗的内存 used_memory_lua_human:37.00K maxmemory:0 #内存使用限制 maxmemory_human:0B maxmemory_policy:noeviction #超出内存限制时的行为 mem_fragmentation_ratio:1.64 #内存碎片率(=used_memory_rss/used_memory) mem_allocator:jemalloc-4.0.3 #内存分配器 # Persistence loading:0 #是否正在载入持久化文件 rdb_changes_since_last_save:0 #上次持久化以来修改的键值数 rdb_bgsave_in_progress:0 #是否正在后台保存RDB文件 rdb_last_save_time:1469670746 #上次RDB持久化的时间戳 rdb_last_bgsave_status:ok #上次RDB持久化的结果 rdb_last_bgsave_time_sec:0 #上次创建RDB文件消耗的秒数 rdb_current_bgsave_time_sec:-1 #如果正在创建RDB文件,记录已经消耗了多少时间 aof_enabled:1 #是否启用AOF持久化 aof_rewrite_in_progress:0 #是否正在重写AOF文件 aof_rewrite_scheduled:0 #是否将要重写AOF文件 aof_last_rewrite_time_sec:-1 #上次AOF重写消耗的时间 aof_current_rewrite_time_sec:-1 #当前AOF重写已消耗的时间 aof_last_bgrewrite_status:ok #上次重写AOF文件的结果 aof_last_write_status:ok #上次写入AOF文件的结果 aof_current_size:54 #当前AOF文件的大小 aof_base_size:0 #上一个AOF文件的大小 aof_pending_rewrite:0 #是否有AOF重写操作在等待RDB文件的创建 aof_buffer_length:0 #AOF写入缓冲区大小 aof_rewrite_buffer_length:0 #AOF重写缓冲区大小 aof_pending_bio_fsync:0 #正在I/O队列中等待的fsync()的数量 aof_delayed_fsync:0 #被延迟执行的fsync()的数量 # Stats total_connections_received:9 #服务器已接受的连接请求数 total_commands_processed:586729 #服务器已经执行的命令数量 instantaneous_ops_per_sec:1 #当前每秒执行的命令数量 total_net_input_bytes:22855989 #接受的数据包总大小 total_net_output_bytes:849760 #发送的数据包总大小 instantaneous_input_kbps:0.05 #当前下行速率 instantaneous_output_kbps:0.01 #当前上行速率 rejected_connections:0 #被拒绝的连接请求数 sync_full:1 #主从同步状态 sync_partial_ok:0 sync_partial_err:0 expired_keys:0 #过期的键数 evicted_keys:0 #因内存达到上限被剔除的键数 keyspace_hits:0 #命中key的次数 keyspace_misses:0 #未命中的次数 pubsub_channels:0 #当前被订阅的频道和模式数 pubsub_patterns:0 latest_fork_usec:640 #最后一次fork()消耗的毫秒数 migrate_cached_sockets:0 #为节点迁移缓存的TCP连接数 # Replication role:master #主节点还是从节点 connected_slaves:1 #已连接的从节点数 slave0:ip=127.0.0.1,port=7004,state=online,offset=821435,lag=1 #从节点信息 ip 端口 数据新度等 master_repl_offset:821435 #主节点数据新度 repl_backlog_active:1 #是否为主从同步启用积压空间 repl_backlog_size:1048576 #积压空间大小 repl_backlog_first_byte_offset:2 #积压空间开头的数据新度 repl_backlog_histlen:821434 #积压空间当前数据量 # CPU used_cpu_sys:255.39 #核心态CPU时间 used_cpu_user:257.42 #用户态CPU时间 used_cpu_sys_children:0.00 #子进程核心态CPU时间 used_cpu_user_children:0.00 #子进程用户态CPU时间 # Cluster cluster_enabled:1 #是否启用集群 # Keyspace db0:keys=1,expires=0,avg_ttl=0 #各数据库的键数、过期键数、数据库中键的平均过期时间戳估测值
准备哨兵配置文件(3个节点)
# 配置文件:sentinel.conf,在sentinel运行期间是会被动态修改的 # sentinel如果重启时,根据这个配置来恢复其之前所监控的redis集群的状态 # 绑定IP bind 0.0.0.0 # 后台运行 daemonize yes # 默认yes,没指定密码或者指定IP的情况下,外网无法访问 protected-mode no # 哨兵的端口,客户端通过这个端口来发现redis port 26380 # 哨兵自己的IP,手动设定也可自动发现,用于与其他哨兵通信 # sentinel announce-ip # 临时文件夹 dir "/tmp" # 日志 logfile "/mnt/redis/logs/sentinel-26380.log" # sentinel监控的master的名字叫做mymaster,初始地址为 192.168.16.40 6380,2代表两个及以上哨兵认定为死亡,才认为是真的死亡 sentinel myid fa62676c970da6800e30b28b9cc732e2cee85952 # 发送心跳PING来确认master是否存活 # 如果master在“一定时间范围”内不回应PONG 或者是回复了一个错误消息,那么这个sentinel会主观地(单方面地)认为这个master已经不可用了 sentinel deny-scripts-reconfig yes # 如果在该时间(ms)内未能完成failover操作,则认为该failover失败 sentinel monitor mymaster 192.168.16.40 6381 2 # 指定了在执行故障转移时,最多可以有多少个从Redis实例在同步新的主实例,在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长 sentinel down-after-milliseconds mymaster 1000
增加三个配置文件
[root@hadoop-master conf]# ll | grep sentinel -rw-r--r-- 1 root root 1989 7月 28 18:09 sentinel-26380.conf -rw-r--r-- 1 root root 1989 7月 28 18:09 sentinel-26381.conf -rw-r--r-- 1 root root 1989 7月 28 18:09 sentinel-26382.conf
启动哨兵节点
# 可使用redis-server + sentinel参数启动 /mnt/redis/bin/redis-server /mnt/redis/conf/sentinel-26380.conf --sentinel /mnt/redis/bin/redis-server /mnt/redis/conf/sentinel-26381.conf --sentinel /mnt/redis/bin/redis-server /mnt/redis/conf/sentinel-26382.conf --sentinel # 直接使用redis-sentinel启动 /mnt/redis/bin/redis-sentinel /mnt/redis/conf/sentinel-26380.conf /mnt/redis/bin/redis-sentinel /mnt/redis/conf/sentinel-26381.conf /mnt/redis/bin/redis-sentinel /mnt/redis/conf/sentinel-26382.conf
# 停掉master,主从切换过程
启动哨兵(客户端通过哨兵发现Redis实例信息)
哨兵通过连接master发现主从集群内的所有实例信息
哨兵监控redis实例的健康状况
哨兵一旦发现master不能正常提供服务,则通知给其他哨兵
当一定数量的哨兵都认为master挂了
选举一个哨兵作为故障转移的执行者
执行者在slave中选取一个作为新的master
将其他slave重新设定为新master的从属
# 因为6380的端口是主节点 [root@hadoop-master bin]# ps -ef | grep redis| grep 6380 root 30325 1 0 19:09 ? 00:00:00 /mnt/redis/bin/redis-server 0.0.0.0:6380 root 30415 1 0 19:10 ? 00:00:01 /mnt/redis/bin/redis-sentinel 0.0.0.0:26380 [sentinel] [root@hadoop-master bin]# kill -9 30325
从日志中分析哨兵间的通信及新mater的生成
####################################启动日志####################################### 31551:X 28 Jul 2020 19:35:23.289 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 31551:X 28 Jul 2020 19:35:23.289 # Redis version=6.0.5, bits=64, commit=00000000, modified=0, pid=31551, just started 31551:X 28 Jul 2020 19:35:23.289 # Configuration loaded 31552:X 28 Jul 2020 19:35:23.293 * Running mode=sentinel, port=26380. 31552:X 28 Jul 2020 19:35:23.293 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. 31552:X 28 Jul 2020 19:35:23.294 # Sentinel ID is fa62676c970da6800e30b28b9cc732e2cee85952 31552:X 28 Jul 2020 19:35:23.294 # +monitor master mymaster 192.168.16.40 6380 quorum 2 31552:X 28 Jul 2020 19:35:24.344 # +sdown sentinel 4cabf69629c1401289b6d3d239eba18b45da0041 192.168.16.40 26381 @ mymaster 192.168.16.40 6380 31552:X 28 Jul 2020 19:35:24.345 # +sdown sentinel 20d8240e06a10cd887b752026c00de0318761eb8 192.168.16.40 26382 @ mymaster 192.168.16.40 6380 31552:X 28 Jul 2020 19:35:26.471 # -sdown sentinel 4cabf69629c1401289b6d3d239eba18b45da0041 192.168.16.40 26381 @ mymaster 192.168.16.40 6380 31552:X 28 Jul 2020 19:35:29.621 # -sdown sentinel 20d8240e06a10cd887b752026c00de0318761eb8 192.168.16.40 26382 @ mymaster 192.168.16.40 6380 ####################################杀掉主节点之后日志1################################### 31552:X 28 Jul 2020 19:37:42.950 # +sdown master mymaster 192.168.16.40 6380 31552:X 28 Jul 2020 19:37:43.018 # +new-epoch 3 31552:X 28 Jul 2020 19:37:43.019 # +vote-for-leader 4cabf69629c1401289b6d3d239eba18b45da0041 3 31552:X 28 Jul 2020 19:37:44.023 # +odown master mymaster 192.168.16.40 6380 #quorum 3/2 31552:X 28 Jul 2020 19:37:44.023 # Next failover delay: I will not start a failover before Tue Jul 28 19:37:49 2020 31552:X 28 Jul 2020 19:37:44.098 # +config-update-from sentinel 4cabf69629c1401289b6d3d239eba18b45da0041 192.168.16.40 26381 @ mymaster 192.168.16.40 6380 31552:X 28 Jul 2020 19:37:44.098 # +switch-master mymaster 192.168.16.40 6380 192.168.16.40 6381 31552:X 28 Jul 2020 19:37:44.098 * +slave slave 192.168.16.40:6382 192.168.16.40 6382 @ mymaster 192.168.16.40 6381 31552:X 28 Jul 2020 19:37:44.098 * +slave slave 192.168.16.40:6380 192.168.16.40 6380 @ mymaster 192.168.16.40 6381 31552:X 28 Jul 2020 19:37:45.169 # +sdown slave 192.168.16.40:6380 192.168.16.40 6380 @ mymaster 192.168.16.40 6381 ####################################杀掉主节点之后日志2################################### 31557:X 28 Jul 2020 19:37:42.952 # +sdown master mymaster 192.168.16.40 6380 31557:X 28 Jul 2020 19:37:43.014 # +odown master mymaster 192.168.16.40 6380 #quorum 2/2 31557:X 28 Jul 2020 19:37:43.014 # +new-epoch 3 31557:X 28 Jul 2020 19:37:43.014 # +try-failover master mymaster 192.168.16.40 6380 31557:X 28 Jul 2020 19:37:43.016 # +vote-for-leader 4cabf69629c1401289b6d3d239eba18b45da0041 3 31557:X 28 Jul 2020 19:37:43.019 # fa62676c970da6800e30b28b9cc732e2cee85952 voted for 4cabf69629c1401289b6d3d239eba18b45da0041 3 31557:X 28 Jul 2020 19:37:43.019 # 20d8240e06a10cd887b752026c00de0318761eb8 voted for 4cabf69629c1401289b6d3d239eba18b45da0041 3 31557:X 28 Jul 2020 19:37:43.087 # +elected-leader master mymaster 192.168.16.40 6380 31557:X 28 Jul 2020 19:37:43.087 # +failover-state-select-slave master mymaster 192.168.16.40 6380 31557:X 28 Jul 2020 19:37:43.140 # +selected-slave slave 192.168.16.40:6381 192.168.16.40 6381 @ mymaster 192.168.16.40 6380 31557:X 28 Jul 2020 19:37:43.140 * +failover-state-send-slaveof-noone slave 192.168.16.40:6381 192.168.16.40 6381 @ mymaster 192.168.16.40 6380 31557:X 28 Jul 2020 19:37:43.216 * +failover-state-wait-promotion slave 192.168.16.40:6381 192.168.16.40 6381 @ mymaster 192.168.16.40 6380 31557:X 28 Jul 2020 19:37:44.023 # +promoted-slave slave 192.168.16.40:6381 192.168.16.40 6381 @ mymaster 192.168.16.40 6380 31557:X 28 Jul 2020 19:37:44.023 # +failover-state-reconf-slaves master mymaster 192.168.16.40 6380 31557:X 28 Jul 2020 19:37:44.097 * +slave-reconf-sent slave 192.168.16.40:6382 192.168.16.40 6382 @ mymaster 192.168.16.40 6380 31557:X 28 Jul 2020 19:37:45.095 * +slave-reconf-inprog slave 192.168.16.40:6382 192.168.16.40 6382 @ mymaster 192.168.16.40 6380 31557:X 28 Jul 2020 19:37:45.095 * +slave-reconf-done slave 192.168.16.40:6382 192.168.16.40 6382 @ mymaster 192.168.16.40 6380 31557:X 28 Jul 2020 19:37:45.172 # -odown master mymaster 192.168.16.40 6380 31557:X 28 Jul 2020 19:37:45.172 # +failover-end master mymaster 192.168.16.40 6380 31557:X 28 Jul 2020 19:37:45.172 # +switch-master mymaster 192.168.16.40 6380 192.168.16.40 6381 31557:X 28 Jul 2020 19:37:45.172 * +slave slave 192.168.16.40:6382 192.168.16.40 6382 @ mymaster 192.168.16.40 6381 31557:X 28 Jul 2020 19:37:45.172 * +slave slave 192.168.16.40:6380 192.168.16.40 6380 @ mymaster 192.168.16.40 6381 31557:X 28 Jul 2020 19:37:46.226 # +sdown slave 192.168.16.40:6380 192.168.16.40 6380 @ mymaster 192.168.16.40 6381 ####################################杀掉主节点之后日志3################################### 31563:X 28 Jul 2020 19:37:42.970 # +sdown master mymaster 192.168.16.40 6380 31563:X 28 Jul 2020 19:37:43.018 # +new-epoch 3 31563:X 28 Jul 2020 19:37:43.019 # +vote-for-leader 4cabf69629c1401289b6d3d239eba18b45da0041 3 31563:X 28 Jul 2020 19:37:43.023 # +odown master mymaster 192.168.16.40 6380 #quorum 3/2 31563:X 28 Jul 2020 19:37:43.023 # Next failover delay: I will not start a failover before Tue Jul 28 19:37:49 2020 31563:X 28 Jul 2020 19:37:44.098 # +config-update-from sentinel 4cabf69629c1401289b6d3d239eba18b45da0041 192.168.16.40 26381 @ mymaster 192.168.16.40 6380 31563:X 28 Jul 2020 19:37:44.098 # +switch-master mymaster 192.168.16.40 6380 192.168.16.40 6381 31563:X 28 Jul 2020 19:37:44.098 * +slave slave 192.168.16.40:6382 192.168.16.40 6382 @ mymaster 192.168.16.40 6381 31563:X 28 Jul 2020 19:37:44.098 * +slave slave 192.168.16.40:6380 192.168.16.40 6380 @ mymaster 192.168.16.40 6381 31563:X 28 Jul 2020 19:37:45.124 # +sdown slave 192.168.16.40:6380 192.168.16.40 6380 @ mymaster 192.168.16.40 6381
哨兵同步pubsub机制发出来的消息
# https://redis.io/topics/sentinel#pubsub-messages +reset-master <instance details> -- 当master被重置时. +slave <instance details> -- 当检测到一个slave并添加进slave列表时. +failover-state-reconf-slaves <instance details> -- Failover状态变为reconf-slaves状态时 +failover-detected <instance details> -- 当failover发生时 +slave-reconf-sent <instance details> -- sentinel发送SLAVEOF命令把它重新配置时 +slave-reconf-inprog <instance details> -- slave被重新配置为另外一个master的slave,但数据复制还未发生时。 +slave-reconf-done <instance details> -- slave被重新配置为另外一个master的slave并且数据复制已经与master同步时。 -dup-sentinel <instance details> -- 删除指定master上的冗余sentinel时 (当一个sentinel重新启动时,可能会发生这个事件). +sentinel <instance details> -- 当master增加了一个sentinel时。 +sdown <instance details> -- 进入SDOWN状态时; -sdown <instance details> -- 离开SDOWN状态时。 +odown <instance details> -- 进入ODOWN状态时。 -odown <instance details> -- 离开ODOWN状态时。 +new-epoch <instance details> -- 当前配置版本被更新时。 +try-failover <instance details> -- 达到failover条件,正等待其他sentinel的选举。 +elected-leader <instance details> -- 被选举为去执行failover的时候。 +failover-state-select-slave <instance details> -- 开始要选择一个slave当选新master时。 +no-good-slave <instance details> -- 没有合适的slave来担当新master +selected-slave <instance details> -- 找到了一个适合的slave来担当新master +promoted-slave -- 确认成功 +failover-state-reconf-slaves -- 开始对slaves进行reconfig操作 +slave-reconf-sent -- 向指定的slave发送“slaveof”指令,告知此slave跟随新的master +slave-reconf-inprog -- 此slave正在执行slaveof + SYNC过程,slave收到“+slave-reconf-sent”之后将会执行slaveof操作 +slave-reconf-done -- 此slave同步完成,此后leader可以继续下一个slave的reconfig操作 failover-state-send-slaveof-noone <instance details> -- 当把选择为新master的slave的身份进行切换的时候。 failover-end-for-timeout <instance details> -- failover由于超时而失败时。 failover-end <instance details> -- failover成功完成,故障转移结束 switch-master <master name> <oldip> <oldport> <newip> <newport> -- 当master的地址发生变化时。通常这是客户端最感兴趣的消息了。 +tilt -- 进入Tilt模式。
至此,Redis哨兵模式基本上可以健壮运行了。
Java使用哨兵模式
@Configuration publicclass SentinelRedisAppConfig { @Bean public LettuceConnectionFactory redisConnectionFactory() { System.out.println("使用哨兵版本"); RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration() .master("mymaster") // 哨兵地址 .sentinel("192.168.16.40", 26380) .sentinel("192.168.16.40", 26381) .sentinel("192.168.16.40", 26381); return new LettuceConnectionFactory(sentinelConfig); } }