蚊子的redis笔记 - 实战篇(四)

Redis集群

问题说明

  1. 分片作用
    a. 可以动态的实现内存扩容
    b. 可以将数据分散保存.
  2. 哨兵作用
    可以实现redis高可用(ha)

Redis集群实现

说明:采用redis集群配置,在集群内部实现通信和选举,同时实现分片的扩容和redis高可用性.

脑裂

说明:因为选举机制投票平票的结果导致出现多台主机.这种现象称之为脑裂.
解决:让节点个数增加(保证超半数即可)

集群搭建步骤

划分集群规模

规模:3主6从
端口:7000-7008共9台

搭建步骤

  1. 复制redis.conf文件到7000下
cp redis.conf cluster/7000
  1. 关闭aof使用rdb模式 593行
    在这里插入图片描述
  2. 取消IP绑定
    在这里插入图片描述
  3. 关闭保护模式
    在这里插入图片描述
  4. 修改端口号
    在这里插入图片描述
  5. 开启后台启动
    在这里插入图片描述
  6. 修改PID位置 150行
    在这里插入图片描述
  7. 修改持久化文件路径
    在这里插入图片描述
  8. 修改内存策略
    在这里插入图片描述
  9. 开启集群
    在这里插入图片描述
  10. 开启集群配置
    在这里插入图片描述
  11. 修改集群推选时间
    在这里插入图片描述

复制7000文件夹

[root@localhostcluster]# cp -r 7000 7001
[root@localhostcluster]# cp -r 7000 7002
[root@localhostcluster]# cp -r 7000 7003
[root@localhostcluster]# cp -r 7000 7004
[root@localhostcluster]# cp -r 7000 7005
[root@localhostcluster]# cp -r 7000 7006
[root@localhostcluster]# cp -r 7000 7007
[root@localhostcluster]# cp -r 7000 7008

修改多个文件端口

分别修改7001-7008文件
在这里插入图片描述

[root@localhostcluster]# vim 7001/redis.conf
[root@localhostcluster]# vim 7002/redis.conf
[root@localhostcluster]# vim 7003/redis.conf
[root@localhostcluster]# vim 7004/redis.conf
[root@localhostcluster]# vim 7005/redis.conf
[root@localhostcluster]# vim 7006/redis.conf
[root@localhostcluster]# vim 7007/redis.conf
[root@localhostcluster]# vim 7008/redis.conf

编辑Redis启动脚本

说明:vim编辑start.sh文件.之后shstart.sh执行脚本
在这里插入图片描述

通过ruby创建redis集群

说明:使用ruby管理redis集群.
在这里插入图片描述
在这里插入图片描述
创建redis集群在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

集群划分
在这里插入图片描述
输入yes
在这里插入图片描述
在这里插入图片描述

集群测试

说明:将redis中的主机关闭后,检测高可用是否能够实现.并且当重新启动主机后,能否实现自动挂载.
在这里插入图片描述

集群宕机条件

在这里插入图片描述

Spring中工厂模式

工厂模式作用

核心思想:实例化对象
需求:

  1. 多例对象的创建
  2. 有些对象例如接口/抽象类不能直接实例化接口—代理抽象类----创建子类.
  3. 需要对对象进行二次封装.

静态工厂

说明:静态工厂中要求必须有静态方法.
调用方式:类名.静态方法
Spring配置方式:

<!--配置静态工厂  -->
	<bean id="calendarA" class="com.jt.manage.factory.StaticFactory" 
	factory-method="getInstance"/>

工厂模式编辑:

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

实例化工厂

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

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

工厂定义:

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

Spring工厂

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

工厂定义:

public class SpringFactory implements FactoryBean<Calendar>{

	@Override
	public CalendargetObject() throws Exception {
		returnCalendar.getInstance();
	}

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

	@Override
	public boolean isSingleton() {	
		returnfalse;
	}
}

配置文件定义:

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

工具类测试:

@Test
public void testFactory(){
	//1.实例化Spring容器
	ApplicationContext context = 
			newClassPathXmlApplicationContext("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("calendarB");
	System.out.println(calendarC.getTime());
}

Spring整合集群

入门案例

@Test
	public void testCluster(){
		Set<HostAndPort>nodes = new HashSet<>();
		nodes.add(newHostAndPort("192.168.126.166",7000));
		nodes.add(newHostAndPort("192.168.126.166",7001));
		nodes.add(newHostAndPort("192.168.126.166",7002));
		nodes.add(newHostAndPort("192.168.126.166",7003));
		nodes.add(newHostAndPort("192.168.126.166",7004));
		nodes.add(newHostAndPort("192.168.126.166",7005));
		nodes.add(newHostAndPort("192.168.126.166",7006));
		nodes.add(newHostAndPort("192.168.126.166",7007));
		nodes.add(newHostAndPort("192.168.126.166",7008));
		JedisCluster jedisCluster = new JedisCluster(nodes);
		jedisCluster.set("aa", "小提莫哪里逃");
		System.out.println(jedisCluster.get("aa"));
	}

Spring整合集群

编辑properties配置文件

#最小空闲数
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

修改Spring配置文件

<!--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>

编辑工厂模式

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();
		}
		
		returnnodes;
	}
	
	@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() {
		returnpoolConfig;
	}

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

	public String getRedisNodePrefix() {
		return redisNodePrefix;
	}

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值