第一部分 Spring整合Redis

一、准备工作

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_redis


springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_02


springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_03


springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_04

二、入门案例1

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_05


masterName主机名: mymaster

sentinel: ip:端口号

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_06

import redis.clients.jedis.JedisSentinelPool;

public class TestSentinel {

	@Test
	public void testSentinel1() {
		String masterName = "mymaster";//主机名
		Set<String> sentinels = new HashSet<>();//哨兵类型
		sentinels.add("192.168.126.166:26379"); //添加哨兵主机名端口号
		// sentinels.add("192.168.126.166:26380");
		// sentinels.add("192.168.126.166:26381");
		// sentinels.add("192.168.126.166:26382");

		// 获取哨兵连接     主机名 哨兵IP:端口号
		JedisSentinelPool sentinelPool = new JedisSentinelPool(masterName, sentinels);
		
//		哨兵设定资源
		Jedis jedis = sentinelPool.getResource();
		jedis.set("commandOne", "commandOne哨兵jedis发来贺电");
//		输出哨兵资源
		System.out.println("获取资源:"+jedis.get("commandOne"));

//		将连接池带着jedis的连接返还给资源
		sentinelPool.returnResource(jedis);
	}
}

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_redis_07


springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_08

三、入门案例2

1、编辑Pro文件

#redis.host=192.168.126.166
#redis.port.a=6379
#redis.port.b=6380
#redis.port.c=6381
redis.maxTotal=10000
redis.sentinel=192.168.126.166:26379
redis.masterName=mymaster

2、编辑application-redis配置文件,注释掉单台redis、分片redis配置

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_09

<!-- 构造注入, sentinels属性对应set集合,要使用set标签 -->
	<bean id="jedisSentinelPool"
		class="redis.clients.jedis.JedisSentinelPool">
		<constructor-arg name="masterName"
			value="${redis.masterName}" />
		<constructor-arg name="sentinels">
			<set>
				<value>${redis.sentinels}</value>
			</set>
		</constructor-arg>
		<constructor-arg name="poolConfig" ref="poolConfig" />
	</bean>

	<!-- 定义池对象 -->
	<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
		<property name="maxTotal" value="${redis.maxTotal}" />
	</bean>

3、修改common项目下的RedisService,把分片使用的内容注释掉

@Service
public class RedisService {

//	使用redis哨兵
	@Autowired(required=false)
	private JedisSentinelPool jedisSentinelPool;
	
	public void set(String key,String value) {
		Jedis jedis = jedisSentinelPool.getResource();
		jedis.set(key, value);
		jedisSentinelPool.returnResource(jedis);
	}
	
	public String get(String key) {
		Jedis jedis = jedisSentinelPool.getResource();
		String result = jedis.get(key);
		jedisSentinelPool.returnResource(jedis);
		return result;
	}
}

注意:修改后要重新打包发布,maven install

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_10


springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_11

第二部分 Redis集群

Redis集群

1、分片作用:可以动态的实现内存扩容,可以将数据分散保存
2、哨兵作用:实现redis高可用
Redis集群实现:
采用redis集群配置,在集群内部实现通信和选举,同时实现分片的扩容和redis高可用性
3、脑裂
因为选举机制投票平票的结果导致出现多台主机,这种现象称之为脑裂。
解决:让节点个数增加(保证超半数即可)

集群搭建步骤【关闭所有开启的redis】

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_12


一、划分集群规模

规模:3主6从【真实:15-20】

端口:70000-7008共9台

二、搭建步骤:

1. 复制redis文件到7000文件夹下

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_13


springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_14

  • 关闭AOF,使用RDB存储模式
  • springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_15

  • 取消ip绑定
  • springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_16

  • 关闭保护模式
  • springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_17

  • 修改端口号
  • springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_18

  • 开启后台启动
  • springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_19

  • 修改PID路径
  • springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_20

  • 修改持久化文件路径
  • springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_redis_21

  • 修改内存策略
  • springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_redis_22

  • 开启集群
  • springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_23

  • 开启集群配置文件
  • springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_24

  • 修改集群推选时间
  • springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_redis_25

2.复制7000文件夹

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_redis_26


快速替换

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_27


springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_28


编写快速启动脚本文件

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_29


springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_30


启动脚本

sh start.sh

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_31

通过ruby创建管理redis集群

./src/redis-trib.rb create --replicas 2 192.168.126.166:7000 192.168.126.166:7001 192.168.126.166:7002 192.168.126.166:7003 192.168.126.166:7004 192.168.126.166:7005 192.168.126.166:7006 192.168.126.166:7007 192.168.126.166:7008

集群划分:

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_32


springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_33


springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_redis_34


springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_35


往7000里写入一个aa,但是bb不能写在7000里了

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_36


7000是主机,7003和7004是从机。当关闭7000时,查看7003状态,主机从7001变为7004

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_redis_37


高可用实现了。

重新开启7000服务

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_38


发现7000变为从机,主机7004

高可用实现了!

集群宕机条件:
9台机器3主6从,宕机多少台集群会崩溃?
一般最小的宕机次数,即超过半数宕机

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_39

第三部分 spring整合集群入门案例

package com.zz.redis;

import java.util.HashSet;
import java.util.Set;

import org.junit.Test;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;

public class TestCluster {

	@Test
	public void testCluster() {
		
		Set<HostAndPort> nodes = new HashSet<>();
		nodes.add(new HostAndPort("192.168.126.166", 7000));
		nodes.add(new HostAndPort("192.168.126.166", 7001));
		nodes.add(new HostAndPort("192.168.126.166", 7002));
		nodes.add(new HostAndPort("192.168.126.166", 7003));
		nodes.add(new HostAndPort("192.168.126.166", 7004));
		nodes.add(new HostAndPort("192.168.126.166", 7005));
		nodes.add(new HostAndPort("192.168.126.166", 7006));
		nodes.add(new HostAndPort("192.168.126.166", 7007));
		nodes.add(new HostAndPort("192.168.126.166", 7008));
		JedisCluster jedisCluster = new JedisCluster(nodes);
		
		jedisCluster.set("hello", "我是lz的爸爸呀");
		System.out.println(jedisCluster.get("hello"));
		jedisCluster.close();
	}
}

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_spring_40

一、工厂模式–spring中的工厂模式

1、工厂模式作用

核心思想:
实例化对象
什么对象才使用工厂模式?
需求:
1、多例对象的创建 new
2、有些对象 例如接口/抽象类不能直接实例化。接口–代理,抽象类–创建子类
3、需要对对象进行二次封装

2、静态工厂:

静态工厂中要求必须有静态方法。【调用方式 类名.静态方法】

StaticFactory类

public static Calendar getInstance() {
		return Calendar.getInstance();
	}

factory.xml

<!-- 配置静态工厂 抽象类不能只通过class反射到方法-->
	<bean id="calendarA" class="java.util.Calendar" 
	factory-method="getInstance"/>

测试类

public class TestFactory {
	@Test
	public void testFactory() {
//		实例化spring容器
		ApplicationContext context = new ClassPathXmlApplicationContext("spring/factory.xml");
		Calendar calendarA = (Calendar)context.getBean("calendarA");
		System.out.println("测试:"+calendarA.getTime());	
	}
}

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_41

3、实例化工厂:

说明:实例化工厂必须先创建工厂对象,之后通过工厂方法调用获取对象

InstanceFactory工厂类

public Calendar getInstance() {
		return Calendar.getInstance();
	}

factory.xml

<!-- 实例化工厂 -->
	<bean id="instanceFactory" class="com.jt.manage.factory.InstanceFactory"></bean>
	<bean id="calendarB" 
	factory-bean="instanceFactory"
	factory-method="getInstance"/>

测试类

@Test
	public void testFactory() {
//		实例化spring容器
		ApplicationContext context = new ClassPathXmlApplicationContext("spring/factory.xml");
		Calendar calendarA = (Calendar)context.getBean("calendarA");
		System.out.println("测试:"+calendarA.getTime());
		
		Calendar calendarB = (Calendar)context.getBean("calendarB");
		System.out.println("测试:"+calendarB.getTime());
	}

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_42

4、spring工厂

说明:该模式有spring内部调用,不需要多余的配置,但是要实现特定的接口。

SpringFactory类

public class SpringFactory implements FactoryBean<Calendar> {

	@Override
	public Calendar getObject() throws Exception {
		// TODO Auto-generated method stub
		return Calendar.getInstance();
	}

	@Override
	public Class<?> getObjectType() {
		// TODO Auto-generated method stub
		return Calendar.class;
	}

	@Override
	public boolean isSingleton() {
		// TODO Auto-generated method stub
		return false;//true单例  false多例
	}

}

factory.xml

<!-- 配置spring工厂 -->
	<bean id="calendarC" class="com.jt.manage.factory.SpringFactory"></bean>

测试类

@Test
	public void testFactory() {
//		实例化spring容器
		ApplicationContext context = new ClassPathXmlApplicationContext("spring/factory.xml");
		Calendar calendarA = (Calendar)context.getBean("calendarA");
		System.out.println("测试:"+calendarA.getTime());
		
		Calendar calendarB = (Calendar)context.getBean("calendarB");
		System.out.println("测试:"+calendarB.getTime());
		
		Calendar calendarC = (Calendar)context.getBean("calendarC");
		System.out.println("测试:"+calendarC.getTime());
	}

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_43

二、spring整合redis集群【使用工厂模式】

1、编辑pro配置文件

#最小空闲数
redis.minIdle=100
#最大空闲数
redis.maxIdle=300
#最大连接数
redis.maxTotal=1000
#客户端超时时间单位是毫秒 
redis.timeout=5000
#最大建立连接等待时间  
redis.maxWait=1000
#是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
redis.testOnBorrow=true

#redis cluster
redis.cluster0=192.168.126.166:7000
redis.cluster1=192.168.126.166:7001
redis.cluster2=192.168.126.166:7002
redis.cluster3=192.168.126.166:7003
redis.cluster4=192.168.126.166:7004
redis.cluster5=192.168.126.166:7005
redis.cluster6=192.168.126.166:7006
redis.cluster7=192.168.126.166:7007
redis.cluster8=192.168.126.166:7008

2、修改Application-context-redis.xml

<!-- jedis 配置-->  
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" >  
        <!--最大空闲数-->  
        <property name="maxIdle" value="${redis.maxIdle}" />  
        <!--最大建立连接等待时间-->  
        <property name="maxWaitMillis" value="${redis.maxWait}" />  
        <!--是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个-->  
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />  
        <property name="maxTotal" value="${redis.maxTotal}" />  
        <property name="minIdle" value="${redis.minIdle}" />  
    </bean>
    
     <!--通过工厂模式获取数据  -->
    <bean id="jedisCluster" class="com.jt.common.factory.JedisClusterFactory">
    	<!--引入配置文件源文件  -->
    	<property name="propertySource">
    		<value>classpath:/property/redis.properties</value>
    	</property>
    	<!--引入池配置文件  -->
    	<property name="poolConfig" ref="poolConfig"/>
    	<!--添加配置前缀-->
    	<property name="redisNodePrefix" value="redis.cluster"/>
    </bean>

3、在common项目中添加JedisClusterFactory类

public class JedisClusterFactory implements FactoryBean<JedisCluster> {
	//引入pro配置文件
		private Resource propertySource;
		private JedisPoolConfig poolConfig;
		private String redisNodePrefix;
		
		//获取Set集合信息
		public Set<HostAndPort> getNodes(){
			Set<HostAndPort> nodes = new HashSet<>();
			
			//操作pro对象
			Properties pro = new Properties();
			try {
				pro.load(propertySource.getInputStream());
				
				//遍历获取nodes节点数据
				for (Object key : pro.keySet()) {
					//将key变为String类型 目的判断字符串方便
					String strKey = (String) key;
					
					//判断哪个是redis节点数据
					if(strKey.startsWith(redisNodePrefix)){
						//IP:端口
						String value = pro.getProperty(strKey);
						String[] args = value.split(":");
						HostAndPort hostAndPort = 
						new HostAndPort(args[0],Integer.parseInt(args[1]));
						nodes.add(hostAndPort);
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			return nodes;
		}
		
		@Override
		public JedisCluster getObject() throws Exception {
			
			Set<HostAndPort> nodes = getNodes();
			
			return new JedisCluster(nodes, poolConfig);
		}

		@Override
		public Class<?> getObjectType() {
			
			return JedisCluster.class;
		}

		@Override
		public boolean isSingleton() {
			
			return false;
		}

		public Resource getPropertySource() {
			return propertySource;
		}

		public void setPropertySource(Resource propertySource) {
			this.propertySource = propertySource;
		}

		public JedisPoolConfig getPoolConfig() {
			return poolConfig;
		}

		public void setPoolConfig(JedisPoolConfig poolConfig) {
			this.poolConfig = poolConfig;
		}

		public String getRedisNodePrefix() {
			return redisNodePrefix;
		}

		public void setRedisNodePrefix(String redisNodePrefix) {
			this.redisNodePrefix = redisNodePrefix;
		}	
	}

springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_redis_44


springboot集成redis哨兵配db 1 redis的哨兵模式+spring整合_实例化_45

Spring整合Redis集群完成了!