Redis學習系列

1、什麼是Redis

Redis是一個基於內存的高性能Key-Value數據庫

2、Redis爲什麼這麼快

  • 完全基於內存,絕大部分請求是純粹的內存操作,執行效率高
  • 數據結構簡單,對數據的操作也簡單
  • 採用單線程,單線程也能處理高併發請求,想多核也可啓動多實例;可保證操作的串行執行,從而減少不必要的上下文切換
  • 使用多路I/O複用模型,非阻塞I/O

3、Redis數據類型

  1. String:最基本的數據類型,二進制安全

  2. Hash:String元素組成的散列,特別適合用於存儲對象

  3. List:簡單的字符串列表,按照插入順序排序。兩端插入

    list的內部實現爲一個雙向鏈表,即可以支持反向查找和遍歷,更方便操作。

    使用場景:1. 最新消息排行榜;2. 分頁:lrange

  4. Set:String類型的無序集合,集合成員是唯一的,不能出現重複數據,通過hash表實現,複雜度O(1)

    set的內部實現是一個value永遠爲null的HashMap,實際就是通過計算hash來快速排重的,這也是set能提供判斷一個成員是否在集合內的原因。

    使用場景:1. 去重列表;2. 存儲一些集合性的數據,如微博應用中,關注人和粉絲分別存儲在一個集合,Redis還提供了求交集、並集、差集等操作實現共同關注,共同喜好等。

  5. Zset:String類型的有序集合,不允許成員重複,每個元素關聯一個double類型的分數,默認小到大排序

    使用場景:1. 排行榜相關;2. 帶權重的隊列,普通消息score爲1,重要信息score爲2,倒序取,重要的任務先執行

  6. Redis HyperLogLog 是用來做基數統計的算法

4、Redis持久化方式

  • RDB持久化:Redis會定期保存數據快照到一個rdb文件中,並在啓動的時候自動加載rdb文件,恢復之前保存的數據。可以在配置文件中配置Redis進行快照的時機。默認爲dump.rdb,會備份dump.rdb

    Redis默認配置:

    • save 900 1 //在900秒內至少有一個key發生變化,觸發一次持久化操作
    • save 300 10 //在300秒內至少10個key發生變化,觸發一次持久化操作
    • save 60 10000 //在60秒內至少10000個key

    save:阻塞Redis的服務器進程,知道rdb文件被創建完畢

    BGsave:Fork出一個子進程來創建rdb文件,不阻塞服務器進程

    觸發時機:

    • 指定時間間隔內,執行指定次數的寫操作
    • 執行save或者bgsave命令
    • 執行flushall命令,清空數據庫所有數據
    • 執行shutdown命令,保證服務器正常關閉並且不丟失任何數據

    優點:

    • 全量數據快照,適合做備份,適用於災難恢復
    • 文件比較小,恢復速度快
    • 性能最大化,因爲fork出子進程來進行rdb的創建,不阻塞服務

    缺點:

    • 可能會丟失數據
    • 當數據過大時,服務器會暫停幾百毫秒或者一秒鐘
  • AOF持久化:Redis默認不開啓。採用日誌追加的形式來記錄每個寫操作。Redis重啓以後,會根據日誌文件的內容將寫指令從前到後執行一次以完成數據的恢復工作。

    要開啓AOF需要在配置文件設置

    • redis默認關閉,開啓需要將no改爲yes

      appendonly yes
      
    • 指定本地數據庫文件名,默認值爲 appendonly.aof

    • 指定更新日誌文件

      # appendfsync always  //同步持久化,每次發生數據變化後就立刻寫入磁盤,性能差但數據完整性高
      appendfsync everysec  //出廠默認推薦,每秒異步記錄一次
      # appendfsync no  //不同步
      
    • 配置重寫觸發機制

      auto-aof-rewrite-percentage 100
      auto-aof-rewrite-min-size 64mb
      

      當AOF文件大小是上次重寫後大小的一倍,並且文件大於64MB的時候觸發,一般設置爲3GB,64M太小

    • 根據AOF文件恢復數據

      正常情況下,將appendonly.aof文件拷貝到redis的安裝目錄下的bin目錄下,重啓redis服務即可,但是在實際開發中可能會因爲某些原因導致appendonly.aof文件格式異常,從而導致數據恢復失敗,可以通過 redis-check-aof --fix appendonly.aof 進行修復

    • AOF重寫機制

      AOF的工作原理就是將寫操作追加到文件中,文件的冗餘內容會越來越多,所以就有了重寫。當AOF文件大小超過了設定閾值,就會觸發重寫,對AOF文件的內容進行壓縮

      重寫的原理:Redis會fork出一個子進程,讀取內存中的數據,直接生成最終數據的寫入命令,最後將舊的AOF文件替換掉

    優點:

    • 帶來更高的數據安全
    • 對日誌文件的寫入是append追加模式,若出現宕機情況,也不會破壞日誌文件中已經存在的內容
    • 若日誌過大,Redis可以自動啓動重寫機制
    • 包含一個格式清晰易於理解的日誌文件,來記錄所有的操作

    缺點:

    • 對於相同數量的數據集,文件相對rdb方式要大,恢復相對較慢
    • 根據同步策略的不同,效率也比rdb要低一些

5、Redis數據的恢復

默認會使用RDB-AOF混合持久化方式

bgsave做鏡像全量持久化,AOF做增量持久化

當rdb文件與aof文件共存的情況下,Redis會先檢查aof文件是否存在;若不存在則去檢查rdb是否存在。

6、Redis主從配置

  1. 常用命令

    • 根據配置文件啓動redis:src/redis-server redis.conf
    • 啓動redis客戶端:redis-cli -p port
    • Slaver連接Master:slaveof host:ip(測試時使用slaveof手動連接master,正式環境下使用配置文件)
    • 關閉Redis:shutdown
    • 查看主從信息:info Replication
  2. Redis配置

    1. 按照1主2從的結構搭建,即一個Master,兩個Slaver節點

    2. Redis配置文件redis.conf的配置
      Redis主從配置

    3. 配置完以後可以根據info Replication查看主從信息

      1. 當Master節點設置了key後,就會異步同步到slaver節點;slaver只能讀取數據,不能修改
      2. 當Master掛掉以後,slaver保持原地待命狀態,Master重啓後,一切照舊
      3. 當slaver掛掉以後,需要重新通過slaveof連接到Master下面
    4. 主節點掛掉以後也可以手動將子節點升級爲主節點

      slaveof no one

    5. 上面講到的需要手動配置,明顯不符合實際業務需求,所以可以使用哨兵模式自動檢測

      1. sentinel.conf配置文件,修改sentinel monitor host6379 127.0.0.1 6379 1,其它使用默認即可
        host6379 主機名稱,隨便起 主機IP 端口 1表示選舉,某個slaver得到超過1票則成爲Master節點
      2. 啓動sentinel: ./redis-sentinel …/sentinel.conf

    主從複製總結:

    1. Master可讀可寫,Slaver只能讀,不能寫
    2. Master可以對應多個Slaver,但是數量越多壓力越大,延遲就可能越嚴重
    3. Master寫入後立即返回,幾乎同時將寫入異步同步到各個Slaver,所以基本上延遲可以忽略
    4. 可以通過slaveof no one命令將Slaver升級爲Master(當Master掛掉時,手動將某個Slaver變爲Master)
    5. 可以通過sentinel哨兵模式監控Master,當Master掛掉時自動選舉Slaver變爲Master,其它Slaver自動重連新的Master

7、redis使用

  1. 導入jedis依賴

  2. 配置Redis連接池屬性:一個pool可分配多少個jedis實例,最大空閒連接,最大等待時間,獲取連接時檢查有效性

  3. 創建連接池,並做相關配置。jedisPool類含有有參構造函數(jedis配置,redis IP地址,redis端口號)

    創建jedisUtil工具類,封裝了redis基本操作

    o2o:更新較少的區域信息,頭條信息,店鋪類別信息

    redis將key在service中定義爲常量,操作在serviceImpl中進行

    利用String進行存儲

    當緩存中不存在時,將查詢到的信息轉換成字符串形式

    //定義jackson數據轉換操作類
    ObjectMapper mapper = new ObjectMapper();
    String jsonString = mapper.writeValueAsString(查詢到的數據);
    jedisString.set(key,jsonString);
    

    如果當緩存中存在當前的key,則需要根據key獲取相應的value值,並轉換成我們需要的集合

    String jsonString = jedisString.get(key);
    JavaType javaType = mapper.getTypeFactory().constructParametricType(ArrayList.class,Area.class);
    arrayList = mapper.readValue(jsonString,javaType);
    

    清除緩存,編寫cacheService,只有一個方法,就是從緩存中清除key(匹配某個前綴的所有key)

    實現類,取出所有的某個前綴開頭的key,並放入set集合中,遍歷set並刪除對應的key

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章