天天看點

Redis在java項目中的緩存應用

前言

在目前大資料時代,資訊量、資料量日益膨脹;一些存儲系統的資料庫也不斷優化,去适應這個大資料的需求;當我們的用戶端某個系統發送請求頻繁讀取大量資料的時候,單單是:用戶端–>請求/響應–>資料庫;這種模式是遠遠不能滿足使用者需求的;因為這種模式頻繁請求涉及很多的IO流通路,成本量太高;就從系統處理器上面來說,當使用者發送指令給PC系統時,其處理器執行該指令很快很快(在記憶體中);接着從IO流通路資料庫開始就變得很慢很慢(遠遠跟不上處理器的執行速度了,導緻處理效率非常低);如果我們将使用者需要的資料提前緩沖到計算機記憶體中(相當于處理器的處理響應結果可以直接在記憶體中拿到,不需要再操作多餘的IO流);讀取資料響應就非常快了,就可以大幅度提高效率,節省時間。但是Redis的記憶體管理成本也是比較高的,如果Redis配置不當,占用的過多的記憶體是會帶來很大的性能影響的;是以需要合理的配置好Redis的參數,控制和節約記憶體。

常用的配置優化:

1.将redis.conf檔案中vm-enabled為no(關閉虛拟記憶體功能);

2.設定好redis.conf中的maxmemory選項,該選項是告訴Redis當使用了多少實體記憶體後就開始拒絕後續的寫入請求,該參數能很好的保護好你的Redis不會因為使用了過多的實體記憶體而導緻swap,最終嚴重影響性能甚至崩潰。

Redis在java項目中的緩存應用

一、Redis在java項目中的應用

1.前提條件(我自己涉及需要到的jar包,可以不用)

1.1 導入redis包

Redis在java項目中的緩存應用

可以自行百度下載下傳,也可以點此連結下載下傳redies包

1.2 導入json包(也可以不使用json,本人在項目中使用到了就導進來)

Redis在java項目中的緩存應用

自行百度下載下傳或點這裡json包

1.3 需要已經安裝部署好Redis服務端,可以參考:配置redis

2.java代碼實作

2.0 RedisUtil.java類和main方法

public class RedisUtil{
	//擷取redis連接配接方法
	private static JedisCluster redis=null;
	private static JedisCluster getRedisConnection(){
		if(redis==null){
			createPool();
		}
		return redis;
	}
	/**
	 * @param args
	 * 測試main
	 */
	public static void main(String[] args) {
		JedisCluster redis=RedisUtil.getRedisConnection();//調用擷取redis連接配接的方法
		RedisUtil.setValue("key_1", "value_1");//設定key_1=value_1
		RedisUtil.setValue("key_1_1", "value_1_1");//設定key_1=value_1
		System.out.println(RedisUtil.getValue("key_1","key_1_1"));//擷取子key的值
		System.out.println(RedisUtil.getAllValue("key_1"));	//擷取key的所有值
		JSONObject jsonobj=new JSONObject();//建立json對象
		jsonobj.put("ObjI_Button", "ADD,QUERY,UPDATE");
		jsonobj.put("Objl_Factory", "WH");
		jsonobj.put("Objl_Repair_depart", "1,2");
		JSONArray jsonArr=new JSONArray();//建立json數組
		jsonArr.add(jsonobj);
		RedisUtil.setValue("key_2", "key_2_1",jsonArr.toString());//存key值
		RedisUtil.delKey("key_1", "key_1_1");//删除子key
	}
	}
           

2.1建立redis連結

(1)IOUtil.java類:操作IO工具類,主要用于讀取Redis配置檔案的參數

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;
public class IOUtil {
/*
 * IO流利用Properties類(持久化的屬性集)讀取檔案的key=value值
 *1.建立Properties類對象
 *2.加載屬性檔案 
 *@param--key:需要取value對應的key值
 *@param--path:檔案路徑
 *@return key的屬性值
 * */
public static String getPropertyByName(String key,String path){
	Properties properties=new Properties();//建立properties類對象
	InputStream input=null;//輸入流
	try {
	    input=new FileInputStream(path);//輸入流讀取檔案
		properties.load(new InputStreamReader(input, "utf-8"));//加載屬性檔案
		return properties.getProperty(key);//擷取key的屬性值
	}catch (IOException e) {
		e.printStackTrace();
		return e.getMessage();
	}finally{
		if(input!=null){
			try {
				input.close();//關閉輸入流
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}	
}
}
           

(2)createPool.java類:建立redis連接配接池,主要用于讀取配置檔案并擷取host位址和端口,配置redis用戶端的服務參數

/*
	 * 建立redis連接配接
	 * 1.讀取配置檔案
	 * 2.擷取HOST位址和端口port
	 * 3.redis用戶端服務配置
	 * @param 全局變量:JedisCluster redis
	 * */
	private static void createPool(){
		//擷取本地檔案key對應的value值,檔案名:Config/test.properties,格式:key=value;
		String maxToal=IOUtil.getPropertyByName("pool.size","Config/test.properties");
		//格式:redis.cluster.address=192.168.0.1:10001;192.168.0.2:10002;192.168.0.3:10003;可以設定多個叢集,ip+port
		String addressList=IOUtil.getPropertyByName("redis.cluster.address","Config/test.properties");
		//儲存addressList裡面的HOST位址和端口port
		Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
		for(String address:addressList.split(";")){
			jedisClusterNodes.add(
					new HostAndPort( address.split(":")[0] , Integer.parseInt(address.split(":")[1]) ) );
		}
		//redis用戶端服務配置
		JedisPoolConfig config = new JedisPoolConfig();
		//設定擷取連接配接時最大的等待時間,逾時就抛異常;小于0:阻塞不确定的時間,預設-1
		config.setMaxWaitMillis(20*1000);
		//設定最大連接配接數,預設是8個
		config.setMaxTotal(Integer.parseInt(maxToal));
		//擷取redis連接配接,參數:address:port、config
		redis = new JedisCluster(jedisClusterNodes,config);//redis為全局變量,redis不為null就已經是建立了,不必重複建立
	}
           

2.2 操作redis資料庫常用一般方法

//1.擷取key/subkey對應的value值
	public static String getValue(String key,String subKey){
		JedisCluster jd=RedisUtil.getRedisConnection();
		String reStr= jd.hget(key, subKey);
		return reStr;
	}
	public static String getValue(String key){
		JedisCluster jd=RedisUtil.getRedisConnection();
		String reStr=jd.get(key);
		return reStr;
	}
	//2.擷取key/subkey調用的次數
	public static Long getIncr(String key){
		JedisCluster jd=RedisUtil.getRedisConnection();
		return jd.incr(key);
	}
	public static Long getIncr(String key,String subKey){
		JedisCluster jd=RedisUtil.getRedisConnection();
		return jd.hincrBy(key, subKey,1);
	}
	//3.擷取key對應value值調用的次數
	public static Long getIncr(String key,String subKey,long value){
		JedisCluster jd=RedisUtil.getRedisConnection();
		return jd.hincrBy(key, subKey,value);
	}
	//4.設定儲存key/subkey-value值
	public static void setValue(String key,String value){
		JedisCluster jd=RedisUtil.getRedisConnection();
		jd.set(key, value);
	}
	public static void setValue(String key,String subKey,String value){
		JedisCluster jd=RedisUtil.getRedisConnection();
		jd.hset(key,subKey, value);
	}
	//5.設定key的生存時間,過時就自動删除
	public static void expire(String key, int seconds){
		JedisCluster jd=RedisUtil.getRedisConnection();
		jd.expire(key, seconds);
	}
	//6.直接删除key/subkey
	public static void delKey(String key){
		JedisCluster jd=RedisUtil.getRedisConnection();
		jd.del(key);
	}
	public static void delKey(String key,String subKey){
		JedisCluster jd=RedisUtil.getRedisConnection();
		jd.hdel(key, subKey);
	}
	//7.擷取key所對應的key-value鍵值對,存map
	public static Map<String,String> getAllValue(String key){
		JedisCluster jd=RedisUtil.getRedisConnection();
		Map<String,String> reStr=jd.hgetAll(key);
		return reStr;
	}
	//8.判斷key/subkey是否存在
	public static boolean keyIsExists(String key){
		JedisCluster jd=RedisUtil.getRedisConnection();
		return jd.exists(key);
	}
	public static boolean keyIsExists(String key,String subKey){
		JedisCluster jd=RedisUtil.getRedisConnection();
		return jd.hexists(key, subKey);
	}