Redis+Sentinel哨兵模式集群方案配置与搭建

搭建Redis-Sentinel 集群环境

环境准备

  • linux 系统 centOS 7.3 虚拟机一台(也可以放在多个虚拟机上)
  • 端口分配
实例名称 ip 端口
redis-master 127.0.0.1 7501
redis-slave1 127.0.0.1 7502
redis-slave2 127.0.0.1 7503
redis-slave3 127.0.0.1 7504
redis-sentinel1 127.0.0.1 7505
redis-sentinel2 127.0.0.1 7506
redis-sentinel3 127.0.0.1 7507
  • 整体架构拓扑图

Redis+Sentinel哨兵模式集群方案配置与搭建_第1张图片

安装Redis

  1. 进入到想安装的文件路径中
cd /root/jiachang/redis
  1. 下载redis
wget http://download.redis.io/releases/redis-3.2.1.tar.gz
  1. 解压
tar -xzf redis-3.2.1.tar.gz 
  1. 进入解压后的文件夹
cd redis-3.2.1 
  1. 检查是否安装gcc,没有的话进行安装,并编译redis源码
// 检查是否安装
yum list installed | grep gcc
// 安装
yum -y install gcc
// 编译
make [MALLOC=libc]
make install 
  1. 在/usr/local/ 下新建一个目录redis-sentinel,然后在此目录下新建7501/ 7502/ 7503/ 7504/ 7505/ 7506/ 7507/七个目录
mkdir /usr/local/redis-sentinel 
mkdir /usr/local/redis-sentinel/{7501,7502,7503,7504,7505,7506,7507}
  1. 将redis安装目录下的reids.conf,拷贝到前4个目录下,分别命名为:redis-7501.conf redis-7502.conf redis-7503.conf redis-7504.conf
cp /root/redis-3.2.1/redis.conf /usr/local/redis-sentinel/7501/redis-7501.conf
cp /root/redis-3.2.1/redis.conf /usr/local/redis-sentinel/7502/redis-7502.conf
cp /root/redis-3.2.1/redis.conf /usr/local/redis-sentinel/7503/redis-7503.conf
cp /root/redis-3.2.1/redis.conf /usr/local/redis-sentinel/7504/redis-7504.conf
  1. 修改redis的conf配置文件,主从的配置几乎都一样(有些地方还是有区别的),以7501端口的redis实例为例进行分析
## 开启守护模式 
daemonize yes
pidfile /var/run/redis_7501.pid
## 端口号
port 7501
bind 127.0.0.1
## redis运行产生的日志
logfile "./redis-7501.log"
#数据目录,数据库的写入会在这个目录。rdb、aof文件也会写在这个目录
dir "/usr/local/redis-sentinel/7501"
## redis配置密码的话,需要以下配置
masterauth "123456"
requirepass "123456"
## 打开aof持久化
appendonly yes

其他子节点对应的conf文件也要进行修改,跟上面差不多,不一样的值:port、pidfile 、logfile 、dir 需要新增的地方:

# 指定所属的master  
slaveof 127.0.0.1 7501
# 指定slave只读  
slave-read-only yes
  1. 启动redis实例
redis-server /usr/local/redis-sentinel/7501/redis-7501.conf
redis-server /usr/local/redis-sentinel/7502/redis-7502.conf
redis-server /usr/local/redis-sentinel/7503/redis-7503.conf
redis-server /usr/local/redis-sentinel/7504/redis-7504.conf
  1. 检查Redis是否启动成功
    1> 使用ping命令
redis-cli -h 127.0.0.1 -p 7501 ping
PONG

2> 查看redis进程

ps -ef | grep redis

root      7795     1  0 16:34 ?        00:00:17 redis-server 127.0.0.1:7501
root     31756     1  0 12:09 ?        00:00:25 ./redis-server 127.0.0.1:7502
root     31766     1  0 12:09 ?        00:00:29 ./redis-server 127.0.0.1:7503
root     31777     1  0 12:09 ?        00:00:25 ./redis-server 127.0.0.1:7504
  1. 启动成功后,查看Redis的主从关系
  • 使用redis-cli -h 127.0.0.1 -p 7501 登录到Redis实例上
  • 使用 info replication 查看主从关系信息
    主节点信息如下:
[root@localhost ~]# redis-cli -h 127.0.0.1 -p 7501
127.0.0.1:7501> info replication
# Replication
role:master // 代表当前节点是从节点
connected_slaves:3
// 下面是从节点的信息
slave0:ip=127.0.0.1,port=7504,state=online,offset=12880468,lag=1
slave1:ip=127.0.0.1,port=7502,state=online,offset=12880600,lag=1
slave2:ip=127.0.0.1,port=7503,state=online,offset=12880600,lag=1
master_repl_offset:12880732
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:11832157
repl_backlog_histlen:1048576

从节点信息如下:

[root@localhost ~]# redis-cli -h 127.0.0.1 -p 7502
127.0.0.1:7502> info replication
# Replication
role:slave // 代表当前节点是从节点
// 下面是主节点的信息
master_host:127.0.0.1
master_port:7501
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:12935376
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
  1. 其他测试
1. 从节点只读权限
127.0.0.1:7502> set zhangsan www
(error) READONLY You can't write against a read only slave.
2. 主节点更新数据后,从节点进行查看
 [root@localhost ~]# redis-cli -h 127.0.0.1 -p 7501
127.0.0.1:7501> set key1 value1
OK
127.0.0.1:7501> exit
[root@localhost ~]# redis-cli -h 127.0.0.1 -p 7502
127.0.0.1:7502> get key1
"value1"

搭建Sentinel

  1. 将redis安装目录下的sentinel.conf拷贝到7505/ 7506/和7507/目录下分别命名: sentinel-7505.conf sentinel-7506.conf sentinel-7507.conf
cp /root/jiachang/redis/redis-3.2.1/sentinel.conf /usr/local/redis-sentinel/7505/sentinel-7505.conf
cp /root/jiachang/redis/redis-3.2.1/sentinel.conf /usr/local/redis-sentinel/7505/sentinel-7506.conf
cp /root/jiachang/redis/redis-3.2.1/sentinel.conf /usr/local/redis-sentinel/7505/sentinel-7507.conf
  1. 修改配置项
daemonize yes 
port 7505
#指定工作目录
dir "/usr/local/redis-sentinel/7505"
logfile "./sentinel-7505.log" 
#指定别名  主节点地址  端口  哨兵个数(有几个哨兵监控到主节点宕机执行转移 判断主节点失败至少需要2个Sentinel节点节点同意)
sentinel monitor mymaster 127.0.0.1 7501 2
#如果哨兵3s内没有收到主节点的心跳,哨兵就认为主节点宕机了,默认是30秒  
sentinel down-after-milliseconds mymaster 3000
## 当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1
sentinel parallel-syncs mymaster 1
# 故障转移超时时间
sentinel failover-timeout mymaster 10000 
#配置连接redis主节点密码  
sentinel auth-pass mymaster 123456  
  1. 启动3个Sentinel
redis-sentinel /usr/local/redis-sentinel/7505/sentinel-7505.conf
redis-sentinel /usr/local/redis-sentinel/7506/sentinel-7506.conf
redis-sentinel /usr/local/redis-sentinel/7507/sentinel-7507.conf

还有一种启动命令

redis-server /usr/local/redis-sentinel/7505/sentinel-7505.conf --sentinel
  1. 此时再去查看进程,发现sentinel已经启动成功
root      6390     1  0 15:48 ?        00:00:29 redis-sentinel *:7505 [sentinel]
root      6426     1  0 15:49 ?        00:00:28 redis-sentinel *:7506 [sentinel]
root      6434     1  0 15:49 ?        00:00:29 redis-sentinel *:7507 [sentinel]
root      7795     1  0 16:34 ?        00:00:17 redis-server 127.0.0.1:7501
root     16257 29348  0 21:28 pts/1    00:00:00 grep --color=auto redis
root     31756     1  0 12:09 ?        00:00:25 ./redis-server 127.0.0.1:7502
root     31766     1  0 12:09 ?        00:00:29 ./redis-server 127.0.0.1:7503
root     31777     1  0 12:09 ?        00:00:25 ./redis-server 127.0.0.1:7504
  1. 启动成功后的变化
  • 自动发现了其他的sentinel节点
    1> sentinel 启动日志查看
tail -200f /usr/local/redis-sentinel/7505/sentinel-7505.log

Redis+Sentinel哨兵模式集群方案配置与搭建_第2张图片
2> 在sentinel的配置文件最下面会多出如下配置

  1. Sentinel一些命令介绍
    要想使用Sentinel,必须使用redis-cli命令进入到Sentinel
redis-cli -h 127.0.0.1 -p 7505
如果有密码 后面再加上 -a 密码
  • info : sentinel的基本状态信息 (例如监控的redis主节点的信息)
  • sentinel masters : 监控的主节点的信息
 1) "name"
 2) "mymaster"
 3) "ip"
 4) "127.0.0.1"
 5) "port"
 6) "7501" (这里就是主节点的端口信息)
 7) "runid"
 8) "06fce2f40c76e0a984d304d519fe6e437ff88aa6"
 9) "flags"
10) "master"
.........
  • sentinel slaves mymaster : 监控的从节点的信息(下面会依次列出3个从节点的详细信息)

故障转移试验

  1. 我们将master节点-7501 强制kill掉
ps -ef|grep redis
kill -9 pid
  1. 查看一下Sentinel节点监控的主节点信息
  • 当将Redis主节点kill掉以后,Redis Sentinel对主节点进行客观下线(Objectively Down, 简称 ODOWN)的判断,确认主节点不可达,则通知从节点中止复制主节点的操作。
127.0.0.1:7505> sentinel masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "7503"
    7) "runid"
    8) "06fce2f40c76e0a984d304d519fe6e437ff88aa6"
    9) "flags"
   10) "master"
   11) "link-pending-commands"
	........

此时发现 7503已经升级为master
sentinel日志也可以看得出来,这个时候Sentinel的配置文件也修改了。
Redis+Sentinel哨兵模式集群方案配置与搭建_第3张图片

  1. 继续启动7501节点后,变为7503的子节点,跟正常一样。

部署过程中遇到的坑

  • bind含义:代表该redis实例能被其他服务器访问的ip地址。比如这台机器有外网ip(114.15.54.55)和内网ip,我只想把内网ip(172.16.130.52)暴露出去,那这里就配置内网ip(172.16.130.52),别人访问这台redis示例只能通过这个ip,外网的那个就不行了。默认是不限制的。
  • 如果redis需要配置密码的话,主从Redis示例需要增加以下配置
    masterauth “123456”
    requirepass “123456”
    注意,这两个的值一定要一样!!
    requirepass 表示 我给这个redis设置的登录密码,你要通过redis-cli登录到这台redis上面就要输入密码了AUTH password
    masterauth : 这个又代表什么意思呢,主节点redis设置了密码,你的从节点想要同步主节点的数据,肯定也要输入密码了,所以就把这个变量配置上去就行了,所以它的值肯定跟requirepass保持一致了。
    因为每个节点都有可能是主节点,所以主从节点关于这个的配置要保持一致,不然就乱套了。
  • protected-mode : 在Redis的配置中,有这个配置,什么意思呢?就是要不要开启保护模式,默认是yes的。开启的时候,只有本地能连接成功,其他的机器想要连接你这个redis会报错的。如果关闭了,就不安全了,但是可以通过其他的措施进行保护,所以官方文档也说了有以下几种方案:
    • 使用 设置CONFIG SET protected-mode no
      步骤:
      在redis本机上打开redis-cli工具,并连接
      在其中输入CONFIG SET protected-mode no即可
      缺点:
      该种方式只是短暂性有效,如果redisServer重新启动后还是不能正常链接
    • 保护模式关闭,重启(不安全,不推荐)
    • 如果只是测试的话,启动的时候加上 --protected-mode no
    • bind ip或者加上密码认证(一般线上这两个都配置才安全)
  • sentinel 的 protected-mode也要改为no,原来的配置文件没有的,要手动加上去。

代码实践(Java版本)

需要引用的jar

            
                redis.clients
                jedis
                2.9.0
            
package com.sunny.redis.sentinel;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;
import java.util.HashSet;
import java.util.Set;

/**
 * @author JiaChang
 * @date 2018/12/18
 */
public class SentinelUtil {
    private static final Set SENTINELS = new HashSet();
    private static String IP = "";

    static {
        //服务IP
        IP = "172.16.150.**";
        // Sentine端口
        SENTINELS.add(new HostAndPort(IP, 7505).toString());
        SENTINELS.add(new HostAndPort(IP, 7506).toString());
        SENTINELS.add(new HostAndPort(IP, 7507).toString());
    }

    public static void main(String[] args) {
        JedisSentinelPool sentinelPool = new JedisSentinelPool("mymaster", SENTINELS);
        System.out.println("Current master: " + sentinelPool.getCurrentHostMaster().toString());
        Jedis master = sentinelPool.getResource();
        master.auth("***");
        master.set("username","张三");
        sentinelPool.returnResource(master);
        Jedis master2 = sentinelPool.getResource();
        master2.auth("***");
        String value = master2.get("username");
        System.out.println("username: " + value);
        master2.close();
        sentinelPool.destroy();
    }
}


运行结果:
Current master: 172.16.150.**:7501
username: 张三

你可能感兴趣的:(Redis)