整理了之前學習 redis 的筆記,強烈建議看最后總結。
在大型系統數據讀請求中,基本上90%都可以通過分布式緩存集群來抗下來,而 Redis 又是分布式緩存集群的主要踐行者,因此了解 Redis 是必不可少的技能。
在 javaWeb 中實現對 Redis 的操作,主要有兩種方式:Jedis、RedisTemplate。
1、什么是 Jedis?什么是 RedisTemplate?
Jedis 是 Redis 官方推薦的面向 Java 的操作Redis 的客戶端,通過jedis我們可以實現連接Redis,以及操作 Redis 。
RedisTemplate 是 SpringDataRedis 中對JedisAp i的高度封裝。SpringDataRedis 相對於 Jedis 來說可以方便地更換 Redis 的 Java客戶端,比 Jedis 多了自動管理連接池的特性,方便與其他 Spring 框架進行搭配使用如:SpringCache
2、Jedis 的使用(了解)
就像在學習 springmvc 框架之前學習 servlet 一樣,了解 jedis 的使用,看一下單機中 Jedis 的使用,首先要導入相關架包,
jedis.jar
import redis.clients.jedis.Jedis;
public class RedisJava {
public static void main(String[] args) {
//連接本地的 Redis 服務
Jedis jedis = new Jedis("localhost");
System.out.println("連接成功");
//查看服務是否運行
System.out.println("服務正在運行: "+jedis.ping());
}
}
編譯以上 Java 程序,確保驅動包的路徑是正確的,打印如下:
連接成功
服務正在運行: PONG
redis 中最主要的就是讀寫數據。Redis 操作5大基本類型:String、List、Hash、Set、SortedSe。t
菜鳥教程中關於 Redis 操作 String 、List 等:http://www.runoob.com/redis/redis-java.html
3、連接池 JedisPool,為什么要用 JedisPool
首先我們如果每次使用緩存都生成一個 Jedis 對象的話,這樣意味着會建立很多 socket 連接,造成系統資源被不可控調用,甚至會導致奇怪錯誤的發生。
如果使用單例模式,在線程安全模式下適應不了高並發的需求,非線程安全模式又可能會出現與時間相關的錯誤。
因此,為了避免這些問題,引入了池的概念 JedisPool。JedissPool 是一個線程安全的網絡連接池,我們可以通過 JedisPool 創建和管理 Jedis 實例,這樣可以有效的解決以上問題以實現系統的高性能。
我們可以理解成項目中的數據庫連接池,例如:阿里巴巴的 druid~
直連和使用連接池的對比
優點 | 缺點 | |
---|---|---|
直連 | 簡單方便適用於少量長期連接的場景 | 存在每次新建/關閉TCP開銷,資源無法控制,存在連接泄露的可能,Jedis對象線程不安全 |
連接池 | Jedis預先生成,降低開銷,連接池的形式保護和控制資源的使用 | 相對於直連,使用相對麻煩,尤其在資源管理上需要很多參數來保證,一旦規划不合理也會出現問題。 |
4、如何創建 JedisPool 實例和 Jedis 實例對象

private static JedisPool pool = null;
if( pool == null ){
JedisPoolConfig config = new JedisPoolConfig();
控制一個pool可分配多少個jedis實例,通過pool.getResource()來獲取;
如果賦值為-1,則表示不限制;如果pool已經分配了maxActive個jedis實例,則此時pool的狀態為exhausted(耗盡)。
config.setMaxTotal(50);
控制一個pool最多有多少個狀態為idle(空閑的)的jedis實例。
config.setMaxIdle(5);
表示當borrow(引入)一個jedis實例時,最大的等待時間,如果超過等待時間,則直接拋出JedisConnectionException;單位毫秒
小於零:阻塞不確定的時間, 默認-1
config.setMaxWaitMillis(1000*100);
在borrow(引入)一個jedis實例時,是否提前進行validate操作;如果為true,則得到的jedis實例均是可用的;
config.setTestOnBorrow(true);
return 一個jedis實例給pool時,是否檢查連接可用性(ping())
config.setTestOnReturn(true);
connectionTimeout 連接超時(默認2000ms)
soTimeout 響應超時(默認2000ms)
}
獲取實例
public static Jedis getJedis() {
return pool.getResource();
}
釋放 redis
public static void returnResource(Jedis jedis) {
if(jedis != null) {
jedis.close();
}
}
5、JedisPool 屬性配置(JedisPoolConfig)
JedisPool的配置參數大部分是由JedisPoolConfig的對應項來賦值的。

6、再回頭看 RedisTemplate
6.1、關於 RedisTemplate
通過最開始的簡單概述,我們了解到 SpringDataRedis(RedisTemplate) 相對於 Jedis 來說可以方便地更換 Redis 的 Java 客戶端,比 Jedis 多了自動管理連接池的特性,方便與其他 Spring 框架進行搭配使用如:SpringCache;
或者可以理解成,redisTemplate 是對 Jedis 的對 redis 操作的擴展,有更多的操作, 封裝使操作更便捷。
6.2、如何使用 RedisTemplate
首先說一下,序列化,因為 redis 存儲的數據必須要經過序列化處理。
那么你要知道 SDK 默認采用的序列化策略有兩種,一種是 String 的序列化策略,一種是 JDK 的序列化策略。
在說如何使用之前再引申出來個 StringRedisTemplate….
6.3、StringRedisTemplate 和 RedisTemplate 區別
通過上邊我們清楚了 RedisTemplate ,但是這個 StringRedisTemplate 又是個啥呢?
其實作用是一樣的? what???
其實他們兩者之間的區別主要在於他們使用的序列化類。
RedisTemplate 使用的是 JdkSerializationRedisSerializer (JDK 序列化)
StringRedisTemplate 使用的是 StringRedisSerializer(String 序列化)
6.4、Redis 序列化:(String 序列化,JDK 序列化)
RedisTemplate :
RedisTemplate 使用的序列類在在操作數據的時候,比如說存入數據會將數據先序列化成字節數組,然后在存入 Redis 數據庫,這個時候打開 Redis 查看的時候,你會看到你的數據不是以可讀的形式展現的,而是以字節數組顯示,類似下面:

當然從Redis獲取數據的時候也會默認將數據當做字節數組轉化,這樣就會導致一個問題,當需要獲取的數據不是以字節數組存在 redis 當中而是正常的可讀的字符串的時候,比如說下面這種形式的數據:

RedisTemplate就無法獲取導數據,這個時候獲取到的值就是NULL。這個時候StringRedisTempate就派上了用場。
StringRedisTemplate
當Redis當中的數據值是以可讀的形式顯示出來的時候,只能使用StringRedisTemplate才能獲取到里面的數據。
所以當你使用RedisTemplate獲取不到數據的時候請檢查一下是不是Redis里面的數據是可讀形式而非字節數組。
序列化總結
當你的 redis 數據庫里面本來存的是字符串數據或者你要存取的數據就是字符串類型數據的時候,那么你就使用 StringRedisTemplate 即可,但是如果你的數據是復雜的對象類型,而取出的時候又不想做任何的數據轉換,直接從 Redis 里面取出一個對象,那么使用RedisTemplate 是更好的選擇。
7、本文總結
不太喜歡寫長篇文章,總感覺太長的篇幅自己都不喜歡看下去,所以就此總結一下,實戰就放下一篇吧。
Jedis 是 Redis 官方推薦的面向 Java 操作 Redis 的客戶端,但在項目中使用 Jedis jedis = new Jedis("xxx"); 的操作有失大雅,就好比還在用 servlet…,同時用 JedisPool 來獲得連接進行 get、set、del 等操作也相對簡單,但是需要注意的是,存入 Redis 是需要序列化的,至於選擇哪種序列化需要自己抉擇;
再說到 RedisTemplate,Spring 針對 Redis 的使用,封裝了一個比較強大的 Template ,在沒有這個 Template 之前,是使用 Jedis 直連進行相應的交互操作,值得一提的是,做這個封裝的是 SpringData,簡單了解一下 SpringData:
Spring Data: Spring 的一個子項目。用於簡化數據庫訪問,支持NoSQL和關系數據庫存儲。其主要目標是使數據庫的訪問變得方便快捷。
Spring Data 項目所支持 NoSQL 存儲:
- - MongoDB(文檔數據庫)
- - Neo4j (圖形數據庫)
- - Redis(鍵/值存儲)
- - Hbase(列族數據庫)
Spring Data 項目所支持的關系數據存儲技術:
- - JDBC
- - JPA
從之前了解的 SpringDataJpa,我們不難想象,RedisTemplate 的使用也一定是非常簡單的,下一篇看一下項目中的應用。
最后:來都來了,左上角不關注一下嗎。
如果文章有錯的地方歡迎指正,大家互相留言交流。習慣在微信看技術文章,想要獲取更多的Java資源的同學,可以關注微信公眾號:niceyoo
