Redis集群部署

1.下载redis

  1. wget http://distfiles.macports.org/redis/redis-5.0.7.tar.gz

2.解压Redis安装包

  1. #解压redis
  2. [root@open-falcon mnt]# tar -zxvf redis-5.0.7.tar.gz
  3. #解压得到包如下
  4. [root@open-falcon mnt]# cd redis-5.0.7
  5. #包内文件如下
  6. [root@open-falcon redis-5.0.7]# ls
  7. 00-RELEASENOTES CONTRIBUTING deps Makefile README.md runtest runtest-moduleapi sentinel.conf tests
  8. BUGS COPYING INSTALL MANIFESTO redis.conf runtest-cluster runtest-sentinel src utils

3.Redis编译安装

  1. #进入解压包
  2. [root@open-falcon redis-5.0.7]# cd redis-5.0.7
  3. #安装gcc环境,若已安装跳过步骤(解决make install失败的问题)
  4. [root@open-falcon redis-5.0.7]# yum install -y gcc g++ gcc-c++ make
  5. [root@open-falcon redis-5.0.7]# make MALLOC=libc
  6. #编译&安装
  7. [root@open-falcon redis-5.0.7]# make && make install

4.集群搭建配置

①总体架构

Redis高可用集群,一般选三台服务器:这样,我们在一台主节点挂了之后,另外两台可以选举其中一台担任主节点master的角色。

  1. slave节点配置从master节点同步数据
  2. 哨兵sentinel故障转移机制:每个redis节点搭建一个监控哨兵,当redis的master节点挂掉之后:三个哨兵选举一个slave节点 成为master节点 ```java

    部署在同一台服务器上,使用3个端口对外提供服务

主节点master
1台
Redis服务 192.168.154.145 6379 sentinel哨兵 192.168.154.145 26379

从节点slave
2台
Redis服务 192.168.154.145 27001 sentinel哨兵 192.168.154.145 27002

  1. <a name="dAxH7"></a>
  2. ### ②伪集群<br />由于现场没有三台服务器,我们就在一台服务器上,使用3个端口,来给他搭一个"伪集群":
  3. 何为"伪集群"呢?<br />"伪集群" 架构与真正集群完全一样,故障转移、高可用都可以。<br />只是搭建在一台服务器上,使用3个端口对外提供服务。<br />生产环境下,集群环境还是需要使用3台不同的服务器,从而保证高可用。这里只是节约资源、方便搭建。
  4. <a name="PGH01"></a>
  5. ### ③主节点redis服务6379配置
  6. 完整配置及步骤如下:
  7. ```java
  8. 1、创建主节点工作目录 redis-6379
  9. mkdir -p /usr/local/redis-6379
  10. 2、将配置文件拷贝到工作目录下
  11. cp redis-5.0.7/redis.conf /usr/local/redis-6379
  1. 3、主节点 6379 端口配置
  2. #打开主节点redis.conf
  3. vim /usr/local/redis-6379/redis.conf
  4. 4、修改如下内容:左侧为修改的行数(:set nu行数显示),方便大家查找
  5. 69 bind 0.0.0.0
  6. 92 port 6379
  7. 136 daemonize yes
  8. 158 pidfile /var/run/redis_6379.pid
  9. 171 logfile "/usr/local/redis-6379/redis-6379.log"
  10. #默认配置不用修改
  11. 218 save 900 1
  12. 219 save 300 10
  13. 220 save 60 10000
  14. #全量备份文件名
  15. 253 dbfilename redis-6379.rdb
  16. #指定路径名
  17. 263 dir /usr/local/redis-6379
  18. #设置redis密码
  19. 509 requirepass 123456
  20. #开启增量备份
  21. 701 appendonly yes
  22. 705 appendfilename "appendonly-6379.aof"

④redis从节点服务7001/7002配置

注意,从节点与主节点配置的区别主要在两个地方
①配置主节点:replicaof 192.168.154.145 6379
②配置主节点的登录密码masterauth 123456
完整配置及步骤如下:

1、创建从节点工作目录 redis-7001 和 redis-7002

  1. mkdir -p /usr/local/redis-7001
  2. mkdir -p /usr/local/redis-7002

2、将配置文件拷贝到工作目录下

  1. cp redis-5.0.7/redis.conf /usr/local/redis-7001
  2. cp redis-5.0.7/redis.conf /usr/local/redis-7002

3、从节点 7001 / 7002 端口配置

  1. #分别打开从节点redis.conf
  2. vim /usr/local/redis-7001/redis.conf
  3. vim /usr/local/redis-7002/redis.conf

4、7001 从节点配置,左侧为修改的行数,方便大家查找

  1. 69 bind 0.0.0.0
  2. 92 port 7001
  3. 136 daemonize yes
  4. 158 pidfile /var/run/redis_7001.pid
  5. 171 logfile "/usr/local/redis-7001/redis-7001.log"
  6. #默认配置不用修改
  7. 218 save 900 1
  8. 219 save 300 10
  9. 220 save 60 10000
  10. #全量备份文件名
  11. 253 dbfilename redis-7001.rdb
  12. #指定路径名
  13. 263 dir /usr/local/redis-7001
  14. #设置主节点 地址端口+主节点连接密码
  15. 286 replicaof 192.168.154.145 6379
  16. 293 masterauth 123456
  17. #设置redis密码
  18. 509 requirepass 123456
  19. #开启增量备份
  20. 701 appendonly yes
  21. 705 appendfilename "appendonly-7001.aof"

5、7002 从节点配置,左侧为修改的行数,方便大家查找

  1. 69 bind 0.0.0.0
  2. 92 port 7002
  3. 136 daemonize yes
  4. 158 pidfile /var/run/redis_7002.pid
  5. 171 logfile "/usr/local/redis-7002/redis-7002.log"
  6. #默认配置不用修改
  7. 218 save 900 1
  8. 219 save 300 10
  9. 220 save 60 10000
  10. #全量备份文件名
  11. 253 dbfilename redis-7002.rdb
  12. #指定路径名
  13. 263 dir /usr/local/redis-7002
  14. #设置主节点 地址端口+主节点连接密码
  15. 286 replicaof 192.168.154.145 6379
  16. 293 masterauth 123456
  17. #设置redis密码
  18. 509 requirepass 123456
  19. #开启增量备份
  20. 701 appendonly yes
  21. 705 appendfilename "appendonly-7002.aof"

5.故障转移/高可用配置(哨兵模式sentinel)

①总体架构

  1. 主节点哨兵:
  2. 6379端口redis主服务,哨兵默认端口为26379
  3. 从节点哨兵:
  4. 7001端口redis服务,哨兵使用27001端口
  5. 7002端口redis服务,哨兵使用27002端口

②主节点master配置哨兵sentinel

为了方便管理,我们把哨兵工作目录分别建在对应的redis工作目录下
注意:

  1. 配置master的地址及命名(mymaster为集群名称):sentinel monitor mymaster 192.168.154.145 6379 2
  2. 配置连接redis主节点的密码 sentinel auth-pass mymaster 123456
  3. 日志目录一定要创建,因为出问题,方便查找原因。 logfile “/usr/local/redis-6379/sentinel/redis-sentinel.log”

    1、创建主节点 sentinel工作目录

    1. mkdir -p /usr/local/redis-6379/sentinel/

    2、将配置文件拷贝到sentinel工作目录下

    1. cp redis-5.0.7/sentinel.conf /usr/local/redis-6379/sentinel/

    3、修改配置文件 左侧为修改的行数,方便大家查找

    ```java vim /usr/local/redis-6379/sentinel/sentinel.conf

配置哨兵端口

21 port 26379

配置进程id存储地址

32 pidfile “/usr/local/redis-6379/redis-sentinel-26379.pid”

配置log路径

37 logfile “/usr/local/redis-6379/sentinel/redis-sentinel.log”

配置哨兵工作目录

65 dir “/usr/local/redis-6379/sentinel”

配置监控的redis主节点

84 sentinel monitor mymaster 192.168.154.145 6379 2

配置主节点登录密码

103 sentinel auth-pass mymaster 123456

  1. <a name="gh9Ai"></a>
  2. ### ③从节点slave配置哨兵sentinel
  3. 从节点的配置,除了工作目录不同及端口,其余与主节点完全一致
  4. <a name="eY2Aw"></a>
  5. #### 1、创建从节点 sentinel工作目录
  6. ```java
  7. mkdir -p /usr/local/redis-7001/sentinel/
  8. mkdir -p /usr/local/redis-7002/sentinel/

2、将配置文件拷贝到sentinel工作目录下

cp redis-5.0.7/sentinel.conf /usr/local/redis-7001/sentinel/
cp redis-5.0.7/sentinel.conf /usr/local/redis-7002/sentinel/

3、分别修改slave节点 哨兵配置文件

vim /usr/local/redis-7001/sentinel/sentinel.conf 
vim /usr/local/redis-7002/sentinel/sentinel.conf

4、27001节点哨兵的配置 左侧为修改的行数,方便大家查找

#配置哨兵端口
21 port 27001
#配置进程id存储地址
32 pidfile "/usr/local/redis-7001/redis-sentinel-27001.pid"
#配置log路径    
37 logfile "/usr/local/redis-7001/sentinel/redis-sentinel.log"
#配置哨兵工作目录
65 dir "/usr/local/redis-7001/sentinel"
#配置监控的redis主节点
84 sentinel monitor mymaster 192.168.154.145 6379 2
#配置主节点登录密码
103 sentinel auth-pass mymaster 123456

5、27002哨兵节点的配置 左侧为修改的行数,方便大家查找

#配置哨兵端口
21 port 27002
#配置进程id存储地址
32 pidfile "/usr/local/redis-7002/redis-sentinel-27002.pid"
#配置log路径    
37 logfile "/usr/local/redis-7002/sentinel/redis-sentinel.log"
#配置哨兵工作目录
65 dir "/usr/local/redis-7002/sentinel"
#配置监控的redis主节点
84 sentinel monitor mymaster 192.168.154.145 6379 2
#配置主节点登录密码
103 sentinel auth-pass mymaster 123456


到此全部配置完成。

6.启动集群

①.启动所有redis服务节点

#分别启动三个节点的redis服务
[root@mail ~]# redis-server /usr/local/redis-6379/redis.conf
[root@mail ~]# redis-server /usr/local/redis-7001/redis.conf 
[root@mail ~]# redis-server /usr/local/redis-7002/redis.conf

②启动所有哨兵sentinel服务

#启动时,根据配置文件启动
[root@mail ~]# redis-sentinel /usr/local/redis-6379/sentinel/sentinel.conf 
[root@mail ~]# redis-sentinel /usr/local/redis-7001/sentinel/sentinel.conf 
[root@mail ~]# redis-sentinel /usr/local/redis-7002/sentinel/sentinel.conf

③查看服务进程

#如下图:三个redis服务+三个哨兵监控 全部启动成功
[root@mail ~]# ps aux|grep redis   
root      50845  0.0  0.1 158068  3904 ?        Ssl  07:50   0:42 redis-server 0.0.0.0:6379                               
root      50166  0.0  0.1 161652  3768 ?        Ssl  07:39   0:43 redis-server 0.0.0.0:7001                    
root      50173  0.1  0.2 161652  4884 ?        Ssl  07:40   0:53 redis-server 0.0.0.0:7002                    
root      50370  0.1  0.1 152436  3692 ?        Ssl  07:43   1:14 redis-sentinel *:26379 [sentinel]                          
root      50375  0.1  0.0 152436  1748 ?        Ssl  07:43   1:15 redis-sentinel *:27001 [sentinel]                          
root      50431  0.1  0.0 152436  1712 ?        Ssl  07:43   1:14 redis-sentinel *:27002 [sentinel]

7.测试:数据同步+读写分离+故障转移

①数据同步测试

测试目标:master主节点 写入/修改/删除数据,slave从节点会自动同步master的数据操作记录。

  1. redis-cli链接master主节点,写入age和name 两个数据

    #链接redis,设置两个值,如下
    [root@mail ~]# redis-cli -a 123456 -p 6379
    Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    127.0.0.1:6379> set age 25
    OK
    127.0.0.1:6379> set name lex
    OK
    
  2. 登录slave从节点查看 ```java

    登录slave从节点

    [root@mail ~]# redis-cli -a 123456 -p 7001 Warning: Using a password with ‘-a’ or ‘-u’ option on the command line interface may not be safe.

查看所有数据

127.0.0.1:7001> keys * 1) “age” 2) “name”

查看age数据

127.0.0.1:7001> get age “25”

尝试修改数据

127.0.0.1:7001> set age 30 (error) READONLY You can’t write against a read only replica.

修改失败,slave从节点 数据只读

<a name="S71IY"></a>
### ②master/slave节点查看

1. 链接哨兵:查看master节点和slave节点的分配情况
1. 链接命令:redis-cli -a 123456 -p 26379 ,同样使用redis-cli,只是链接到sentinel的端口即可

查看master主节点地址:6379端口服务
```java
#链接哨兵sentinel 同样使用redis-cli
[root@mail ~]# redis-cli -a 123456 -p 26379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
#查看mymaster(我们配置的集群名)  集群的master 是哪个
127.0.0.1:26379> sentinel master mymaster
 1) "name"
 2) "mymaster"
 3) "ip"
 4) "192.168.154.145"
 5) "port"
 6) "6379"
 7) "runid"
 8) "105cc1c986fcda65ad4ddba69012e8e6e0073e1f"
 9) "flags"
10) "master"
...
  1. 查看slave节点地址:两个slave节点分别是7001和7002服务,可以看到两个slave节点指向的master节点为6379 ```java

    命令如下:

    127.0.0.1:26379> sentinel slaves mymaster 1) 1) “name” 2) “192.168.154.145:7001” 3) “ip” 4) “192.168.154.145” 5) “port” 6) “7001” 9) “flags” 10) “slave” 31) “master-link-status” 32) “ok” 33) “master-host” 34) “192.168.154.145” 35) “master-port” 36) “6379” …

2) 1) “name” 2) “192.168.154.145:7002” 3) “ip” 4) “192.168.154.145” 5) “port” 6) “7002” 9) “flags” 10) “slave” 31) “master-link-status” 32) “ok” 33) “master-host” 34) “192.168.154.145” 35) “master-port” 36) “6379” …

<a name="EoVcs"></a>
### ③故障转移(高可用)测试
**测试目的:master主节点挂掉之后,我们的sentinel集群可以通过选举机制,重新在slave节点中选举一个作为新的master节点。**

1. 关闭主节点6379
```java
#链接主节点,shutdown关闭主节点
[root@mail ~]# redis-cli -a 123456 -p 6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> shutdown
not connected>
  1. 查看此时的master节点

链接到哨兵,查看主节点:此时,经过三个哨兵的选举,主节点变为 7002

#链接到哨兵,查看主节点:主节点变为 7002
[root@mail ~]# redis-cli -a 123456 -p 26379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:26379> sentinel master mymaster
 1) "name"
 2) "mymaster"
 3) "ip"
 4) "192.168.154.145"
 5) "port"
 6) "7002"
 7) "runid"
 8) "105cc1c986fcda65ad4ddba69012e8e6e0073e1f"
 9) "flags"
10) "master"
...
127.0.0.1:26379>
  1. 此时,再查看slave节点的情况

发现slave节点变为:6379和7001两个,而且6379的状态为 “s_down,slave,disconnected”,因为我们关闭了6379

[root@mail ~]# redis-cli -a 123456 -p 26379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:26379> sentinel slaves mymaster
1)  1) "name"
    2) "192.168.154.145:6379"
    3) "ip"
    4) "192.168.154.145"
    5) "port"
    6) "6379"
    7) "runid"
    8) "e740b7285067b2dbb8c2640745196099460f4bb3"
    9) "flags"
   10) "s_down,slave,disconnected"

...
2)  1) "name"
    2) "192.168.154.145:7001"
    3) "ip"
    4) "192.168.154.145"
    5) "port"
    6) "7001"
    7) "runid"
    8) "19a7647509ba020adfd06b1eb40f1f35d06c549d"
    9) "flags"
   10) "slave"
...
127.0.0.1:26379>
  1. 所以,故障转移就成功了。

    ④读写分离测试

  2. redis集群开启之后,slave从节点的权限 默认是只读的;当然我们也可以开启slave节点的写入权限。

所以,写数据:链接master主节点;读数据:链接slave从节点。
如下图:slave从节点,没有写入权限

#登录slave从节点
[root@mail ~]# redis-cli -a 123456 -p 7001
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.

#查看所有数据
127.0.0.1:7001> keys *
1) "age"
2) "name"

#查看age数据
127.0.0.1:7001> get age
"25"

#尝试修改数据
127.0.0.1:7001> set age 30
(error) READONLY You can't write against a read only replica.
#修改失败,slave从节点 数据只读

哨兵模式

哨兵模式概述

主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式
哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。
Redis集群部署~哨兵模式 - 图1
这里的哨兵有两个作用

  • 通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。
  • 当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换主机。

然而一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多哨兵模式。

用文字描述一下故障切换(failover)的过程。假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象成为主观下线。当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover操作。切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。这样对于客户端而言,一切都是透明的。

Java中使用哨兵模式

/**
 * 测试Redis哨兵模式
 * @author liu
 */
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 down-after-milliseconds配置项只是一个哨兵在超过规定时间依旧没有得到响应后,会自己认为主机不可用。对于其他哨兵而言,并不是这样认为。哨兵会记录这个消息,当拥有认为主观下线的哨兵达到sentinel monitor所配置的数量时,就会发起一次投票,进行failover,此时哨兵会重写Redis的哨兵配置文件,以适应新场景的需要。