redis主从+哨兵
首先我们解释一下主从的区别:主对于数据可读可写。从默认是只读不写的。当从连接上主时,主会将数据同步到从上。
主从结构只能保证数据有备份,但是如果主挂掉了,怎么办,整个服务就不可用了,这显然是个大问题。当然redis也帮我们考虑到了这一点。解决方案就是哨兵。他可以作为一个第三方,监控着我们主节点的状态,当发现主挂掉后,就会从这个主的从服务器中进行选举,推选出一个新主,同时slave也切换成这个新主的slave,如果原来的主重启成功了也不会再次成为主了,而是作为slave挂到新主上。
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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 使用配置文件时使用 --> <!-- <context:property-placeholder location="classpath:redis.properties" /> --> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <!-- 最大连接数, 默认8个 --> <property name="maxTotal" value="2048" /> <!-- 最大空闲连接数, 默认8个 --> <property name="maxIdle" value="10" /> <!-- 最小空闲连接数, 默认0 --> <property name="minIdle" value="0" /> <!-- 每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3 --> <property name="numTestsPerEvictionRun" value="1024" /> <!-- 表示idle object evitor两次扫描之间要sleep的毫秒数 300000毫秒,5分钟 --> <property name="timeBetweenEvictionRunsMillis" value="300000" /> <!-- 逐出连接的最小空闲时间 --> <property name="minEvictableIdleTimeMillis" value="1800000" /> <!-- 对象空闲多久后逐出, 当空闲时间>该值 且 空闲连接>最大空闲数 时直接逐出,不再根据MinEvictableIdleTimeMillis判断 (默认逐出策略) --> <!-- 默认30分钟逐出连接--> <property name="softMinEvictableIdleTimeMillis" value="1800000" /> <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true --> <property name="blockWhenExhausted" value="true" /> <!-- 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1 --> <property name="maxWaitMillis" value="1500" /> <!-- 在获取连接的时候检查有效性, 默认false --> <property name="testOnBorrow" value="false" /> <!-- 在空闲时检查有效性, 默认false --> <property name="testWhileIdle" value="true" /> <!-- 在return给pool时,是否提前进行validate操作; --> <property name="testOnReturn" value="false" /> <!-- 是否启用pool的jmx管理功能, 默认true --> <property name="jmxEnabled" value="true" /> <property name="jmxNamePrefix" value="pool" /> <!-- 是否启用后进先出, 默认true --> <property name="lifo" value="false" /> </bean> <!--redis操作模版,使用该对象可以操作redis --> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" > <property name="connectionFactory" ref="jedisConnectionFactory" /> <!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!! --> <property name="keySerializer" > <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> <property name="valueSerializer" > <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" /> </property> <property name="hashKeySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/> </property> <property name="hashValueSerializer"> <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/> </property> <!--开启事务 --> <!-- <property name="enableTransactionSupport" value="true"></property> --> </bean > <!-- redis集群配置 哨兵模式 --> <bean id="sentinelConfiguration" class="org.springframework.data.redis.connection.RedisSentinelConfiguration"> <property name="master"> <bean class="org.springframework.data.redis.connection.RedisNode"> <!-- 这个值要和Sentinel中指定的master的值一致,不然启动时找不到Sentinel会报错的 --> <property name="name" value="redis-sentinel"></property> <!-- 配置注master节点 主机节点,不需要配置从机节点--> <constructor-arg name="host" value="10.80.64.126"/> <constructor-arg name="port" value="7977"/> </bean> </property> <!-- 记住了,这里是指定Sentinel的IP和端口,不是Master和Slave的 --> <property name="sentinels"> <set> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="10.80.64.126" /> <constructor-arg name="port" value="26377" /> </bean> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="10.80.64.126" /> <constructor-arg name="port" value="26378" /> </bean> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="10.80.64.126" /> <constructor-arg name="port" value="26379" /> </bean> </set> </property> </bean> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <!--配置第几个库--> <property name="database" value="2"/> <constructor-arg name="sentinelConfig" ref="sentinelConfiguration" /> <constructor-arg name="poolConfig" ref="jedisPoolConfig" /> </bean> <bean id="redisService" class="com.kayak.kpl.frameservice.cache.jedis.RedisServiceImp"> </bean> </beans>