1. 程式人生 > >四:redis主從讀寫分離,哨兵模式與spring的整合

四:redis主從讀寫分離,哨兵模式與spring的整合

本篇主要介紹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()));
    }


}