Redis應用實踐

 

     Redis Java客戶端有不少的開源產品好比Redission、Jedis、lettuce
     Jedis是Redis的Java實現的客戶端,其API提供了比較全面的Redis命令的支持;
     Redisson實現了分佈式和可擴展的Java數據結構,和Jedis相比,功能較爲簡單,不支持字符串操做,不支持排 序、事務、管道、分區等Redis特性。Redisson主要是促進使用者對Redis的關注分離,從而讓使用者可以將精力更 集中地放在處理業務邏輯上。
     lettuce是基於Netty構建的一個可伸縮的線程安全的Redis客戶端,支持同步、異步、響應式模式。多個線程能夠 共享一個鏈接實例,而沒必要擔憂多線程併發問題;
 

      一:Redis基本操做redis

     基於RedisTemplate(Spring對操做Redis數據庫的封裝)對五種數據類型的操做數據庫

      string類型          緩存

      適用場景:通常的key-value緩存,計數功能的緩存。安全

 

      list類型               服務器

        適用場景: value存放的是結構化的對象,比較方便的就是操做其中的某個字段。博主在作單點登陸的時候,就是用這種數據結構存儲用戶信息,以cookieId做爲key,設置30分鐘爲緩存過時時間,能很好的模擬出相似session的效果。cookie

 

       hash類型          session

         使用場景:使用List的數據結構,能夠作簡單的消息隊列的功能。另外還有一個就是,能夠利用lrange命令,作基於redis的分頁功能,性能極佳,用戶體驗好。數據結構

        set類型           多線程

         使用場景: set堆放的是一堆不重複值的集合。因此能夠作全局去重的功能。爲何不用JVM自帶的Set進行去重?由於咱們的系統通常都是集羣部署,使用JVM自帶的Set,比較麻煩,難道爲了一個作一個全局去重,再起一個公共服務,太麻煩了。另外,就是利用交集、並集、差集等操做,能夠計算共同喜愛,所有的喜愛,本身獨有的喜愛等功能。架構

         zset類型            

         使用場景:  sorted set多了一個權重參數score,集合中的元素可以按score進行排列。能夠作排行榜應用,取TOP N操做。另外,參照另外一篇《分佈式之延時任務方案解析》,該文指出了sorted set能夠用來作延時任務。最後一個應用就是能夠作範圍查找。

 

          二: Redis實現分佈式鎖
           經過Jedis,Redisson實現
 
          三: Redis的應用架構          

           常見的幾個問題
           (一)緩存和數據庫雙寫一致性問題

                 獲取緩存的基本流程:

                 那麼有幾個問題出現:      

                 1. 先操做緩存中的數據再更新數據庫的數據

                 2. 修改數據庫中的數據再操做緩存中的數據

                 3. 更新緩存仍是讓緩存失效

                 redis中的數據和數據庫中的數據不可能保證絕對事務性,這個是毫無疑問的,因此在實際應用中,咱們都是基於當前的場景進行權衡下降出現不一致問題的出現機率。更新緩存表示數據不但會寫入到數據庫,還會同步更新緩存,而讓緩存失效是表示只更新數據庫中的數據,而後刪除緩存中對應的key。那麼這兩種方式怎麼去選擇?

                 1. 若是更新緩存的代價很小,那麼能夠先更新緩存,這個代價很小的意思是不須要很複雜的計算。
                 2. 若是是更新緩存的代價很大,意味着須要經過多個接口調用和數據查詢才能得到最新的結果,那麼能夠先淘汰緩存。淘汰緩存之後後續的請求若是在緩存中找不到,天然去數據庫中檢索。
更新數據庫和更新緩存這兩個操做,是沒法保證原子性的,因此咱們須要根據當前業務的場景的容忍性來選擇。也就是若是出現不一致的狀況下,哪種更新方式對業務的影響最小,就先執行影響最小的方案。

 

           (二)緩存雪崩問題

                 緩存同一時間大面積的失效,這個時候又來了一波請求,結果請求都懟到數據庫上,從而致使數據庫鏈接異常            

                     1. 對緩存的訪問,若是發現從緩存中取不到值,那麼經過加鎖或者隊列的方式保證緩存的單進程操做,從而避免失效時併發請求所有落到底層的存儲系統上,可是這種方式會帶來性能上的損耗。
                     2. 將緩存失效的時間分散,下降每個緩存過時時間的重複率。
                     3. 若是是由於緩存服務器故障致使的問題,一方面須要保證緩存服務器的高可用、另外一方面,應用程序中能夠採用多級緩存。

           (三)緩存擊穿問題

                 黑客故意去請求緩存中不存在的數據,致使全部的請求都懟到數據庫上,從而數據庫鏈接異常         

                     1. 若是查詢數據庫也爲空,直接設置一個默認值存放到緩存,這樣第二次到緩衝中獲取就有值了,而不會繼續訪問數據庫,這種辦法最簡單粗暴。好比,」key」 , 「&&」。在返回這個&&值的時候,我    們的應用就能夠認爲這是不存在的key,那咱們的應用就能夠 決定是否繼續等待繼續訪問,仍是放棄掉此次操做。若是繼續等待訪問,過一個時間輪詢點後,再次請求這個key,若是取到的值再也不是&&,則能夠認爲這時候key有值了,從而避免了透傳到數據庫,從而把大量的相似請求擋在了緩存之中。

                     2. 根據緩存數據Key的設計規則,將不符合規則的key進行過濾採用布隆過濾器,將全部可能存在的數據哈希到一個足夠大的BitSet中,不存在的數據將會被攔截掉,從而避免了對底層存儲系統的查  詢壓力。

相關文章
相關標籤/搜索