对Redis的深入理解与解析

最近换了项目中,突然碰到redis了,对他的理解很有限,这里做个分享。

1.Redis的连接池(JedisPool)

说到连接池,我的第一反应是这可能跟数据源的C3P0类似。结果一查,恩,差不多。

Redis是一种C/S的模式,但是频繁的链接会导致花费在底层链接上的时间大大增加(因为Redis是基于内存的,读取效率高,假设一次数据交互总共用时30ms,超高性能的Redis数据库处理数据所花的时间可能不到1ms,也即是说前期的连接占用了29ms)。显然很不合理,怎么办呢。于是JedisPool就开始出现了。

连接池可以使在客户端建立多个连接并且不释放,想链接即可通过某算法建立连接,用完了,归还即可。这就免去了数据库链接所需要的时间。

但是如果超过连接池的上限以后,会怎么样呢:采用IO的多路复用来解决。


2.连接池的配置

package com.jedis;

import java.util.concurrent.locks.ReentrantLock;  
import org.apache.commons.lang.StringUtils;  
import org.apache.log4j.Logger;
import org.junit.Test;

import redis.clients.jedis.Jedis;  
import redis.clients.jedis.JedisPool;  
import redis.clients.jedis.JedisPoolConfig;  
  
/**
 * Reids的工具类  
 * @author EdwardShen
 *
 * 2018年4月30日
 */
public class JedisUtil {  
  
    protected static ReentrantLock lockPool = new ReentrantLock();  
    protected static ReentrantLock lockJedis = new ReentrantLock();  
  
    protected static Logger logger = Logger.getLogger(JedisUtil.class);  
  
    //Redis服务器IP  
    private static String ADDR_ARRAY = "127.0.0.1,127.0.0.2";  
  
    //Redis的端口号  
    private static int PORT = 6379;  
  
    //访问密码  
    private static String AUTH = "http://blog.csdn.net/sx1119183530";  
    //可用连接实例的最大数目,默认值为8;  
    //如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。  
    private static int MAX_ACTIVE = 8;  
  
    //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。  
    private static int MAX_IDLE = 8;  
  
    //等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;  
    private static int MAX_WAIT = 3000;  
  
    //超时时间  
    private static int TIMEOUT = 10000;  
  
    //在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;  
    private static boolean TEST_ON_BORROW = false;  
  
    private static JedisPool jedisPool = null;  
  
    /** 
     * redis过期时间,以秒为单位 
     */  
    public final static int EXRP_HOUR = 60 * 60;            //一小时  
    public final static int EXRP_DAY = 60 * 60 * 24;        //一天  
    public final static int EXRP_MONTH = 60 * 60 * 24 * 30; //一个月  
  
    /** 
     * 初始化Redis连接池 
     */  
    @Test
    private static void initialPool() {  
        try {  
            JedisPoolConfig config = new JedisPoolConfig();  
            config.setMaxTotal(MAX_ACTIVE);  
            config.setMaxIdle(MAX_IDLE);  
            config.setMaxWaitMillis(MAX_WAIT);  
            config.setTestOnBorrow(TEST_ON_BORROW);  
            System.out.println(ADDR_ARRAY.split(",")[0]+":"+ADDR_ARRAY.split(",")[1]);
            jedisPool = new JedisPool(config, ADDR_ARRAY.split(",")[0], PORT, TIMEOUT, AUTH);  
        } catch (Exception e) {  
            logger.error("First create JedisPool error : " + e);  
            try {  
                //如果第一个IP异常,则访问第二个IP  
                JedisPoolConfig config = new JedisPoolConfig();  
                config.setMaxTotal(MAX_ACTIVE);  
                config.setMaxIdle(MAX_IDLE);  
                config.setMaxWaitMillis(MAX_WAIT);  
                config.setTestOnBorrow(TEST_ON_BORROW);  
                jedisPool = new JedisPool(config, ADDR_ARRAY.split(",")[1], PORT, TIMEOUT, AUTH);  
            } catch (Exception e2) {  
                logger.error("Second create JedisPool error : " + e2);  
            }  
        }  
    }  
  
    /** 
     * 在多线程环境同步初始化 
     */  
    private static void poolInit() {  
        lockPool.lock();  
        try {  
            if (jedisPool == null) {  
                initialPool();  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            lockPool.unlock();  
        }  
    }  
  
    public static Jedis getJedis() {  
        lockJedis.lock();  
        if (jedisPool == null) {  
            poolInit();  
        }  
        Jedis jedis = null;  
        try {  
            if (jedisPool != null) {  
                jedis = jedisPool.getResource();  
            }  
        } catch (Exception e) {  
            logger.error("Get jedis error : " + e);  
        } finally {  
            returnResource(jedis);  
            lockJedis.unlock();  
        }  
        return jedis;  
    }  
  
    /** 
     * 释放jedis资源 
     * 
     * @param jedis 
     */  
    public static void returnResource(final Jedis jedis) {  
        if (jedis != null && jedisPool != null) {  
            jedisPool.returnResource(jedis);  
        }  
    }  
  
    /** 
     * 设置 String 
     * 
     * @param key 
     * @param value 
     */  
    public synchronized static void setString(String key, String value) {  
        try {  
            value = StringUtils.isEmpty(value) ? "" : value;  
            getJedis().set(key, value);  
        } catch (Exception e) {  
            logger.error("Set key error : " + e);  
        }  
    }  
  
    /** 
     * 设置 过期时间 
     * 
     * @param key 
     * @param seconds 以秒为单位 
     * @param value 
     */  
    public synchronized static void setString(String key, int seconds, String value) {  
        try {  
            value = StringUtils.isEmpty(value) ? "" : value;  
            getJedis().setex(key, seconds, value);  
        } catch (Exception e) {  
            logger.error("Set keyex error : " + e);  
        }  
    }  
  
    /** 
     * 获取String值 
     * 
     * @param key 
     * @return value 
     */  
    public synchronized static String getString(String key) {  
        if (getJedis() == null || !getJedis().exists(key)) {  
            return null;  
        }  
        return getJedis().get(key);  
    }  
}  

测试类:

package com.jedis;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.junit.Test;
/**
 * 测试类
 * @author EdwardShen
 *
 * 2018年4月30日
 */
public class TestJedis extends Thread {
	int i = 0;

	public  TestJedis(int i) {
		this.i = i;
	}

	public void run() {
		Date date = new Date();
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String time = format.format(date);
		JedisUtil.setString("foo", time);
		String foo = JedisUtil.getString("foo");
		System.out.println("【输出>>>>】foo:" + foo + " 第:" + i + "个线程" + "当前时间:" + format.format(new Date()));
	}
	
	
	@Test
	public void test()
	{
		System.out.println("kaishil  !");
		 for (int i = 0; i < 10000; i++) {            
			 TestJedis t = new TestJedis(i);  
	            t.start();  
	        } 
	}
}

猜你喜欢

转载自blog.csdn.net/sx1119183530/article/details/80151472