`
TableMiao
  • 浏览: 75403 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Redis(七) HA集群(基于Sentinel)集成Spring、master写slave读

阅读更多
Redis() HA集群(基于Sentinel)集成Springmasterslave

说明:适合测试且了解sentinel模式,线上项目慎用。

 

一、配置情况说明:

    Master: 端口 6381

    Slave 端口 63796380

    Sentinel 端口 26379

 

二、集成spring-data-redis

   2.1配置文件:

 

<?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.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd">

	<context:component-scan base-package="com.tablemiao.redis.dao"></context:component-scan>
	<context:property-placeholder location="classpath:applicationContext.properties" />
	
	<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
		<property name="maxIdle" value="${redis.maxIdle}" />
		<property name="maxTotal" value="${redis.maxActive}" />
		<property name="maxWaitMillis" value="${redis.maxWait}" />
		<property name="testOnBorrow" value="${redis.testOnBorrow}" />		
	</bean>
		
  <bean id="redisSentinelConfiguration"
		class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
		<property name="master">
			 <bean class="org.springframework.data.redis.connection.RedisNode">
				<property name="name" value="mymaster" />
			</bean> 
		</property>
		<property name="sentinels">
			<set>
				 <bean class="org.springframework.data.redis.connection.RedisNode">
					<constructor-arg name="host" value="192.168.1.118"></constructor-arg>
					<constructor-arg name="port" value="26379"></constructor-arg>
				</bean> 
			</set>		
		</property>
	</bean>

	<bean id="jedisConnectionFactory"
		class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">	
		<property name="poolConfig" ref="poolConfig"/> 
		 <constructor-arg ref="redisSentinelConfiguration"></constructor-arg> 
	 	<property name="usePool" value="false"/>
	    <property name="hostName" value="${redis.hostName}" />
		<property name="port" value="${redis.port}" /> 
	</bean>

	<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
		<property name="connectionFactory" ref="jedisConnectionFactory" />
	</bean>


</beans>

 

网上看了很多配法,解释的都不完整,有些根本不能运行,共同学习。

poolConfig 连接池配置  可以忽略,因为<property name="usePool" value="false"/>

配了这句,如果启用,读取配置就会出错,始终没有解决,可以直接删除掉。

redisSentinelConfiguration 哨兵的配置,hostportsentinel的监听端口和host(有人说是redis服务进程的端口和host,不知道怎么玩的,说的不清不楚,一直出错,查看过这个类,也不该这么配),本人是一个sentinel.conf文件中监听三个redis进程(就是Redis()中的配法),所以只有一个,多个可以在set中添加。

jedisConnectionFactory 配置连接工厂、默认端口为master的端口,以方便后续测试。

 

2.2加载上诉配置文件 直接拿到注入的redisTemplate  进行数据操作,读写无异常。

 

2.3断开master进程、主从切换,后台切换完成,重新加入开始master,此时master变为slave详见Redis()

2.4 再次通过redisTemplate 进行样例操作,发现,此时读取可以,但是写数据不行。原因为,代码中的连接地址依旧为开始master连接的地址和端口。

 

2.5 问人找文档无果。仔细查看redis的连接模式,想到如下法子,测试可行,性能没测试过。             

 

  2.5.1通过redisTemplate.getConnectionFactory().getSentinelConnection().masters();可以获取当前的master连接地址和端口。

  2.5.2获取配置文件中当前连接地址和端口比对,如果一致,说明当前连接为master,可以进行读写,直接利用注入的redisTemplate进行操作即可,如果不一致,利用当前master的地址和端口在代码里重新建立连接,进行写操作。


2.6比对的逻辑代码(整体代码详见cc-redis-three

 

//获取当前的master
  	public String getMaster() {
		Iterator<RedisServer> masters = redisTemplate.getConnectionFactory()
				.getSentinelConnection().masters().iterator();
		while(masters.hasNext()){
			return  masters.next().asString();
		}
		return "get_master_error";	
	}
 
//连接的逻辑比对。 如果一致,就返回redisTemplate,否则返回jedis连接
public Object getMasterRedisTemplate(){
		String proptiesHostAndPort = hostName+":"+port;
		String mHost = getMaster().split(":")[0];
		int mPort = Integer.parseInt(getMaster().split(":")[1]);
		//如果当前连接为master,直接返回,用作写操作
		if(proptiesHostAndPort.equals(getMaster())){
			return redisTemplate;
		}else{
			//获取master 的连接方式  再次建立连接,进行写操作
			
			/*
			    本想通过这种方式,返回一个RedisTemplate  结果发现获取不到连接,希望大神弄好了,一起学习
			JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
			jedisConnectionFactory.setHostName(hostName);
			jedisConnectionFactory.setPort(port);
			RedisTemplate<String, Object> re= new RedisTemplate<String, Object>();
			re.setConnectionFactory(jedisConnectionFactory);
			//这种也不行
			JedisConnection jedis = jedisConnectionFactory.getConnection();
			*/
			
			//直接jedis 操作
			JedisPoolConfig jpl = new JedisPoolConfig();
			jpl.setMaxTotal(50000);
			jpl.setMaxIdle(5);
			jpl.setMaxWaitMillis(1000*60*5);
			jpl.setTestOnBorrow(true);
			JedisPool jp = new JedisPool(jpl,mHost,mPort);

			return jp.getResource();
		}
	}

 

2.7 获取到2.6中的连接,分别利用其进行操作,读,写代码

  写,如果返回是的RedisTemplate,说明是当前是master的连接,直接写数据即可,否则

创建一个masterjedis连接 进行写数据

 

public boolean insertString(String key, String value) {
		try {
			//先拿连接判断,是否当前连接为master,底下insert相同处理即可
			if(getMasterRedisTemplate() instanceof RedisTemplate){
				redisTemplate.opsForValue().set(key, value);
			}else{
				Jedis jedis = (Jedis)getMasterRedisTemplate();
				jedis.set(key, value);
			}
			return true;
		} catch (Exception e) {
			logger.info("新增错误:{}", e.getMessage());
			return false;
		}

	}
读,一样的判断即可
public Object select(String key){
		try {
			if(getMasterRedisTemplate() instanceof RedisTemplate){
				 DataType type = redisTemplate.type(key);
				 if(DataType.NONE == type){
					 logger.info("key不存在");
					 return null;
				 }else if(DataType.STRING == type){
					 return super.redisTemplate.opsForValue().get(key);
				 }else if(DataType.LIST == type){
					 return super.redisTemplate.opsForList().range(key, 0, -1);
				 }else if(DataType.HASH == type){
					 return super.redisTemplate.opsForHash().entries(key);
				 }else
					 return null;
			}else{
				Jedis jedis = (Jedis)getMasterRedisTemplate();
				if("string".equals(jedis.type(key))){
					return jedis.get(key);
				}else{
					 return null;
				}	
			}
		} catch (Exception e) {
			logger.info("查询错误:{}", e.getMessage());
			return null;
		}
	}

若是想要达到master slave读,在读的时候判断即可,如果是当前的master连接,那创建一个slavejedis进行读取。

 

三、测试

 

@org.junit.Test
	public void test() throws Exception{
		
		logger.info("=========start===========");
		logger.info("当前master列表:{}",customDao.getMaster());
		//logger.info("当前连接的hostName:{}",customDao.isMaster());
		customDao.insertString("sentinel:key:1", "sentinel_value_集群值测试1");
		logger.info("读取集群配置的值:{}",customDao.select("sentinel:key:1"));
		logger.info("=========end===========");
	}

结果如下,当前连接是的slave,也能读写

 

 

 

 

 

 

 

  • 大小: 48.6 KB
分享到:
评论

相关推荐

    springcloud部署redis集群

    SpringCloud通过集成Spring Data Redis模块,使得在微服务架构中与Redis进行交互变得非常便捷。以下将详细介绍如何在SpringCloud中配置和使用Redis集群。 首先,你需要了解Redis集群的基本概念。Redis集群通过数据...

    spring + redis + sentinel 配置

    在IT行业中,Spring框架是Java应用...总结来说,这个配置文件组合提供了Spring应用与Redis Sentinel集成的基础,实现了对Redis的高可用访问。这种配置模式在大型分布式系统中尤为常见,能够提高系统的稳定性和可靠性。

    基于phpredis封装的redis-sentinel客户端redis-sentinel.zip

    redis-sentinel 就像他的名字一样,他是一个哨兵,监控 master 状态,如果超过规定时间没有响应,则自动进行主从切换,期间会有一段时间(决定于具体的配置参数)redis集群无法提供服务 。原理类似 mysql 的 MHA。...

    spring集成redis单节点、集群、哨兵配置

    本文将深入探讨如何在Spring项目中集成Redis的单节点、集群和哨兵模式。 首先,让我们来看**单节点配置**。在Spring中集成Redis单节点,我们需要在Spring的配置文件中定义RedisConnectionFactory。这通常通过...

    Spring集成redis集群

    **Spring集成Redis集群详解** 在现代的Web应用程序开发中,数据缓存扮演着至关重要的角色,而Redis作为一款高性能的键值数据存储系统,被广泛应用于缓存、消息队列等多个场景。当业务规模扩大,单机Redis可能无法...

    springboot整合redis集群零配置

    在Spring Boot 2.1及以上版本中,我们可以利用`spring.redis.cluster.nodes`属性来实现零配置连接到Redis集群,只需将所有集群节点的IP和端口以逗号分隔的形式列出即可,如: ```properties spring.redis.cluster....

    Redis 2.8.9 sentinel集群实验

    在本实验中,我们将探讨如何设置和操作一个Redis 2.8.9版本的Sentinel集群,该集群包括环境的搭建、实验步骤以及相关截图的解析。 首先,我们需要了解Redis Sentinel的基本概念。Sentinel是一个分布式系统,它可以...

    redis集群:redis-sentinel(哨兵机制)集群

    Redis Sentinel(哨兵)是Redis集群中的一个重要组件,它提供了高可用性解决方案,确保当主节点发生故障时,能够自动将从节点提升为主节点,从而维持服务的连续性。哨兵系统通过监控、通知和自动故障转移来实现这一...

    spring集成redis,集成redis集群

    当我们谈论“Spring集成Redis集群”时,这意味着我们要在Spring应用中配置和使用多个Redis实例,形成一个高可用、高并发的数据库解决方案。 首先,让我们深入理解Spring对Redis支持的基本概念。Spring Data Redis...

    spring集成redis集群需要的jar.zip

    Spring + redis集群的集成 spring-data-redis-1.8.1.RELEASE.jar jedis-2.9.0.jar spring-data-commons-1.8.1.RELEASE.jar commons-pool2-2.4.2.jar

    spring + redis集群

    本文将深入探讨如何使用Spring Data Redis构建一个Redis集群,以及如何通过Spring框架来操作Redis集群,存储对象集合,并提供一个基于Maven的可运行项目示例。 首先,Spring Data Redis是Spring框架的一个模块,它...

    SpringMVC整合Redis集群

    项目由maven构建,使用springMVC整合了Redis的集群,发布到tomcat中,访问http://localhost:8080/SpringRedisCluster/redis/hello.do测试即可,前提是配好了redis的集群。

    第四十六章:Redis sentinel哨兵集群1

    Redis Sentinel是一种高可用性解决方案,它是Redis官方提供的一种分布式系统,专门用于监控Redis集群中的Master主服务器状态。在Master出现故障时,Sentinel能够自动进行故障转移,将健康的Slave提升为新的Master,...

    redissentinel基于phpredis扩展的redissentinel客户端

    标题中的“redissentinel基于phpredis扩展的redissentinel客户端”指的是一个使用PHP语言开发的Redis Sentinel客户端,它依赖于phpredis扩展来实现与Redis Sentinel服务的交互。Redis Sentinel是Redis集群的一个重要...

    SpringBoot集成Redis集群

    SpringBoot集成Redis集群 在本文档中,我们将指导您如何在SpringBoot 2.X中集成Redis集群。下面是相关的知识点: 集成Redis集群的必要性 在实际应用中,使用Redis集群可以提高系统的可扩展性和可靠性。Redis集群...

    Redis-master-slave-sentinel.rar

    在企业级应用中,为了实现数据的高可用性和容错性,通常会采用主从复制(master-slave replication)和哨兵(Sentinel)系统来搭建分布式环境。 **一、Redis主从复制** 1. **主从复制的概念** 主从复制是Redis的...

    redis-sentinel集群及双机热备

    Redis Sentinel集群和双机热备是 Redis 高可用性(High Availability, HA)的重要组成部分,它们确保了在主节点故障时能够快速切换到备份节点,从而维持服务的连续性。以下将详细介绍这两个概念以及相关配置和操作。...

    redis集群以及Spring-data-redis操作集群

    总结来说,Redis集群是提升系统性能和可用性的关键,而Spring-data-redis则是简化了在Java应用中使用Redis(包括集群)的过程,提供了一套完整的操作API。通过理解并熟练掌握这两个方面,可以有效地利用Redis来解决...

    SpringCloud整合Redis

    SpringCloud整合Redis缓存;版本:SpringCloud :Dalston.SR4;SpringBoot:1.5.14.RELEASE;Redis:3.2.0;Maven :3.5.3.代码下载下来即可用

    Redis集群管理工具Redis::Sentinel.zip

    因为Redis实例在各个大公司的应用,每个公司都需要一个Redis集群的管理工具,被迫都自己写管理工具来管理Redis集群,antirez考虑到社区的急迫需要(详情),花了几个星期写出了Redis-sentinel。 Redis-sentinel的三大...

Global site tag (gtag.js) - Google Analytics