Linux Redis 主从复制,Redis slaveof replicaof主从复制,redis-sentinel哨兵

Linux Redis 主从复制,Redis slaveof replicaof主从复制,redis-sentinel哨兵

 

================================

©Copyright 蕃薯耀 2020-12-18

https://www.cnblogs.com/fanshuyao/

 

基于redis-5.0.10.tar.gz

一、Redis主从复制配置,从机配置

进行redis配置文件的目录,在redis.conf加入下面的配置(replicaof <masterip> <masterport>)

vim redis.conf
replicaof 192.168.170.11 6379

从机只读模式默认是开启的:

replica-read-only yes


或者(不打开配置文件,直接加到文件中):

echo "replicaof 192.168.170.11 6379" >> redis.conf

 

说明一下,replicaof是新版本的命令,旧版本是slaveof命令

(旧版本)使用slaveof命令:

slaveof 192.168.170.11 6379
slave-read-only yes

或者直接追加到配置文件

echo "slaveof 192.168.170.11 6379" >> redis.conf
echo "slave-read-only yes" >> redis.conf

 

二、查看redis主从配置

主机查看主从信息(先运行redis-cli)

127.0.0.1:6379> info replication

或者直接(不需要运行redis-cli):

/java/redis5/bin/redis-cli info replication

显示的内容是:

# Replication
role:master
connected_slaves:2
slave0:ip=192.168.170.129,port=6379,state=online,offset=1207,lag=0
slave1:ip=192.168.170.130,port=6379,state=online,offset=1207,lag=0
master_replid:498a75a7d0eeacef2b29664a4f1c848be4882460
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1207
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1207

role:master,表示是主机

 

从机查看主从信息(开启了redis-cli):

info replication

或者(不需要运行redis-cli)

/java/redis5/bin/redis-cli info replication

显示的内容:

127.0.0.1:6379> info replication
# Replication
role:slave
master_host:192.168.170.11
master_port:6379
master_link_status:up

role:slave,表示从机

 

测试从机有没有复制主机的值,建立主从关系后,从机自动会从主机复制所有数据:

/java/redis5/bin/redis-cli get b

显示内容

[root@host_132 ~]# /java/redis5/bin/redis-cli get b
"456"

 

测试在从机增加数据:

从机是只读模式,是不能设置值的:

127.0.0.1:6379> set c 12345
(error) READONLY You can't write against a read only replica.

 

三、Redis sentinel哨兵模式

Sentinel(哨兵)是用于监控redis集群中Master状态的工具,是Redis 的高可用性解决方案。

sentinel哨兵模式已经被集成在redis2.4之后的版本中。

sentinel是redis高可用的解决方案,sentinel系统可以监视一个或者多个redis master服务,以及这些master服务的所有从服务;

当某个master服务下线时,自动将该master下的某个从服务升级为master服务替代已下线的master服务继续处理请求。

sentinel可以让redis实现主从复制,当一个集群中的master失效之后,sentinel可以选举出一个新的master用于自动接替master的工作,集群中的其他redis服务器自动指向新的master同步数据。

一般建议sentinel采取奇数台,防止某一台sentinel无法连接到master导致误切换。其结构如下:

Linux Redis 主从复制,Redis slaveof replicaof主从复制,redis-sentinel哨兵

 

1、复制sentinel的配置文件sentinel.conf 到指定的目录

cp /java/redis5/sentinel.conf /java/redis5/bin/

2、去掉配置文件的注释和空行,生成新的配置文件

cd /java/redis5/bin/
cat sentinel.conf | grep -v "#" | grep -v "^$" > sentinel-26379.conf

3、修改配置文件sentinel-26379.conf

vim sentinel-26379.conf

修改内容:(这个文件夹要先建:/java/redis5/data/)

port 26379
daemonize yes
pidfile /java/redis5/data/redis-sentinel-26379.pid
logfile "redis-sentinel-26379.log"
dir /java/redis5/data/

4、修改ip地址,将127.0.0.1修改成192.168.170.11,端口如果是默认的,不需要修改,后面那个2表示2个redis-sentinel检查到master出问题后进入换master的方案。

sentinel monitor mymaster 192.168.170.11 6379 2

5、启动sentinel

/java/redis5/bin/redis-sentinel /java/redis5/bin/sentinel-26379.conf

6、查看进程:

ps -ef | grep redis-sentinel
[root@host_132 bin]# ps -ef | grep redis-sentinel
root       4303      1  0 09:32 ?        00:00:00 /java/redis5/bin/redis-sentinel *:26379 [sentinel]
root       4311   1396  0 09:32 pts/0    00:00:00 grep --color=auto redis-sentinel

 

四、设置redis-sentinel开机启动
1、创建服务文件(此方式为centos7的方式),文件原来是没有的。

vi /etc/systemd/system/redis-sentinel.service

开机启动文件内容:

[Unit]
#Description:描述服务
Description=RedisSentinel
#After:描述服务类别 
After=network.target

#服务运行参数的设置 
[Service]
#Type=forking是后台运行的形式 
Type=forking
#ExecStart为服务的具体运行命令,路径必须是绝对路径 
ExecStart=/java/redis5/bin/redis-sentinel /java/redis5/bin/sentinel-26379.conf
#ExecReload为重启命令 ,路径必须是绝对路径 
ExecReload=/java/redis5/bin/redis-sentinel -s reload
#ExecStop为停止命令 ,路径必须是绝对路径 
ExecStop=/java/redis5/bin/redis-sentinel -s stop
#PrivateTmp=True表示给服务分配独立的临时空间 
PrivateTmp=true

#运行级别下服务安装的相关设置,可设置为多用户,即系统运行级别为3
[Install]
WantedBy=multi-user.target

 

2、重载系统服务:

systemctl daemon-reload

3、将服务加入开机自启 (注意redis-sentinel.service后面不能跟空格 )

systemctl enable redis-sentinel.service

成功后提示:

[root@host_132 bin]# systemctl enable redis-sentinel.service
Created symlink from /etc/systemd/system/multi-user.target.wants/redis-sentinel.service to /etc/systemd/system/redis-sentinel.service.

4、测试开机启动是否成功,重启服务器

重启服务器

reboot -f

5、系统重启后,查看服务运行状态:

systemctl status redis-sentinel.service

或者查看进程

ps -ef | grep redis-sentinel

 

 五、Jedis测试Redis哨兵模式切换master

1、准备3台虚拟机,分别安装了redis和redis-sentinel

过程略。

 

2、引入jedis依赖

<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
</dependency>

 

3、编写Java代码测试:

import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;

public class RedisSentinel {

    private static Logger log = Logger.getLogger(RedisSentinel.class);
    
    public static void redisSentinel() {
        Set<String> sentinels = new HashSet<String>();
        sentinels.add("192.168.170.128:26379");//192.168.170.11
        sentinels.add("192.168.170.129:26379");//192.168.170.12
        sentinels.add("192.168.170.130:26379");//192.168.170.13
        JedisSentinelPool jedisSentinelPool = new JedisSentinelPool("mymaster", sentinels);
        Jedis jedis = jedisSentinelPool.getResource();
        String a = jedis.get("a");
        String b = jedis.get("b");
        System.out.println("a=" + a);
        System.out.println("b=" + b);
        jedis.close();
        jedisSentinelPool.close();
    }
    
    
    /**
     * 测试哨兵转移
     */
    public static void redisSentinelTransfer() {
        Set<String> sentinels = new HashSet<String>();
        sentinels.add("192.168.170.11:26379");
        sentinels.add("192.168.170.12:26379");
        sentinels.add("192.168.170.13:26379");
        @SuppressWarnings("resource")
        JedisSentinelPool jedisSentinelPool = new JedisSentinelPool("mymaster", sentinels);
        Jedis jedis = null;
        
        while(true) {
            try {
                //不能放在while里面,这样连接池在8次后会被用完,不执行redis方法,也不报错。
                //如果放在while,必须回收。
                jedis = jedisSentinelPool.getResource();
                int randInt = new Random().nextInt(10000);
                String key  = "k_" + randInt;
                String value  = "v_" + randInt;
                jedis.set(key, value);
                
                log.info(key + " = " + value);
                TimeUnit.SECONDS.sleep(2);
                
            } catch (Exception e) {
                log.info(e);
                
            } finally {
                if(jedis != null) {
                    jedis.close();
                }
            }
            
        }
        
    }
    
    
    public static void main(String[] args) {
        //redisSentinel();
        redisSentinelTransfer();
    }
    
    
}

 

4、直接通过kill -9 xxx 关闭Redis(主)的redis服务,测试master是否切换。

 

 

================================

©Copyright 蕃薯耀 2020-12-18

https://www.cnblogs.com/fanshuyao/

上一篇:SQLite数据类型(学习必备)


下一篇:# Redis5+(6.0.9) CentOS 7.6+ 安装及其主从哨兵配置(1主2从3哨兵)搭建