Redis哨兵架构(哨兵搭建,哨兵原理)

Posted 脱不下的长衫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis哨兵架构(哨兵搭建,哨兵原理)相关的知识,希望对你有一定的参考价值。

Redis哨兵架构(哨兵搭建,哨兵原理)

sentinel哨兵是特殊的Redis服务,不提供读写服务,主要用来监控redis实例节点,实现自动故障转移

一、Redis哨兵架构搭建

  1. 基于主从架构搭建一主两从架构

  2. 准备开启三个哨兵节点,这里演示安装26379

  3. 复制sentinel.conf到26379目录下(目录自己指定)

  4. 修改sentinel.conf配置

port 26379

daemonize yes

pidfile "/var/run/redis‐sentinel‐26379.pid"

logfile "26379.log"

dir "/usr/local/redis/26379/"

# sentinel monitor <master‐redis‐name> <master‐redis‐ip> <master‐redis‐port> <quorum>
# quorum是一个数字,指明当有多少个seninel(值一般为:sentinel总数/2+1)认为一个master失效时master才算失效
# mymaster 自己定义,客户端访问时需要
sentinel monitor mymaster 192.168.1.110 6379 2
  1. 启动哨兵实例
./bin/redis-sentinel ./26379/sentinel/sentinel.conf
./bin/redis-sentinel ./26380/sentinel/sentinel.conf
./bin/redis-sentinel ./26381/sentinel/sentinel.conf
  1. 查看哨兵是否启动成功
  2. info命令查看哨兵信息
  3. 查看sentinel.conf中的redis节点信息

二、Java中使用哨兵架构

哨兵架构模式中,客户端访问Redis服务,第一次从哨兵服务中获取Redis主节点信息,后续就会直接访问主节点,不会再通过哨兵代理访问,当主节点发送变化后,哨兵会立即将新的主节点信息通知客户端(客户端一般都订阅了哨兵发布的节点变动信息)

  1. 引入依赖
<dependency>
   <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>22.0</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <!-- <scope>test</scope>-->
</dependency>
  1. 测试代码
/**
 * Jedis连接哨兵架构
 */
public class JedisSentinelTest 

    JedisSentinelPool jedisSentinelPool = null;

    @Before
    public void connect()
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(20);
        config.setMaxIdle(10);
        config.setMinIdle(5);

        String masterName = "mymaster";

        Set<String> sentinels = new HashSet<>();
        sentinels.add(new HostAndPort("192.168.1.110",26379).toString());
        sentinels.add(new HostAndPort("192.168.1.110",26380).toString());
        sentinels.add(new HostAndPort("192.168.1.110",26381).toString());

        jedisSentinelPool = new JedisSentinelPool(masterName,sentinels,config,3000,null);

    

    @Test
    public void testSentinel()
        Jedis jedis = null;

        try 
            jedis=jedisSentinelPool.getResource();
            System.out.println(jedis.set("sentinel","1"));
            System.out.println(jedis.get("sentinel"));
         catch (Exception e) 
            e.printStackTrace();
         finally 
            if (jedis!=null)
                jedis.close();
            
        
    


  1. 运行结果

三、哨兵机制原理

1. 哨兵机制解决了什么问题

哨兵主要是为了解决主从复制架构中出现宕机的情况,在主节点出现宕机时,哨兵会自动将主节点下的某个从节点升级为新的主节点

2. 哨兵定时监控

  1. 每个哨兵节点每10秒会向主节点和从节点发送info命令获取最新拓扑结构图,哨兵配置时只需要配置对主节点的监控即可,通过向主节点发送info命令,获取从节点的信息,并且当有新的从节点时可以立马感知到
  2. 每个哨兵节点每2秒会像redis数据节点的指定频道上发送该哨兵节点对于主节点的判断以及当前哨兵节点的信息,同时每个哨兵节点也会订阅该频道,来了解其他哨兵对主节点状态的判断,其实就是通过消息publish/subscribe来完成的
  3. 每一秒每个哨兵会向主节点,从节点,其他哨兵节点发送一次ping命令做一次心跳检测,这个也是哨兵用来判断节点是否正常的重要依据

3. 主观下线与客观下线

3.1 主观下线

主观下线就是单个哨兵认为某个节点下线

哨兵会以每秒一次的频率向所有与其建立连接的实例(主节点,从节点,其他哨兵节点)发送ping命令,通过判断ping回复是否有效,还是无效来判断实例是否在线

3.2 客观下线

当主观下线的节点是主观节点时,认为主节点主观下线的哨兵节点会通过指令sentinel is-masterdown-by-addr寻求其他哨兵节点对主节点的判断,当主观下线的个数超过quorum个数,此时大部分哨兵节点会都同意下线,这就是客观下线

4. 哨兵leader选举流程

主节点被判定为客观下线后,就需要选取一个哨兵节点来完成故障转移的工作,选举哨兵leader的流程如下:

  1. 每个在线的哨兵节点都可以成为leader,当它确认主节点下线后,会向其他哨兵发送is-master-down-by-addr命令,征求判断并要求把自己设置为leader
  2. 其他哨兵接收到这个命令后,可以同意或者拒绝它成为领导者
  3. 如果哨兵发现自己在选举的过程中的票数大于等于(sentinel/2 +1)时,它将成为leader,如果没有,继续选举

5. 自动故障转移

5.1 选择新的主节点

哨兵状态数据结构中保存了主服务的所有从服务的信息,哨兵leader会按照一定的规则选择出一个从节点成为新的主节点,选择规则如下:

  1. 过滤掉主观下线的节点
  2. 选择slave-priority最高的节点,如果有就返回,没有就继续选择
  3. 选择出复制偏移量最大的节点,复制偏移量越大则数据复制的越完整,有则返回,没有则继续
  4. 选择run_id最小的节点

5.2 更新主从状态

通过slaveof no one命令,让选择出来的从节点变为主节点,并通过slaveof命令让其他节点成为从节点
将已下线的主节点设置为新主节点的从节点,当它恢复正常时,从新的主节点复制数据
其他下线的从节点恢复正常时,哨兵会向其发送slaveof命令,让他成为新主的从节点

Redis哨兵(sentinel)

前言

背景:测试环境的redis集群被运维回收,无奈之下只能自己动手,Redis高可用集群架构的搭建。

原理

Redis的哨兵(sentinel)系统用于管理多个redis服务器,该系统执行以下三个任务:

  • 监控(Monitoring):哨兵(sentinel)会不断地检查你的Master和Slave是否运作正常。

  • 提醒(Notification):当被监控的某个Redis出现问题时,哨兵(sentinel)可以通过API向管理员或者其他应用程序发送通知。

  • 自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel)会开始一次自动故障迁移操作,它会将失效Master的其中一个Slave升级为新的Master,并让失效Master的其他Slave改为复制新的Master;当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用Master代替失效Master,客户端实际获取的链接是哨兵返回的。

哨兵(sentinel)是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel)进程,这些进程使用流言协议(gossipprotocols)来接收关于Master是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master。

每个哨兵(sentinel)会向其它哨兵(sentinel)、master、slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定时间(可配置)内未回应,则暂时认为对方已挂(所谓的”主观认为宕机” Subjective Down,简称sdown).

若“哨兵群”中的多数sentinel,都报告某一master没响应,系统才认为该master"彻底死亡"(即:客观上的真正down机,Objective Down,简称odown),通过一定的vote算法,从剩下的slave节点中,选一台提升为master,然后自动修改相关配置.

虽然哨兵(sentinel)释出为一个单独的可执行文件redis-sentinel ,但实际上它只是一个运行在特殊模式下的Redis服务器,你可以在启动一个普通Redis服务器时通过给定--sentinel选项来启动哨兵(sentinel).

哨兵(sentinel)的一些设计思路和zookeeper非常类似。

架构图

下载

首页地址:http://redis.io/

最新稳定版下载地址:http://download.redis.io/releases/redis-3.2.9.tar.gz

# tar -xvf redis-3.2.9.tar.gz

# cd redis-3.2.9

# make install

# make test

命令

redis-server    -h

Usage: ./redis-server [/path/to/redis.conf] [options]

./redis-server - (read config from stdin)

./redis-server -v or --version

./redis-server -h or --help

./redis-server --test-memory

Examples:

./redis-server (run the server with default conf)

./redis-server /etc/redis/6379.conf

./redis-server --port 7777

./redis-server --port 7777 --slaveof 127.0.0.1 8888

./redis-server /etc/myredis.conf --loglevel verbose

Sentinel mode:

./redis-server /etc/sentinel.conf --sentinel

配置

daemonize yes        ###daemon后台运行模式

pidfile /var/run/redis.pid  ###pidfile

port 6379  ###默认6379端口

tcp-backlog 511  ###tcp三次握手等待确认ack最大的队列数

bind 192.168.65.128 127.0.0.1  ###绑定的监听的ip,可同时写多个ip,不写默认监控0.0.0.0

timeout 0  ###关闭空闲客户端,0为disable

tcp-keepalive 0 ###是否开启tcp长连接,定义socket连接timeout时长

loglevel notice  ###定义日志级别为notice(输出必要的日志)

logfile "/var/log/redis/redis.log" ###定义日志输出目录

databases 16  ###允许redis定义的最大的db簇

###开启rdb并应用如下数据保存策略,aof和rdb可同时启用,aof强烈建议开启

save 900 1

save 300 10

save 60 10000

stop-writes-on-bgsave-error yes  ###有任何问题导致的bgsave失败都停止redis的对外服务

rdbcompression yes  ###rdb写压缩

rdbchecksum yes  ###rdb文件正确性检查

dbfilename dump.rdb  ###rdb文件名称(dump.rdb可任意起)

dir /var/lib/redis/    ###rdb文件写目录

# slaveof     ###如果是slave需要写明master

# masterauth     ###master密码验证(因为redis基于内存,作用不大)

slave-serve-stale-data no  ###如果master宕机,slave是否还正常对外服务no->停止服务

slave-read-only yes    ###salve是否只读(默认只读)
repl-diskless-sync no  ### Disk-backed 启动新进程写rdb到disk,然后增量传输到salves 方式二:Diskless 直接写salve sockers,而不用写disk,当网络好的时候建议使用,但因为用到的是M/S+哨兵的架构,随时可能会进行主从切换,这个方式暂时不用

repl-diskless-sync-delay 5  ##每5s传输一次diskless开启后生效

repl-ping-slave-period 3  ###slave每3s ping测试master是否存活

repl-timeout 10      ###定义replicationtxuq  timeout时间,这里的时间要大于repl-ping-slave-period里的时间,不然后一直发生low traffic between the master and the slave问题

repl-disable-tcp-nodelay no  ###yes 一条线40milliseconds发送一次数据包,意识着更小的tcp packets和更小的带宽去发送到slave,但在slave会有相应的数据延迟. No,刚相反.一般上我们期望是低延迟,所以最选择no是个不错的选择,但如果在复杂的网络情况或m/s之间有很多中继网络,这里建议修改为yes

slave-priority 100  ###slave优先级别,数字越小优先级别越高,当master宕机时优先选取slave

# min-slaves-to-write 3  ###当最少有3个slave延迟<= 10s时,master才正常提供服务

# min-slaves-max-lag 10  ###当最少有3个slave延迟<= 10s时,master才正常提供服务

maxmemory  1536000000  #1.5G  ###单位 ,redis最大占用内存数,当超过1.5G时redis会根据策略清理内存key

#############6种清理策略

# volatile-lru -> remove the key with an expire set using an LRU algorithm ##推荐使用

# allkeys-lru -> remove any key according to the LRU algorithm

# volatile-random -> remove a random key with an expire set

# allkeys-random -> remove a random key, any key

# volatile-ttl -> remove the key with the nearest expire time (minor TTL)

# noeviction -> don\'t expire at all, just return an error on write operations

maxmemory-policy volatile-lru  ###使用LRU算法清理过期key

# maxmemory-samples 3  ###LRU算法和TTL算法均为模糊算法,该精确算法redis会选择3个keys选择最少使用的一个key进行删除, 个人不建议使用

appendonly yes  ###aof持久化,增量写disk,比aof慢,但更可靠.企业的默认选择,有的会两者均开启

appendfilename "appendonly.aof"  ###aof文件名

# appendfsync always

appendfsync everysec  ###建议使用该方式

# appendfsync no

no-appendfsync-on-rewrite no  ##建议no, 主要用来缓和redis调用fsync()写数据时间长的问题.当BGSAVE或BGREWRITEAOF被调用期间,fsync()进程将阻止被调用,即相当于

auto-aof-rewrite-percentage 100  ###当文件大小达到64mb的100%大小时开始rewrite aof文件

auto-aof-rewrite-min-size 64mb  ###当文件大小达到64mb的100%大小时开始rewrite aof文件

aof-load-truncated yes  ###当aof文件被损坏时,redis将返回错误并退出

lua-time-limit 5000  ###LUA scripts最大执行时间,单位(milliseconds),超出后返回查询错误并写日志

slowlog-log-slower-than 10000 ###单位microseconds(毫秒) 1000000 microseconds=1 s,记录执行时长超过10000 microseconds的执行命令

slowlog-max-len 128  ###最大长度为128

latency-monitor-threshold 0  ###监控相关,关闭就好

notify-keyspace-events ""  ###空表示关闭,发布相关key的操作记录到所有 client

######下面是高级设置,个人保持为默认配置

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

启动

# redis-server /etc/redis/redis.conf

查看

# redis-cli -h Mrds

Mrds:6379> info

# Server

redis_version:2.8.19    ###redis版本号

redis_git_sha1:00000000  ###git SHA1

redis_git_dirty:0  ###git dirty flag

redis_build_id:78796c63e58b72dc

redis_mode:standalone  ###redis运行模式

os:Linux 2.6.32-431.el6.x86_64 x86_64  ###os版本号

arch_bits:64  ###64位架构

multiplexing_api:epoll  ###调用epoll算法

gcc_version:4.4.7  ###gcc版本号

process_id:25899  ###服务器进程PID

run_id:eae356ac1098c13b68f2b00fd7e1c9f93b1c6a2c  ###Redis的随机标识符(用于sentinel和集群)

tcp_port:6379  ###Redis监听的端口号

uptime_in_seconds:6419 ###Redis运行时长(s为单位)

uptime_in_days:0  ###Redis运行时长(天为单位)

hz:10

lru_clock:10737922  ###以分钟为单位的自增时钟,用于LRU管理

config_file:/etc/redis/redis.conf  ###redis配置文件

# Clients

connected_clients:1  ###已连接客户端的数量(不包括通过从属服务器连接的客户端)

client_longest_output_list:0  ###当前连接的客户端中最长的输出列表

client_biggest_input_buf:0  ###当前连接的客户端中最大的输出缓存

blocked_clients:0  ###正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量 需监控

# Memory

used_memory:2281560  ###由 Redis 分配器分配的内存总量,以字节(byte)为单位

used_memory_human:2.18M  ###以更友好的格式输出redis占用的内存

used_memory_rss:2699264  ###从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致

used_memory_peak:22141272  ### Redis 的内存消耗峰值(以字节为单位)

used_memory_peak_human:21.12M  ###以更友好的格式输出redis峰值内存占用

used_memory_lua:35840  ###LUA引擎所使用的内存大小

mem_fragmentation_ratio:1.18  ###used_memory_rss 和 used_memory 之间的比率

mem_allocator:jemalloc-3.6.0

###在理想情况下, used_memory_rss 的值应该只比 used_memory 稍微高一点儿。当 rss > used ,且两者的值相差较大时,表示存在(内部或外部的)内存碎片。内存碎片的比率可以通过 mem_fragmentation_ratio 的值看出。

当 used > rss 时,表示 Redis 的部分内存被操作系统换出到交换空间了,在这种情况下,操作可能会产生明显的延迟。

# Persistence

loading:0  ###记录服务器是否正在载入持久化文件

rdb_changes_since_last_save:0  ###距离最近一次成功创建持久化文件之后,经过了多少秒

rdb_bgsave_in_progress:0  ###记录了服务器是否正在创建 RDB 文件

rdb_last_save_time:1420023749  ###最近一次成功创建 RDB 文件的 UNIX 时间戳

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  ###RDB 文件创建完毕之后,是否需要执行预约的 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_current_size:176265  ###AOF 文件目前的大小

aof_base_size:176265  ###服务器启动时或者 AOF 重写最近一次执行之后,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:8466  ###服务器已接受的连接请求数量

total_commands_processed:900668  ###服务器已执行的命令数量

instantaneous_ops_per_sec:1  ###服务器每秒钟执行的命令数量

total_net_input_bytes:82724170

total_net_output_bytes:39509080

instantaneous_input_kbps:0.07

instantaneous_output_kbps:0.02

rejected_connections:0  ###因为最大客户端数量限制而被拒绝的连接请求数量

sync_full:2

sync_partial_ok:0

sync_partial_err:0

expired_keys:0  ###因为过期而被自动删除的数据库键数量

evicted_keys:0  ###因为最大内存容量限制而被驱逐(evict)的键数量。

keyspace_hits:0  ###查找数据库键成功的次数。

keyspace_misses:500000  ###查找数据库键失败的次数。

pubsub_channels:0  ###目前被订阅的频道数量

pubsub_patterns:0  ###目前被订阅的模式数量

latest_fork_usec:402  ###最近一次 fork() 操作耗费的毫秒数

# Replication

role:master  ###如果当前服务器没有在复制任何其他服务器,那么这个域的值就是 master ;否则的话,这个域的值就是 slave 。注意,在创建复制链的时候,一个从服务器也可能是另一个服务器的主服务器

connected_slaves:2  ###2个slaves

slave0:ip=192.168.65.130,port=6379,state=online,offset=1639,lag=1

slave1:ip=192.168.65.129,port=6379,state=online,offset=1639,lag=0

master_repl_offset:1639

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:2

repl_backlog_histlen:1638

# CPU

used_cpu_sys:41.87  ###Redis 服务器耗费的系统 CPU

used_cpu_user:17.82  ###Redis 服务器耗费的用户 CPU

used_cpu_sys_children:0.01  ###后台进程耗费的系统 CPU

used_cpu_user_children:0.01  ###后台进程耗费的用户 CPU

# Keyspace

db0:keys=3101,expires=0,avg_ttl=0  ###keyspace 部分记录了数据库相关的统计信息,比如数据库的键数量、数据库已经被删除的过期键数量等。对于每个数据库,这个部分都会添加一行以下格式的信息

Sentinel(哨兵)配置

vi sentinel.conf

启动前:

port 26379

dir "/var/lib/redis/tmp"  ###定义目录存放

sentinel auth-passmymaster vhreal   ##密码

sentinel monitor mymaster 192.168.65.128 6379 2    ###监控mymaster(可自定义-但只能包括A-z 0-9和”._-”)

sentinel down-after-milliseconds mymaster 30000  ###mymaster多久不响应认为SDOWN

sentinel parallel-syncs mymaster 1  ###指定最大同时同步新maser配置的salve数量

sentinel failover-timeout mymaster 180000  ###2次failover切换时间

启动后(redis.con配置文件完全由sentinel控制,请不要再随意手动改动):

port 26379

dir "/var/lib/redis/tmp"

sentinel monitor mymaster 192.168.65.128 6379 2

sentinel config-epoch mymaster 18  ###确认mymater SDOWN时长

sentinel leader-epoch mymaster 18  ###同时一时间最多18个slave可同时更新配置,建议数字不要太大,以免影响正常对外提供服务

sentinel known-slave mymaster 192.168.65.129 6379  ###已知的slave

sentinel known-slave mymaster 192.168.65.130 6379  ###已知的slave

sentinel known-sentinel mymaster 192.168.65.130 26379 be964e6330ee1eaa9a6b5a97417e866448c0ae40    ###已知slave的唯一id

sentinel known-sentinel mymaster 192.168.65.129 26379 3e468037d5dda0bbd86adc3e47b29c04f2afe9e6  ###已知slave的唯一id

sentinel current-epoch 18  ####当前可同时同步的salve数最大同步阀值

开启sentinel

开启sentinel后会后redis.conf会由sentinel进行管理

# redis-server /etc/redis/sentinel.conf --sentinel &> /var/log/redis/sentinel.log &

常用命令

redis-cli

redis-server

auth

set key value

get key

Q&A

Redis主从配置异常解决:Error condition on socket for SYNC: Connection refused

Redis主从集群时,从服务器上的redis日志报错:

32677:S08Feb16:14:38.947*ConnectingtoMASTER172.168.10.70:637932677:S08Feb16:14:38.948*MASTER<->SLAVEsyncstarted32677:S08Feb16:14:38.948#ErrorconditiononsocketforSYNC:Connectionrefused32677:S08Feb16:14:39.950*ConnectingtoMASTER172.168.10.70:637932677:S08Feb16:14:39.950*MASTER<->SLAVEsyncstarted32677:S08Feb16:14:39.950#ErrorconditiononsocketforSYNC:Connectionrefused32677:S08Feb16:14:40.952*ConnectingtoMASTER172.168.10.70:637932677:S08Feb16:14:40.952*MASTER<->SLAVEsyncstarted32677:S08Feb16:14:40.953#ErrorconditiononsocketforSYNC:Connectionrefused
  • 解决方案:

在redis主服务器上的redis.conf中修改bind字段,将

bind 127.0.0.1

修改为

bind 0.0.0.0

又或者直接注释掉bind字段

# bind 127.0.0.1
  • 原因:

如果redis主服务器绑定了127.0.0.1,那么跨服务器IP的访问就会失败,从服务器用IP和端口访问主的时候,主服务器发现本机6379端口绑在了127.0.0.1上,也就是只能本机才能访问,外部请求会被过滤,这是Linux的网络安全策略管理的。如果bind的IP地址是172.168.10.70,那么本机通过localhost和127.0.0.1、或者直接输入命令redis-cli登录本机redis也就会失败了。只能加上本机ip才能访问到。

所以,在研发、测试环境可以考虑bind 0.0.0.0,线上生产环境建议绑定IP地址。

(DENIED Redis is running in protected mode)

Java程序中使用JedisSentinelPool建立redis连接池


Set sentinels = new HashSet();

sentinels.add("172.17.16.7:26379");

sentinels.add("172.17.16.8:26379");

sentinels.add("172.17.16.9:26379");

JedisSentinelPool sentinelPool = new JedisSentinelPool("mymaster", sentinels, "123456");

报错:

DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to    clients.......

使用redis-cli -h 127.0.0.1 -p 26379连接sentinel可以执行命令,而使用redis-cli -h 172.17.16.7 -p 26379连接sentinel执行命令则会报同上的错误。

查遍了网上没有找到相关的问题分析和解决的案例,所以只能自己猜测和排查,初步怀疑是通过172.17.16.7访问sentinel时受限。

由于此错误和redis server的protect-mode为yes的访问错误颇为相似,官方在redis.conf的注释说明中有protected-mode这一配置项,但sentinel.conf的注释中完全没有提到过该配置项,我很疑惑,但还是尝试在sentinel.conf中加入

protected-mode no

之后保存并重新启动sentinel,之后用Java程序建立连接池,没有报错,且可以对redis server进行数据处理,问题解决。

以上是关于Redis哨兵架构(哨兵搭建,哨兵原理)的主要内容,如果未能解决你的问题,请参考以下文章

Redis哨兵(sentinel)

Redis哨兵(sentinel)

Redis主从与哨兵架构详解 Redis主从架构 如何在同一台机器搭建主从架构 Redis主从工作原理 数据部分复制 Jedis使用 Redis的管道(Pipeline) Redis Lua脚本(代码

redis集群介绍与搭建(主从哨兵cluster集群)!

redis集群介绍与搭建(主从哨兵cluster集群)!

Redis高可用架构之哨兵模式 - Sentinel