四:redis主從讀寫分離,哨兵模式與spring的整合
阿新 • • 發佈:2018-12-22
本篇主要介紹redis實現主從讀寫分離,採用哨兵模式後如何與spring整合在專案中進行開發
主要依賴的jar包,其他專案中實際依賴的jar包很多這裡就不一一列舉了:
- jar包依賴
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId >org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.1.RELEASE</version>
</dependency>
redis配置檔案
#sentinel1的IP和埠
redis.sentinel1.host=192.168.1.232
redis.sentinel1.port=5000
#sentinel2的IP和埠
redis.sentinel2.host=192.168 .1.233
redis.sentinel2.port=5001
#sentinel2的IP和埠
redis.sentinel2.host=192.168.1.233
redis.sentinel2.port=5002
#redis.password=123456,這裡沒有配置密碼
redis.maxIdle=500
redis.maxTotal=5000
redis.maxWaitTime=1000
redis.testOnBorrow=true
redis.minIdle=300
- spring裡的配置檔案
<context:property-placeholder ignore-unresolvable ="true" location="classpath:redis.properties" />
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.maxTotal}" />
<property name="minIdle" value="${redis.minIdle}" />
<property name="maxWaitMillis" value="${redis.maxWaitTime}" />
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
<property name="testOnReturn" value="true" />
<property name="testWhileIdle" value="true" />
</bean>
<bean id="jedisSentinelPool" class="redis.clients.jedis.JedisSentinelPool">
<constructor-arg index="0" value="mymaster" />
<constructor-arg index="1">
<set>
<value>${redis.sentinel1.host}:${redis.sentinel1.port}</value>
<value>${redis.sentinel2.host}:${redis.sentinel2.port}</value>
<value>${redis.sentinel3.host}:${redis.sentinel3.port}</value>
</set>
</constructor-arg>
<constructor-arg index="2" ref="poolConfig" />
<!--
<constructor-arg index="3" value="${redis.password}" />
-->
<bean id="jeidsConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:password="${im.hs.server.redis.sentinel.password}">
<constructor-arg name="sentinelConfig" ref="redisSentinelConfiguration"></constructor-arg>
<constructor-arg name="poolConfig" ref="poolConfig"></constructor-arg>
</bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jeidsConnectionFactory" />
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
<property name="defaultSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
</bean>
<!-- 封裝redis快取操作類 實現自介面:ICacheMangerTarget -->
<bean id="cacheMangerTarget" class="com.xx.xx.db.cache.redis.CacheMangerJedisSentinerAdapter">
<constructor-arg index="0" ref="jedisPool"/>
</bean>
</bean>
- java介面程式碼封裝
- 介面略,之前一篇裡有提到過
實現類CacheMangerJedisSentinerAdapter入下:
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.xxx.framework.db.cache.ICacheMangerTarget;
import com.xxx.framework.utils.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.exceptions.JedisException;
/**
*
* 類名稱: CacheMangerJedisSentinerAdapter <br/>
* 功能描述:redis操作介面封裝-適用於redis主從哨兵叢集模式 <br/>
* 日期:
*
* @author hadoop
* @version
* @since JDK 1.8
*/
public class CacheMangerJedisSentinerAdapter implements ICacheMangerTarget {
protected JedisSentinelPool jedisPool;
// protostuff序列化
//protected RuntimeSchema<Object> schema = RuntimeSchema.createFrom(Object.class);
public CacheMangerJedisSentinerAdapter(JedisSentinelPool jedisPool) {
this.jedisPool = jedisPool;
}
private static Logger logger = LoggerFactory.getLogger(CacheMangerJedisSentinerAdapter.class);
private Jedis getResource() throws JedisException {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
// logger.debug("getResource.", jedis);
} catch (JedisException e) {
logger.warn("getResource.", e);
returnBrokenResource(jedis);
throw e;
}
return jedis;
}
private void returnBrokenResource(Jedis jedis) {
if (jedis != null) {
jedisPool.returnBrokenResource(jedis);
}
}
private void returnResource(Jedis jedis) {
if (jedis != null) {
jedisPool.returnResource(jedis);
}
}
@Override
public String getWithkey(String key) {
String value = null;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(key)) {
value = jedis.get(key);
value = StringUtils.isNotBlank(value) && !"nil".equalsIgnoreCase(value) ? value : null;
}
logger.debug("get {} = {}", key, value);
} catch (Exception e) {
logger.warn("get {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return value;
}
@Override
public String setKeyValue(String key, String value) {
Jedis jedis = null;
try {
jedis = getResource();
value = jedis.set(key, value);
logger.debug("keys {} = {}", key, value);
return value;
} catch (Exception e) {
logger.warn("keys {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return value;
}
@Override
public long delWithkey(String key) {
Jedis jedis = null;
long value = 0;
try {
jedis = getResource();
value = jedis.del(key);
logger.debug("keys {}", "", key);
} catch (Exception e) {
} finally {
returnResource(jedis);
}
return value;
}
@Override
public String getHashWithKey(String hkey, String key) {
String value = null;
Jedis jedis = null;
try {
jedis = getResource();
value = jedis.hget(key, key);
logger.debug("keys {} = {}", key, value);
return value;
} catch (Exception e) {
logger.warn("keys {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return value;
}
@Override
public Map<String, String> getAllWithHashKey(String hkey) {
Jedis jedis = null;
try {
jedis = getResource();
Map<String, String> map = jedis.hgetAll(hkey);
// logger.debug("keys {}", "", key);
return map;
} catch (Exception e) {
} finally {
returnResource(jedis);
}
return null;
}
@Override
public long setHashKeyValue(String hkey, String key, String value) {
Jedis jedis = null;
long back = 0;
try {
jedis = getResource();
back = jedis.hset(hkey, key, value);
} catch (Exception e) {
} finally {
returnResource(jedis);
}
return back;
}
/**
* * @param nxxx NX|XX, NX -- Only set the key if it does not already exist.
* XX -- Only set the key if it already exist.
*
* @param expx
* EX|PX, expire time units: EX = seconds; PX = milliseconds
*/
@Override
public String setExpxKeyCache( String key, String value, long timeout) {
Jedis jedis = null;
String back ="";
try {
jedis = getResource();
jedis.del(key);
back = jedis.set(key, value,"NX","EX",timeout);
// jedis.expireAt(key, unixTime)
} catch (Exception e) {
} finally {
returnResource(jedis);
}
return back;
}
@Override
public String setHashKeyValues(String hkey, Map<String, String> map) {
Jedis jedis = null;
String back = "";
try {
jedis = getResource();
back = jedis.hmset(hkey, map);
} catch (Exception e) {
} finally {
returnResource(jedis);
}
return back;
}
@Override
public long delHashWithKey(String hkey, String key) {
Jedis jedis = null;
long back = 0;
try {
jedis = getResource();
back = jedis.hdel(hkey, key);
} catch (Exception e) {
} finally {
returnResource(jedis);
}
return back;
}
@Override
public String setValueByprotostuff(String key, byte[] bytes) {
Jedis jedis = null;
String back = "";
try {
jedis = getResource();
back = jedis.set(key.getBytes(), bytes);
} catch (Exception e) {
} finally {
returnResource(jedis);
}
return back;
}
@Override
public byte[] getValueByprotostuff(String key) {
Jedis jedis = null;
byte[] back = null;
try {
jedis = getResource();
back = jedis.get(key.getBytes());
} catch (Exception e) {
} finally {
returnResource(jedis);
}
return back;
}
@Override
public long delByprotostuff(String key) {
Jedis jedis = null;
long back = 0;
try {
jedis = getResource();
back = jedis.del(key.getBytes());
} catch (Exception e) {
//拋異常
} finally {
returnResource(jedis);
}
return back;
}
}
這個類是可以根據實際情況繼續擴充套件的,到這裡我們就可以用,CacheMangerJedisSentinerAdapter 在專案中對redis快取進行操作了
junit測試類如下:
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.alibaba.fastjson.JSON;
import com.doraemon.framework.db.cache.ICacheMangerTarget;
import com.psiot.cloud.system.entity.PSiotUserEntity;
import redis.clients.jedis.JedisSentinelPool;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring/spring-context.xml" })
public class RedisTest02 {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Resource
private JedisSentinelPool jedisPool;
@Autowired
private ICacheMangerTarget cacheMangerTarget;
@Test
public void testSet(){
// String value1 = (String) redisTemplate.boundValueOps("key1").get();
// System.out.println(value1);
PSiotUserEntity user = new PSiotUserEntity();
user.setContactName("測試");
// redisTemplate.execute(new RedisCallback<Object>() {
// @Override
// public Object doInRedis(RedisConnection connection)
// throws DataAccessException {
// connection.hSet(redisTemplate.getStringSerializer().serialize("SYS_USER_TAB"),
// redisTemplate.getStringSerializer().serialize("USER_"+100),
// redisTemplate.getStringSerializer().serialize(JSON.toJSONString(user)));
// System.out.println(redisTemplate.getStringSerializer().serialize("USER_"+100));
// return null;
// }
// });
//redisTemplate.getConnectionFactory().getSentinelConnection();
//System.out.println(jedisPool.getResource().get("key1"));
System.out.println(cacheMangerTarget.getWithkey("key1"));
//System.out.println(redisTemplate.getConnectionFactory().getConnection().get("key1".getBytes()));
}
}