Redis主从复制 Redis的集群建

Redis主从复制

在这里插入图片描述

快速入门实践

1.将redis01拷贝两份

cp -r redis01/ redis02
cp -r redis01/ redis03

2.假如已有redis服务,先将原先所有redis服务停止(docker rm -f redis容器名)
3.启动新的redis容器

docker run -p 6379:6379 --name redis6379 \
-v /usr/local/docker/redis01/data:/data \
-v /usr/local/docker/redis01/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf \
--appendonly yes
docker run -p 6380:6379 --name redis6380 \
-v /usr/local/docker/redis02/data:/data \
-v /usr/local/docker/redis02/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf \
--appendonly yes
docker run -p 6381:6379 --name redis6381 \
-v /usr/local/docker/redis03/data:/data \
-v /usr/local/docker/redis03/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf \
--appendonly yes

4.检测redis服务角色

127.0.0.1:6379> info replication
\# Replication
role:master
connected_slaves:0
master_repl_offset:3860
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:3859

5.检测redis6379的ip设置

docker inspect redis6379
……
"Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "c33071765cb48acb1efed6611615c767b04b98e6e298caa0dc845420e6112b73",
                    "EndpointID": "4c77e3f458ea64b7fc45062c5b2b3481fa32005153b7afc211117d0f7603e154",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }

6.设置Master/Slave架构
分别登陆redis6380/redis6381,然后执行如下语句

slaveof 172.17.0.2 6379 

说明,假如master有密码,需要在slave的redis.conf配置文件中添加"masterauth 你的密码"这条语句,然后重启redis再执行slaveof 指令操作.
7.再次登陆redis6379,然后检测info

[root@centos7964 ~]# docker exec -it redis6379 redis-cli
127.0.0.1:6379> info replication
\# Replication
role:master
connected_slaves:2
slave0:ip=172.17.0.3,port=6379,state=online,offset=2004,lag=1
slave1:ip=172.17.0.4,port=6379,state=online,offset=2004,lag=1
master_failover_state:no-failover
master_replid:5baf174fd40e97663998abf5d8e89a51f7458488
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2004
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:2004

8.登陆redis6379测试,master读写都可以

[root@centos7964 ~]# docker exec -it redis6379 redis-cli
127.0.0.1:6379> set role master6379
OK
127.0.0.1:6379> get role
"master6379"
127.0.0.1:6379>

9.登陆redis6380测试,slave只能读。

[root@centos7964 ~]# docker exec -it redis6380 redis-cli
127.0.0.1:6379> get role
"master6379"
127.0.0.1:6379> set role slave6380
(error) READONLY You can't write against a read only replica.
127.0.0.1:6379>

Java中的读写测试分析,代码如下:

@SpringBootTest
public class MasterSlaveTests {
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    void testMasterReadWrite(){//配置文件端口为6379
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set("role", "master6379");
        Object role = valueOperations.get("role");
        System.out.println(role);
    }

    @Test
    void testSlaveRead(){//配置文件端口为6380
        ValueOperations valueOperations = redisTemplate.opsForValue();
        Object role = valueOperations.get("role");
        System.out.println(role);
    }

}

Redis哨兵模式

哨兵快速入门
1.分别进入3台redis容器内部进行配置,在容器指定目录/etc/redis创建sentinel.conf文件,文件内容为:

sentinel monitor redis6379 172.17.0.2 6379 1

其中, 如上指令表示要的监控的master, redis6379为服务名, 172.17.0.2和6379为master的ip和端口,1表示多少个sentinel认为一个master失效时,master才算真正失效.

假如,这里如果出现 bash: vi: command not found,可依次执行如下两个指令来安装vim

apt-get update 
apt-get install vim

网络不好,也可以在宿主机对应的挂载目录去创建文件,或者在容器中执行:

cat <<EOF > /etc/redis/sentinel.conf 
sentinel monitor redis6379 172.17.0.2 6379 1
EOF

2.在每个redis容器内部的执行cd /etc/redis目录下执行如下指令(最好是在多个客户端窗口执行),启动哨兵服务

redis-sentinel sentinel.conf

3.打开一个新的客户端连接窗口,关闭redis6379服务(这个服务是master服务)

docker stop redis6379

其它客户端窗口,检测日志输出,例如

410:X 11 Jul 2021 09:54:27.383 # +switch-master redis6379 172.17.0.2 6379 172.17.0.4 6379
410:X 11 Jul 2021 09:54:27.383 * +slave slave 172.17.0.3:6379 172.17.0.3 6379 @ redis6379 172.17.0.4 6379
410:X 11 Jul 2021 09:54:27.383 * +slave slave 172.17.0.2:6379 172.17.0.2 6379 @ redis6379 172.17.0.4 6379

4.登陆ip为172.17.0.4对应的服务进行info检测,例如:

127.0.0.1:6379> info replication
\# Replication
role:master
connected_slaves:1
slave0:ip=172.17.0.3,port=6379,state=online,offset=222807,lag=0
master_failover_state:no-failover
master_replid:3d63e8474dd7bcb282ff38027d4a78c413cede53
master_replid2:5baf174fd40e97663998abf5d8e89a51f7458488
master_repl_offset:222807
second_repl_offset:110197
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:29
repl_backlog_histlen:222779
127.0.0.1:6379>

从上面的信息输出发现,redis6381服务现在已经变为master。

Sentinel 配置进阶

对于sentinel.conf文件中的内容,我们还可以基于实际需求,进行增强配置,例如:

sentinel monitor redis6379 172.17.0.2 6379 1 
daemonize yes #后台运行
logfile "/var/log/sentinel_log.log" #运行日志
sentinel down-after-milliseconds redis6379 30000 #默认30秒

其中:
1)daemonize yes表示后台运行(默认为no)
2)logfile 用于指定日志文件位置以及名字
3)sentinel down-after-milliseconds 表示master失效了多长时间才认为失效

例如: 基于cat指令创建sentinel.conf文件,并添加相关内容.

cat <<EOF > /etc/redis/sentinel.conf
sentinel monitor redis6379 172.17.0.2 6379 1
daemonize yes 
logfile "/var/log/sentinel_log.log"
sentinel down-after-milliseconds redis6379 30000 
EOF

Redis集群高可用

基本架构

对于redis集群(Cluster),一般最少设置为6个节点,3个master,3个slave,其简易架构如下:

在这里插入图片描述

创建集群

1.准备网络环境
创建虚拟网卡,主要是用于redis-cluster能于外界进行网络通信,一般常用桥接模式.

docker network create redis-net

查看docker的网卡信息,可使用如下指令

docker network ls

查看docker网络详细信息,可使用命令

docker network inspect redis-net

2.准备redis配置模板

mkdir -p /usr/local/docker/redis-cluster
cd /usr/local/docker/redis-cluster
vim redis-cluster.tmpl

在redis-cluster.tmpl中输入以下内容

port ${PORT}
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 192.168.126.129
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}
appendonly yes

其中:

各节点解释如下所示:

  1. port:节点端口,即对外提供通信的端口
  2. cluster-enabled:是否启用集群
  3. cluster-config-file:集群配置文件
  4. cluster-node-timeout:连接超时时间
  5. cluster-announce-ip:宿主机ip
  6. cluster-announce-port:集群节点映射端口
  7. cluster-announce-bus-port:集群总线端口
  8. appendonly:持久化模式
    3.创建节点配置文件
    在redis-cluser中执行以下命令
for port in $(seq 8010 8015); \
do \
  mkdir -p ./${port}/conf  \
  && PORT=${port} envsubst < ./redis-cluster.tmpl > ./${port}/conf/redis.conf \
  && mkdir -p ./${port}/data; \
done

其中:

  • for 变量 in $(seq var1 var2);do …; done为linux中的一种shell 循环脚本, 例如:
[root@centos7964 ~]# for i in $(seq 1 5);
> do echo $i;
> done;
1
2
3
4
5
[root@centos7964 ~]#
  • 指令envsubst <源文件>目标文件,用于将源文件内容更新到目标文件中.
    通过cat指令查看配置文件内容
cat /usr/local/docker/redis-cluster/801{0..5}/conf/redis.conf

4.创建集群中的redis节点容器

for port in $(seq 8010 8015); \
do \
   docker run -it -d -p ${port}:${port} -p 1${port}:1${port} \
  --privileged=true -v /usr/local/docker/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
  --privileged=true -v /usr/local/docker/redis-cluster/${port}/data:/data \
  --restart always --name redis-${port} --net redis-net \
  --sysctl net.core.somaxconn=1024 redis redis-server /usr/local/etc/redis/redis.conf; \
done

其中, --privileged=true表示让启动的容器用户具备真正root权限, --sysctl net.core.somaxconn=1024 这是一个linux的内核参数,用于设置请求队列大小,默认为128,后续启动redis的启动指令需要先放到这个请求队列中,然后依次启动.
创建成功以后,通过docker ps指令查看节点内容。
5.创建redis-cluster集群配置

docker exec -it redis-8010 bash

如上指令要尽量放在一行执行,其中最后的1表示主从比例,当出现选择提示信息时,输入yes即可。当集群创建好以后,可以通过一些相关指令查看集群信息,例如

cluster nodes   #查看集群节点数
cluster info #查看集群基本信息

6.连接redis-cluster,并添加数据到redis

redis-cli -c -h 192.168.126.129 -p 8010

其中,这里-c表示集群(cluster),-h表示host(一般写ip地址),-p为端口(port)
其它:
在搭建过程,可能在出现问题后,需要停止或直接删除docker容器,可以使用以下参考命令:

批量停止docker 容器,例如:

docker ps -a | grep -i "redis-801*" | awk '{print $1}' | xargs docker stop

批量删除docker 容器,例如

docker ps -a | grep -i "redis-801*" | awk '{print $1}' | xargs docker rm -f

批量删除文件,目录等,例如:

rm -rf 801{0..5}/conf/redis.conf
rm -rf 801{0..5}

Jedis读写数据测试

@Test
void testJedisCluster()throws Exception{
      Set<HostAndPort> nodes = new HashSet<>();
      nodes.add(new HostAndPort("192.168.126.129",8010));
      nodes.add(new HostAndPort("192.168.126.129",8011));
      nodes.add(new HostAndPort("192.168.126.129",8012));
      nodes.add(new HostAndPort("192.168.126.129",8013));
      nodes.add(new HostAndPort("192.168.126.129",8014));
      nodes.add(new HostAndPort("192.168.126.129",8015));
      JedisCluster jedisCluster = new JedisCluster(nodes);
      //使用jedisCluster操作redis
      jedisCluster.set("test", "cluster");
      String str = jedisCluster.get("test");
      System.out.println(str);
      //关闭连接池
      jedisCluster.close();
 }

RedisTemplate读写数据测试

1.配置application.yml,例如:

spring:
  redis:
    cluster: #redis 集群配置
      nodes: 192.168.126.129:8010,192.168.126.129:8011,192.168.126.129:8012,192.168.126.129:8013,192.168.126.129:8014,192.168.126.129:8015
      max-redirects: 3 #最大跳转次数
    timeout: 5000 #超时时间
    database: 0
    jedis: #连接池
      pool:
        max-idle: 8
        max-wait: 0

第二步:编写单元测试类,代码如下:

package com.cy.redis;
@SpringBootTest
public class RedisClusterTests {
    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    void testMasterReadWrite(){
        //1.获取数据操作对象
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //2.读写数据
        valueOperations.set("city","beijing");
        Object city=valueOperations.get("city");
        System.out.println(city);
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值