一、Spring整合redis(单机版)

1、pom.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>redisdemo</groupId>
    <artifactId>com.mh.redis</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.1.0-m1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.1.7.RELEASE</version>
        </dependency>
    </dependencies>
</project>

2、redis.properties配置文件

#ip地址
redis.host= 127.0.0.1    
#端口号
redis.port = 6379
# 密码 (如果有密码需要配置)
redis.password = root
#客户端超时时间单位是毫秒 默认是2000
redis.timeout = 3000
#数据库,默认的是0
redis.database = 0
#最大空闲链接
redis.maxIdle=300 
#最小的空闲链接
redis.minIdle=10
#连接池的最大数据库连接数
redis.maxTotal=400
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
redis.maxWaitMillis=1000
#在空闲时检查有效性, 默认false
redis.testOnBorrow=false
#连接耗尽是否阻塞,false代表抛异常,true代表阻塞直到超时,默认为true
redis.blockWhenExhausted=false

3、spring的配置文件

<?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" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <bean class="com.mh.redis.mapper.SingleReidsMapper" id="singleRedis">
        <property name="jedisPool" ref="jedisPool"></property>
    </bean>
 <!--加载redis的配置文件-->
    <context:property-placeholder location="classpath:redis.properties"/>
   <!--JedisPool这个bean的构造方法需要多个参数,使用构造方法的方式注入bean -->
    <bean class="redis.clients.jedis.JedisPool" id="jedisPool">
        <constructor-arg name="host" value="${redis.host}"></constructor-arg>
        <constructor-arg name="port" value="${redis.port}"></constructor-arg>
        <constructor-arg name="password" value="${redis.password}"></constructor-arg>
        <constructor-arg name="timeout" value="${redis.timeout}"></constructor-arg>
        <constructor-arg name="database" value="${redis.database}"></constructor-arg>
        <constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg>
    </bean>
    <!--redis配置项-->
    <bean class="redis.clients.jedis.JedisPoolConfig" id="jedisPoolConfig">
        <property name="maxIdle" value="${redis.maxIdle}" />
        <property name="minIdle" value="${redis.minIdle}" />
        <property name="maxTotal" value="${redis.maxTotal}" />
        <property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />
        <property name="blockWhenExhausted" value="${redis.blockWhenExhausted}" />
    </bean>
</beans>

4、操作redis的接口

public interface RedisMapper {
    String set(String key, String value);

    String get(String key);

    Boolean exists(String key);

    Long expire(String key, int seconds);

    Long ttl(String key);

    Long incr(String key);

    Long hset(String key, String field, String value);

    String hget(String key, String field);

    Long hdel(String key, String... field);

    Boolean hexists(String key, String field);

    List<String> hvals(String key);

    Long del(String key);

}

5、实现类

public class SingleReidsMapper implements RedisMapper{

    private JedisPool jedisPool;

    public JedisPool getJedisPool() {
        return jedisPool;
    }

    public void setJedisPool(JedisPool jedisPool) {
        this.jedisPool = jedisPool;
    }

    @Override
    public String set(String key, String value) {
        Jedis jedis = jedisPool.getResource();
        String result = jedis.set(key, value);
        jedis.close();
        return result;
    }

    @Override
    public String get(String key) {
        Jedis jedis = jedisPool.getResource();
        String result = jedis.get(key);
        jedis.close();
        return result;
    }

    @Override
    public Boolean exists(String key) {
        Jedis jedis = jedisPool.getResource();
        Boolean result = jedis.exists(key);
        jedis.close();
        return result;
    }

    @Override
    public Long expire(String key, int seconds) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.expire(key, seconds);
        jedis.close();
        return result;
    }

    @Override
    public Long ttl(String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.ttl(key);
        jedis.close();
        return result;
    }

    @Override
    public Long incr(String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.incr(key);
        jedis.close();
        return result;
    }

    @Override
    public Long hset(String key, String field, String value) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.hset(key, field, value);
        jedis.close();
        return result;
    }

    @Override
    public String hget(String key, String field) {
        Jedis jedis = jedisPool.getResource();
        String result = jedis.hget(key, field);
        jedis.close();
        return result;
    }

    @Override
    public Long hdel(String key, String... field) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.hdel(key, field);
        jedis.close();
        return result;
    }

    @Override
    public Boolean hexists(String key, String field) {
        Jedis jedis = jedisPool.getResource();
        Boolean result = jedis.hexists(key, field);
        jedis.close();
        return result;
    }

    @Override
    public List<String> hvals(String key) {
        Jedis jedis = jedisPool.getResource();
        List<String> result = jedis.hvals(key);
        jedis.close();
        return result;
    }

    @Override
    public Long del(String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.del(key);
        jedis.close();
        return result;
    }
}

6、测试类

public class RedisTest {
    @Test
    public void redisTest(){
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        SingleReidsMapper redis = context.getBean(SingleReidsMapper.class);
        redis.set("k1", "哼哼");
        String value = redis.get("k1");
        System.out.println(value);
    }
}

//这里的测试只是整合一个,其他的都和这个类似,如果感兴趣可以自己动手实践

二、Spring整合redis(集群)

1、搭建集群的环境

redis集群最少需要三个节点,因为投票容错机制要求超过半数节点挂了改节点才是挂了。要保证集群的高可用,需要每个节点都有从节点,也就是备份节点,所以redis集群至少需要6台服务器

1.1 修改每台服务器上redis的配置文件

注:修改:bind 127.0.0.1 为自己的ip地址,集群不要在bind上设置回环ip地址,负责后面创建的时候可能出问题。

cluster-enabled yes       #开启集群
cluster-config-file nodes-6379.conf       
#每个加入集群的redis服务器都会自动生成一个节点配置文件,这里设置名称
cluster-node-timeout 10000    
#节点互联超时时间,超过这个设置的时间redis会触发故障迁移,把某台从服务器提升为主服务器
cluster-slave-validity-factor < factor>:    (redis5.0以后将slave 变成了replica)
#在进行故障转移的时候全部slave都会请求申请为master,但是有些slave可能与master断开连接一段时间,导致数据过于陈旧,不应该被提升为master。该参数就是用来判断slave节点与master断线的时间是否过长。判断方法是:比较slave断开连接的时间和(node-timeout * slave-validity-factor)+ repl-ping-slave-period,如果节点超时时间为三十秒, 并且slave-validity-factor为10,假设默认的repl-ping-slave-period(定义心跳(PING)间隔。)是10秒,即如果超过310秒slave将不会尝试进行故障转移。

cluster-migration-barrier < count>: 
 #master的slave数量大于该值,slave才能迁移到其他孤立master上,如这个参数被设为2,那么只有当一个主节点拥有2个可工作的从节点时,它的一个从节点才会尝试迁移。

cluster-require-full-coverage < yes/no>:
#设置为yes,这也是默认值,集群全部的slot有节点负责,集群状态才为ok并提供服务。设置为no可以在slot没有全部分配的时候提供服务。不建议打开该配置,这样会造成分区的时候,小分区的master一直在接受写请求,而造成很长时间数据不一致。

cluster-slave-no-failover/cluster-replica-no-failover
在主节点失效期间,从节点不允许对master失效转移,取值yes,no
2、准备好集群环境,下面我们在单机版的基础上来实现spring整合redis 的集群版。

1、修改spring的配置文件

<?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" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 连接redis集群 -->
	<bean class="cn.ybzy.springredis.dao.RedisCluster" id="redisCluster">
		<property name="jedisCluster" ref="jedisCluster"/>
	</bean>
	<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
		<constructor-arg name="nodes">
			<set>
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.238.4"></constructor-arg>
					<constructor-arg name="port" value="6379"></constructor-arg>
				</bean> 
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.238.5"></constructor-arg>
					<constructor-arg name="port" value="6379"></constructor-arg>
				</bean> 
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.238.6"></constructor-arg>
					<constructor-arg name="port" value="6379"></constructor-arg>
				</bean> 
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.238.7"></constructor-arg>
					<constructor-arg name="port" value="6379"></constructor-arg>
				</bean> 
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.238.8"></constructor-arg>
					<constructor-arg name="port" value="6379"></constructor-arg>
				</bean> 
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.238.9"></constructor-arg>
					<constructor-arg name="port" value="6379"></constructor-arg>
				</bean> 
			</set>
		</constructor-arg>
<!--constructor-arg .....根据构造函数的参数来设置!-->
	</bean>
</beans>

2、RedisMapper 接口的实现类 (集群版)RedisCluster

public class JedisPoolDaoImpl2  implements JedisClient {
	private JedisCluster jedisCluster;
	public JedisCluster getJedisCluster() {
		return jedisCluster;
	}
	public void setJedisCluster(JedisCluster jedisCluster) {
		this.jedisCluster = jedisCluster;
	}
	@Override
	public String set(String key, String value) {
		return jedisCluster.set(key, value);
	}
	@Override
	public String get(String key) {
		return jedisCluster.get(key);
	}
	@Override
	public Boolean exists(String key) {
		return jedisCluster.exists(key);
	}
	@Override
	public Long expire(String key, int seconds) {
		return jedisCluster.expire(key, seconds);
	}
	@Override
	public Long ttl(String key) {
		return jedisCluster.ttl(key);
	}
	@Override
	public Long incr(String key) {
		return jedisCluster.incr(key);
	}
	@Override
	public Long hset(String key, String field, String value) {
		return jedisCluster.hset(key, field, value);
	}
	@Override
	public String hget(String key, String field) {
		return jedisCluster.hget(key, field);
	}
	@Override
	public Long hdel(String key, String... field) {
		return jedisCluster.hdel(key, field);
	}
	@Override
	public Boolean hexists(String key, String field) {
		return jedisCluster.hexists(key, field);
	}
	@Override
	public List<String> hvals(String key) {
		return jedisCluster.hvals(key);
	}
	@Override
	public Long del(String key) {
		return jedisCluster.del(key);
	}
}

测试和单例测试一样,这里不做演示了!!

后续我会出SpringBoot整合redis的博客,希望对大家有所帮助!