美文网首页
搭建redis主从从+哨兵模式(故障转移)及应用JavaAPI

搭建redis主从从+哨兵模式(故障转移)及应用JavaAPI

作者: 阿文很淘气 | 来源:发表于2020-04-14 15:33 被阅读0次

自已撸的,一针一线,有图有真相
Step1准备好redis-5.0.8.tar.gz 包

Step2 上传到centos7 /root 目录下面

Step3 解压 tar -zxvf redis-5.0.8.tar.gz

Step4 编译 make

Step5 安装 make install
若报error,基本上是没有安装gcc ,make 等lib库
yum install -y gcc g++ gcc-c++ make

Step6 安装成功以后。配置环境变量
vim /etc/profile

export PATH=${JAVA_HOME}/bin:/root/redis-5.0.8/src:${ZOOKEEPER_HOME}/bin:${KAFKA_HOME}/bin:/usr/local/openssh-8.1p1/sbin:/usr/local/openssh-8.1p1/bin:$PATH 

执行 source /etc/profile 生效

Step7文件目录定位到/root/redis-5.0.8/
在机器ip为172.16.104.219 ,机器ip为,机器ip为 上面分别创建cluster 用于配置文件里面的dir路径。
mkdir cluster
pwd 查询路径 正确样式为/root/redis-5.0.8/cluster

Step8 修改三台机器的redis.conf 文件
Master 机器
vim /root/redis-5.0.8/redis.conf

port 6379
#bind 172.16.104.198

masterauth "123456."

requirepass "123456."

daemonize yes

pidfile "/var/run/redis_6379.pid"

protected-mode no

#cluster-enabled no

#cluster-config-file nodes_6379.conf

#cluster-node-timeout 15000

appendonly yes

logfile "/tmp/redis6379.log"

dir "/root/redis-5.0.8/cluster"

Slave1机器

vim /root/redis-5.0.8/redis.conf

port 6379

#bind 172.16.104.210

masterauth "123456."

requirepass "123456."

daemonize yes

pidfile "/var/run/redis_6379.pid"

protected-mode no

#cluster-enabled no

#cluster-config-file nodes_6379.conf

#cluster-node-timeout 15000

appendonly yes

logfile "/tmp/redis6379.log"

dir "/root/redis-5.0.8/cluster"

slaveof 172.16.104.198 6379

Slave2机器

vim /root/redis-5.0.8/redis.conf

port 6379

#bind 172.16.104.219

masterauth "123456."

requirepass "123456."

daemonize yes

pidfile "/var/run/redis_6379.pid"

protected-mode no

#cluster-enabled no

#cluster-config-file nodes_6379.conf

#cluster-node-timeout 15000

appendonly yes

logfile "/tmp/redis6379.log"

dir "/root/redis-5.0.8/cluster"

slaveof 172.16.104.198 6379

修改 三台机器的 哨兵 配置 文件 sentinel.conf
配置一样

port 26379

daemonize yes

pidfile "/var/run/redis-sentinel_6379.pid"

logfile "/tmp/sentinel6379.log"

dir "/tmp"

protected-mode no

sentinel monitor mymaster 172.16.104.198 6379 2

sentinel down-after-milliseconds mymaster 15000

sentinel failover-timeout mymaster 60000

sentinel auth-pass mymaster 123456.

sentinel config-epoch mymaster 1

sentinel leader-epoch mymaster 1

sentinel current-epoch 1

Step8 完成以上配置进行启动,先启动主master机器 上的redis ,然后在启动从slave机器上的redis。再启动 分别三台机上面sentinel

主(ip:172.16.104.198)机器redis-server /root/redis-5.0.8/redis.conf

从redis-server /root/redis-5.0.8/redis.conf

从redis-server /root/redis-5.0.8/redis.conf

redis-sentinel /root/redis-5.0.8/sentinel.conf

redis-sentinel /root/redis-5.0.8/sentinel.conf

redis-sentinel /root/redis-5.0.8/sentinel.conf

ps -ef|grep redis 查看启动情况

图片1.png

Step9测试连接

连接主节点redis-cli -h 172.16.104.198 -p 6379 -a 123456.

连接从节点redis-cli -h 172.16.104.210 -p 6379 -a 123456.

图片2.png

另外一种连接方式

图片3.png

主节点和备用的从节点数据是一致的。

图片4.png

主节点可读可写,从节点做为备份节点只读。

图片5.png

通过 info查看节点当前的角色

图片6.png

退出redis客户端连接使用exit

图片7.png

Step10下面测试sentinel哨兵 故障转移

先kill掉主节点的redis 进程

ps-ef|grep redis

图片8.png

当主节点redis进程被杀死以后,再次去连接主节点将失败。

图片9.png

此时,哨兵sentinel就开始通过上面的配置timeout时间,多个sentinel认定主节点客观宕机。多个sentinel自己进行选举出新的主节点。

客户端连接 172.16.104.210 机器 通过info查看Replication信息发现此时它已经是master主节点了。

redis-cli -h 172.16.104.210 -p 6379 -a 123456. 图片10.png 图片11.png

通过上面的图,清晰的看到 sentinel已经完成了故障转移,主备的切换。

在有了哨兵模式的主从架构,可靠性明显提升了。

为了做到高可用。使用 supervisor守护进程, 每台机器把redis,sentinel服务加进去。supervisor本身设置开机启动。还可以直接把进程做成开机自启动 通过/etc/rc.d/init.d 编写shell命令启动脚本,然后添加软连接到rc3.d和rc5.d下面。服务部署至此完结!

JavaAPI

先建立spring-sentinels-redis.xml文件

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xmlns:context="http://www.springframework.org/schema/context"

       xsi:schemaLocation="http://www.springframework.org/schema/beans

                        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

                        http://www.springframework.org/schema/context

                        http://www.springframework.org/schema/context/spring-context.xsd">

    <description>redis 相关类 Spring 托管</description>

     <!--载入 redis 配置文件-->

    <context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true"/>

   <bean id = "poolConfig" class="redis.clients.jedis.JedisPoolConfig">

            <!-- 最大空闲数 -->

            <property name="maxIdle" value="50"></property>

            <!-- 最大连接数 -->

            <property name="maxTotal" value="100"></property>

            <!-- 最大等待时间 -->

            <property name="maxWaitMillis" value="20000"></property>

        </bean>

         <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">

            <constructor-arg name="poolConfig" ref="poolConfig"></constructor-arg>

            <constructor-arg name="sentinelConfig" ref="sentinelConfig"></constructor-arg>

            <property name="password" value="123456."></property>

        </bean>      

        <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">  

          <property name="connectionFactory" ref="connectionFactory"></property>  

          <property name="keySerializer">

<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />

</property>

<property name="valueSerializer">

<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />

</property>

<property name="hashKeySerializer">

<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />

</property>

<property name="hashValueSerializer">

<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />

</property>

      </bean>

        <!-- 哨兵配置 -->

        <bean id="sentinelConfig" class="org.springframework.data.redis.connection.RedisSentinelConfiguration">

            <!-- 服务名称 -->

            <property name="master">

                <bean class="org.springframework.data.redis.connection.RedisNode">

                    <property name="name" value="mymaster"></property>

                </bean>

            </property>

            <!-- 哨兵服务IP和端口 -->

            <property name="sentinels">

                <set>

                    <bean class="org.springframework.data.redis.connection.RedisNode">

                        <constructor-arg name="host" value="172.16.104.198"></constructor-arg>

                        <constructor-arg name="port" value="26379"></constructor-arg>

                    </bean>

                    <bean class="org.springframework.data.redis.connection.RedisNode">

                        <constructor-arg name="host" value="172.16.104.210"></constructor-arg>

                        <constructor-arg name="port" value="26379"></constructor-arg>

                    </bean>

                    <bean class="org.springframework.data.redis.connection.RedisNode">

                        <constructor-arg name="host" value="172.16.104.219"></constructor-arg>

                        <constructor-arg name="port" value="26379"></constructor-arg>

                    </bean>

                </set>

            </property>

        </bean>

</beans>  

创建Test测试类

package com.wenjin.zhu.redis;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.HashMap;

import java.util.HashSet;

import java.util.List;

import java.util.Map;

import java.util.Set;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.test.context.ContextConfiguration;

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import redis.clients.jedis.Jedis;

import redis.clients.jedis.JedisPoolConfig;

import redis.clients.jedis.JedisSentinelPool;

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = "classpath:redis/spring-sentinels-redis.xml")

public class Test{

@Autowired

private RedisTemplate<Object, Object> redisTemplate;

@SuppressWarnings("unchecked")

@Test

public void testSentinel() {

JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();

jedisPoolConfig.setMaxTotal(10);

jedisPoolConfig.setMaxIdle(5);

jedisPoolConfig.setMinIdle(5);

Set<String> sentinels = new HashSet<String>(

Arrays.asList("172.16.104.198:26379","172.16.104.210:26379", "172.16.104.219:26379"));

JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels, jedisPoolConfig, "123456.");

Jedis jedis = pool.getResource();

// 执行两个命令

jedis.set("name", "wenjin.zhu");

String value = jedis.get("testname");

System.err.println(value+jedis.get("tt"));

System.err.println("***"+redisTemplate.opsForValue().get("testname"));

Map<String, String> map = new HashMap<String, String>();

map.put("name", "jack");

map.put("age", "27");

map.put("class", "1");

redisTemplate.opsForHash().putAll("hashOps", map);

List<Object> kes = new ArrayList<Object>();

kes.add("name");

kes.add("age");

kes.add("class");

System.out.println(redisTemplate.opsForHash().multiGet("hashOps", kes));

}

@SuppressWarnings("unchecked")

@Test

public void testOpsValue() {

redisTemplate.opsForValue().set("testname","Amy");

System.err.println("***"+redisTemplate.opsForValue().get("testname"));

}

}

操作中遇到问题,欢迎在评论区留言一起探讨!
如果对你有帮助,点个赞。关注的话,可以在主页中看我更多的技术文档

相关文章

网友评论

      本文标题:搭建redis主从从+哨兵模式(故障转移)及应用JavaAPI

      本文链接:https://www.haomeiwen.com/subject/dhzouhtx.html