1. 程式人生 > >Redis零基礎筆記之三 -- Redis的高階特性

Redis零基礎筆記之三 -- Redis的高階特性

Redis進階實踐之五Redis的高階特性

一、引言

    上一篇文章寫了Redis的特徵,使用場景,同時也介紹了Redis的基本資料型別,redis的資料型別是操作redis的基礎,這個必須好好的掌握。今天我們開始介紹一些Redis的高階特性,雖然有些命令很簡單,但是這些命令是使用很廣泛的,並且是通用的一些命令,好好的把握這些命令,通過組合這些命令可以完成比較複雜的任務,這都是基礎,我們就開始我們今天的學習之旅吧。

二、Redis的高階特性

   下面我們就是Redis高階特性的每個知識點,只是個人的理解,隨著學習的深入,也會更新相關的章節。

  1、通用命令:



    1.1】、語法:keys pattern,pattern可以是類似正則的匹配規則,可以是*,也可以是?,返回匹配規則的鍵值key的列表。

複製程式碼

           192.168.127.128:6379>keys *
           1)"name"
           2)"set2"
           3)"set1"

           192.168.127.128:6379>keys n*
           1)"name"

           192.168.127.128:6379>keys s*
           1)"set2"
           2)"set1"

           192.168.127.128:6379>keys set?
           1)"set2"
           2)"set1"

           192.168.127.128:6379>keys n?me
           1)"name"

複製程式碼


    1.2】、語法:exists key [key ...],判斷一個或者多個key是否存在,並返回存在key的個數,不存在返回0。

複製程式碼

           192.168.127.128:6379>keys *
           1)"name"
           2)"age"

           192.168.127.128:6379>exists name age address(該值存在)
           (integer)2

           192.168.127.128:6379>exists name1 age1 address(該值存在)
           (integer)0

複製程式碼


    1.3】、語法:expire key seconds,給指定的key設定過期時間,單位是秒。用ttl命令可以檢視剩餘的時間,如果想更精確的、效能更好的倒計時功能,可以使用該功能。設定過期時間成功返回值為1,此命令可以多次執行,後面的過期值會覆蓋前面的過期值。過期的資料會從Redis資料庫裡刪除。

複製程式碼

           192.168.127.128:6379>expire name 60 設定name過期時間為60秒
           (integer)1

           192.168.127.128:6379>expire name 50 設定name過期時間為50秒
           (integer)1

           192.168.127.128:6379>ttl name
           (integer)48

           192.168.127.128:6379>ttl name
           (integer)45

            ttl返回值:

              -1、過期時間不存在

              -2、過期操作成功,資料已經移除

複製程式碼


    1.4】、語法:persist key,取消已經設定了過期時間的key的過期策略。取消過期策略成功返回1,key沒有過期策略返回0。

複製程式碼

           192.168.127.128:6379>keys *
           1)"name"
           2)"age"

           192.168.127.128:6379>expire name 60 設定name過期時間為60秒
           (integer)1

           192.168.127.128:6379>persist name
           (integer)1 //成功取消設定的過期策略

           192.168.127.128:6379>persist name
           (integer)0 //上一步已經取消了,在此執行取消操作返回0。

複製程式碼


    1.5】、語法:select index,在Redis中,邏輯劃分為16個數據庫,索引從0-15,我們在使用的過程中,可以針對不同的業務邏輯把資料快取在不同的資料庫,這是一個很好的架構設計,切記不要把所有的資料放在0號資料庫裡,不便於管理和分類。這16個數據庫資料是分離的,不是共享的,或者說資料都是獨立的。

複製程式碼

           192.168.127.128:6379>select 1
           OK

           192.168.127.128:6379[1]>

           192.168.127.128:6379[1]>select 5
           OK

           192.168.127.128:6379[5]>

複製程式碼


    1.6】、語法:move key db,至指定名稱為key的鍵值對轉移到指定資料庫db裡面,db是資料下標索引。

複製程式碼

           //索引為0的資料庫
           192.168.127.128:6379>keys *
           1)"name"
           2)"age"

           //索引為5的資料庫
           192.168.127.128:6379[5]>keys *
           (empty list or set)

           //在索引為5的資料庫裡面增加sex鍵值對,然後把其移動到索引為0的資料庫
           192.168.127.128:6379[5]>set sex nan
           OK

           192.168.127.128:6379[5]>keys *
           1)"sex"

           192.168.127.128:6379[5]>move sex 0
           (integer)1

           //索引為0的資料庫
           192.168.127.128:6379>keys *
           1)"name"
           2)"sex"    //從索引為5的資料已經移動到了索引為0的資料庫
           2)"age"

複製程式碼


    1.7】、語法:randomkey,隨機返回當前資料庫中的key,其實這個功能我們可以使用在抽獎的場景,如果在併發比較高,而且有要保證效能的情況下,我建議大家使用Redis的這個功能來完成抽獎的功能。有時候會返回重複的值,如果做抽獎需要做處理一下。

複製程式碼

           192.168.127.128:6379>keys *
           1)"name"
           2)"sex"
           2)"age"

           192.168.127.128:6379>randomkey
           "name"

           192.168.127.128:6379>randomkey
           "age"

           192.168.127.128:6379>randomkey
           "age"

複製程式碼


    1.8】、語法:rename key newkey,重新給指定的key命名。

複製程式碼

           192.168.127.128:6379>keys *
           1)"name"
           2)"sex"
           2)"age"

           192.168.127.128:6379>rename name name1
           OK

           192.168.127.128:6379>keys *
           1)"name1"
           2)"sex"
           2)"age"

           192.168.127.128:6379>rename name1 name
           OK

複製程式碼

 


    1.9】、語法:echo message,在當前介質上列印message資訊。

           192.168.127.128:6379>echo patrickLiu
           "patrickLiu"


    1.10】、語法:dbsize,返回當前資料中鍵值對的個數,或者更準確的說是key的個數。

複製程式碼

           192.168.127.128:6379>keys *
           1)"name"
           2)"sex"
           2)"age"

           192.168.127.128:6379>dbsize
           3

複製程式碼


    1.11】、語法:info [section],可以獲取當前資料的詳細資訊。

複製程式碼

           192.168.127.128:6379>info //顯示當前資料的所有資料


           192.168.127.128:6379>info replication //顯示指定節的資訊
           # Replication

           role:master
           connected_slaves:0
           ...

複製程式碼


    1.12】、語法:config get *,獲取配置檔案中的所有的配置資料。

複製程式碼

           192.168.127.128:6379>config get *
           ...

           192.168.127.128:6379>config get bind
           1)"bind"
           2)"192.168.127.128"

           192.168.127.128:6379>config get port
           1)"port"
           2)"6379"

複製程式碼


    1.13】、語法:flushdb,清空當前資料所有的鍵值對。

           192.168.127.128:6379>flushdb
           OK

           192.168.127.128:6379>keys *
           (empty list or set)


    1.14】、語法:flushall,清空所有資料庫的所有鍵值對。

複製程式碼

           192.168.127.128:6379>flushall
           OK


           192.168.127.128:6379[1]>keys *
           (empty list or set)

           ...

           192.168.127.128:6379[5]>keys *
           (empty list or set)

           ...

複製程式碼


  2、安全設定

     2.1】、vi 或者 vim 編輯 redis.conf 文件,修改
     
          #requirepass 123456 (設定密碼)
          
           requirepass admin

     2.2】、重啟伺服器 pkill redis-server

複製程式碼

           [[email protected]~]# application/program/redis-tool/redis-cli -h 192.168.127.128 -p 6379

           192.168.127.128:6379>keys *
           (error)NOAUTH Authentication required.

           192.168.127.128:6379>auth admin   //授權
            OK

           192.168.127.128:6379>keys *  //可以執行
           (empty list or set)

複製程式碼


     2.3】、[[email protected]~]/root/application/program/redis-tool/redis-cli -h 192.168.127.128 -p 6379 -a admin

  3、事務模型

     redis也是支援事務的,但是這個事務是比較簡單的,之所以說簡單,是因為redis的事務不能保證操作的同時成功或者同時失敗而進行提交或者回滾,這種情形很容易導致資料的不一致性,大家使用的時候要特別注意。

     3.1】、首先通過multi命令開啟事務,然後進行事務性的設定,這些設定完的資料會儲存在虛擬佇列中,最後可以通過exec命令執行事務。

複製程式碼

           //當前資料庫中無值
           192.168.127.128:6379>keys *
           (empty list or set)


           192.168.127.128:6379>multi
           OK

           192.168.127.128:6379>set p1 1
           QUEUED

           192.168.127.128:6379>set p2 2
           QUEUED

           192.168.127.128:6379>set p3 3
           QUEUED

           192.168.127.128:6379>exec
           1)OK
           2)OK
           3)OK

           192.168.127.128:6379>keys *
           1)"p3"
           2)"p2"
           3)"p1"

複製程式碼


     3.2】、redis的事務可以通過discard命令取消事務。

複製程式碼

           //當前資料庫中的值
           192.168.127.128:6379>keys *
           1)"p3"
           2)"p2"
           3)"p1"

           192.168.127.128:6379>multi
           OK

           192.168.127.128:6379>set p4 4
           QUEUED

           192.168.127.128:6379>set p5 5
           QUEUED

           192.168.127.128:6379>discard  //取消事務
           OK

           //值沒變
           192.168.127.128:6379>keys *
           1)"p3"
           2)"p2"
           3)"p1"

複製程式碼


     3.3】、特別注意redis事務的不一致性。(以前版本有這個問題,現在版本有修復,我的是redis-5.0.3,會回滾)

複製程式碼

           //當前資料庫中的值
           192.168.127.128:6379>keys *
           1)"age"
           2)"name"

           192.168.127.128:6379>get name
           "huangfeihong"

           192.168.127.128:6379>get age
           (integer)18

           192.168.127.128:6379>multi
           OK

           192.168.127.128:6379>incr name
           QUEUED

           192.168.127.128:6379>incr age
           QUEUED

           192.168.127.128:6379>exec
           1)(error)ERR value is not an integer or out of range
           2)(integer)19

           192.168.127.128:6379>get name
           "huangfeihong" //姓名沒有改變

           192.168.127.128:6379>get age
           (integer)19  //當前年齡已經修改

複製程式碼

Redis-5.0.3執行情況

     再次強調,在真正的產品環境中,要特別注意Redis事務的這個特點,或者說是弊端,不能保證資料的一致性。

  4、持久化

     Redis是一種高階key-value資料庫。它跟memcached類似,不過資料可以持久化。Redis的所有資料都是儲存在記憶體中,然後不定期的通過非同步方式儲存到磁碟上(這稱為“半持久化模式”);也可以把每一次資料變化都寫入到一個append only file(aof)裡面(這稱為“全持久化模式”)。所以來說,總結起來,Redis的資料持久化就有兩種方式。

     4.1】、第一種方法filesnapshotting(rdb):預設redis是會以快照的形式將資料持久化到磁碟的(一個二進位制檔案,dump.rdb,這個檔名字可以指定),在配置檔案中的格式是:save N(秒數) M(改變的個數),表示在N秒之內,redis至少發生M次修改,redis才生成快照並持久化到磁碟。當然我們也可以手動執行save或者bgsave(非同步)做快照。該模式無論怎麼設定,都會產生時間間隔,如果在這時間間隔斷電,資料還是會丟失,會對資料持久化產生不利的影響,在實際的生產環境中,不建議使用該模式。

          save 900 1     900秒內有超過1個的key值被修改了就發起快照儲存

          save 300 30    300秒內有超過30個的key值被修改了就發起快照儲存

          save 60  10000 60秒內有超過10000個的key值被修改了就發起快照儲存


     4.2】、第二種方法是Append-only-file(aof):Append-only方法可以做到全部資料不丟失,但redis的效能就要差些。AOF就可以做到全程持久化,只需要在配置檔案中開啟,預設是不開啟AOF功能的(appendonly no),appendonly yes開啟AOF之後,redis每執行一個修改資料的命令,都會把它新增到aof檔案中,當redis重啟時,將會讀取AOF檔案進行“重放”以恢復到redis關閉前的最後時刻。

          appendfsync有三個選項:always、everysec和no:

         1、always:伺服器會在每執行一個事件就把AOF緩衝區的內容強制性的寫入硬碟上的AOF檔案裡,可以看成你每執行一個redis寫入命令就往AOF檔案裡記錄這條命令,這保證了資料持久化的完整性,但效率是最慢的,卻也是最安全的;

         2、everysec:服務端每執行一次寫操作也會把該條命令追加到一個單獨的AOF緩衝區的末尾,並將AOF緩衝區寫入AOF檔案,然後每隔一秒才會進行一次檔案同步把記憶體緩衝區裡的AOF快取資料真正寫入AOF檔案裡,這個模式兼顧了效率的同時也保證了資料的完整性,即使在伺服器宕機也只會丟失一秒內對redis資料庫做的修改;

         3、no:你完全可以接受Redis資料的丟失,它雖然也會把每條寫命令追加到AOF緩衝區的末尾,然後寫入檔案,但什麼時候進行檔案同步真正把資料寫入AOF檔案裡則由系統自身決定,即當記憶體緩衝區的空間被填滿或者是超過了設定的時限後系統自動同步。這種模式下效率是最快的,但對資料來說也是最不安全的,如果redis裡的資料都是從後臺資料庫如mysql中取出來的,屬於隨時可以找回或者不重要的資料,那麼可以考慮設定成這種模式。

        [[email protected]~]# more application/program/redis-tool/redis.conf
        dir "/root/application/program/redis-tool/datas/"           #AOF或者RDB檔案存放目錄
        appendonly yes                       #啟用AOF持久化,預設關閉,RDB模式就關閉了,兩者是二選一的情況
        appendfilename "appendonly.aof"      #AOF持久化的檔名稱(預設)
        appendfsync no                       #AOF持久化的策略
        auto-aof-rewrite-percentage 100      #觸發AOF檔案重寫的條件(預設)
        auto-aof-rewrite-min-size 64mb       #觸發AOF檔案重寫的條件(預設)


  5、釋出訂閱

     Redis的這個釋出訂閱功能有點類似MQ(訊息佇列)功能,但是這功能不能濫用,它的使用場景非常有限,並且資料量也不能太大。比如:成千上萬條的資料場景是可以滿足的,如果訂閱和釋出的資料量超過N萬、十萬、千萬或者億級別,這樣的場景就很難滿足了,到那時候我們就需要使用真正的MQ來滿足該功能了。

     5.1】、語法:subscribe channel [channel ...],進行訂閱監聽,可以接受來之釋出端的訊息了。可以定義多個頻道,這個頻道的名稱是自己可以定義的。

複製程式碼

           192.168.127.128:6379>subscribe c1 c2
           Reading messages...(press Ctrl-C quit)         
           1)"subscribe"
           2)"c1"
           3)(integer)1
           1)"subscribe"
           2)"c2"
           3)(integer)2
           //接受的到的訊息
           1)"message"
           2)"c2"
           3)"redis"

           1)"message"
           2)"c1"
           3)"hello"

           //處於等待狀態,可以接收訊息了

複製程式碼


     5.2】、語法:publish channel message,針對指定的訊息頻道釋出訊息,訂閱端就可以接受到訊息了。
 

           192.168.127.128:6379>publish c1 hello
           (integer)1  //釋出訊息成功

           192.168.127.128:6379>publish c2 redis
           (integer)1  //釋出訊息成功


三、總結

   隨著學習的深入,理解的越來越全面和深刻了,以前很多聯絡不起來的知識點都聯絡起來了,以後還需繼續努力,如果有了新的學習心得,還會持續更新相關的章節。隨著學習的繼續,也讓自己養成學習的習慣。努力吧!!!!