一文入門Redis
一、Redis簡介
Redis:REmote DIctionary Server(遠端字典服務)。是一款使用C語言編寫的、開源的、基於記憶體的、高效能的、可持久化的非關係型Key-Value資料庫。
二、常用資料型別
1、String(字串)
string是redis最基本的資料型別,一個key對應一個value。string型別是二進位制安全的,可以包含任何資料,包括圖片、序列化的物件等,最大儲存512MB。
常用命令:
命令 | 描述 | 用法 |
---|---|---|
SET | 1、將value關聯到key;2、key已關聯則覆蓋;3、原本key帶有TTL(生存時間),那麼TTL被清楚 | SET key value |
GET | 1、返回key所關聯的字串值;2、key不存在返回null; | GET key |
SETEX | 1、將value關聯到key;2、設定key生存時間為seconds,單位為秒;3、如果key已關聯則覆蓋;4、原子操作,關聯與設定生存時間同時完成 | SETEX key seconds value |
SETNX | 1、將value關聯到key,當且僅當key不存在;2、若key已存在,不做任何動作 | SETNX key value |
2、Hash(雜湊)
hash是一個string型別的field和value的對映表,key 還是key,但是value是多個鍵值對(key-value),比較適合儲存物件。
常用命令:
命令 | 描述 | 用法 |
---|---|---|
HSET | 1、將key中的field值設為value;2、filed已存在,被覆蓋 | HSET key field value |
HGET | 1、返回key中給定域field中的值 | HGET key field |
HDEL | 1、刪除key中的一個或多個指定域;2、不存在的域被忽略 | HDEL key field |
HEXISTS | 1、檢視key中,給定域field是否存在,存在返回1,否,返回0 | HEXISTS key field |
HGETALL | 1、返回key中所有的域和值 | HGETALL key |
HLEN | 1、返回key中域的數量 | HLNE key |
3、List(列表)
list 列表,它是簡單的字串列表,按照插入順序排序,你可以新增一個元素到列表的頭部(左邊)或者尾部(右邊),它的底層實際上是個連結串列。有序、可以重複。
常用命令:
命令 | 描述 | 用法 |
---|---|---|
LPUSH | 1、將一個或多個值value按順序插入到key的表頭;2、key不存在,則建立並插入;3、key存在但不是list型別,返回錯誤; | LPSUH key value |
LPUSHX | 1、將value插入到key的頭部,當且僅當key存在且為list型別;2、key不存在,什麼都不做; | LPUSHX key value |
LPOP | 1、移除並返回key的頭元素; | LPOP key |
LRANGE | 1、返回key中指定區間的元素;2、可使用負數下標,-1表示list最後一個元素;3、start大於list最大下標,返回空列表;4、stop大於list最大下標,stop=list最大下標; | LRANG key start stop |
LSET | 1、將key下標為index的元素值設為value;2、index超出範圍或list為空,返回錯誤; | LSET key index value |
LINDEX | 1、返回key中,下標為index的元素; | LINDEX key index |
LLEN | 1、返回key的長度;2、key不存在,返回0; | LLEN key |
RPUSH | 1、將一個或多個值value按順序插入到key的表尾; | RPUSH key value |
RPUSHX | 1、將value插入到key的尾部,當且僅當key存在且為list型別; | RPUSHX key value |
RPOP | 1、移除並返回key的尾元素; | RPOP key |
4、Set(集合)
set 是 string 型別的無序集合。無序、不可重複
常用命令:
命令 | 描述 | 用法 |
---|---|---|
SADD | 1、將一個或多個元素加入key中,已存在的元素將返回0;2、key不存在,則建立並新增;3、key不是集合型別時,返回錯誤 | SADD key member |
SCARD | 1、返回key中對應的集合中的元素數量 | SCARD key |
5、Zset(有序集合)
Redis 有序集合和集合一樣也是 string 型別元素的集合,且不允許重複的成員。
不同的是每個元素都會關聯一個 double 型別的分數。redis 正是通過分數來為集合中的成員進行從小到大的排序。
有序集合的成員是唯一的,但分數(score)卻可以重複。
命令 | 描述 | 用法 |
---|---|---|
ZADD | 1、將一個或多個元素及其score值加入key中;2、如果已存在元素,則更新score值並重新插入; | ZADD key score member |
ZCARD | 1、返回key中元素個數 | ZCARD key |
ZRANGE | 1、返回key中指定區間類的成員,按score從小到大排序;2、相同score值按字典序排序;3、從大到小排序,使用ZREVRANGE命令;4、可通過WITHSCORES選項讓成員和它的score值一併返回 | ZRANGE key start stop [WITHSCORES] |
ZRANK | 1、返回有序集中成員member的排名,按score從小到大排序;2、排名以0為底,score最小的排名0 | ZRANK key member |
三、持久化
Redis 是一個記憶體資料庫將資料庫中的內容儲存在記憶體中,這與傳統的MySQL等關係型資料庫直接將內容儲存到硬碟中相比,記憶體資料庫的讀寫效率比傳統資料庫要快的多(記憶體的讀寫效率遠遠大於硬碟的讀寫效率),這也是Redis如此之快的原因。但是儲存在記憶體中也隨之帶來了一個缺點,一旦斷電或者當機,那麼記憶體資料庫中的資料將會全部丟失。
為了解決這個缺點,Redis提供了將記憶體資料持久化到硬碟,以及用持久化檔案來恢復資料庫資料的功能。Redis 支援兩種形式的持久化,分別是RDB(Redis DataBase)和AOF(Append Only File)。
1、持久化流程
- 客戶端向服務端傳送寫操作(資料在客戶端的記憶體中)。
- 資料庫服務端接收到寫請求的資料(資料在服務端的記憶體中)。
- 服務端呼叫write這個系統呼叫,將資料往磁碟上寫(資料在系統記憶體的緩衝區中)。
- 作業系統將緩衝區中的資料轉移到磁碟控制器上(資料在磁碟快取中)。
- 磁碟控制器將資料寫到磁碟的物理介質中(資料真正落到磁碟上)。
這5個過程是在理想條件下一個正常的儲存流程,但是在大多數情況下,我們的機器等等都會有各種各樣的故障,這裡劃分了兩種情況:
- Redis資料庫發生故障,只要在上面的第三步執行完畢,那麼就可以持久化儲存,剩下的兩步由作業系統替我們完成。
- 作業系統發生故障,必須上面5步都完成才可以。
2、RDB
RDB持久化是指在指定的時間間隔內將記憶體中的資料集快照寫入磁碟。即將記憶體中資料以快照的方式寫入到二進位制檔案中,預設的檔名為dump.rdb。
將備份檔案 (dump.rdb) 移動到 redis 安裝目錄並啟動服務即可回覆資料,redis就會自動載入檔案資料至記憶體了。Redis 伺服器在載入 RDB 檔案期間,會一直處於阻塞狀態,直到載入工作完成為止。
2.1、原理
把當前記憶體中的資料集快照寫入磁碟,也就是 Snapshot 快照(資料庫中所有鍵值對資料)。恢復時是將快照檔案直接讀到記憶體裡。也是Redis預設的持久化方式。
2.2、觸發方式
1、save
該命令會阻塞當前Redis伺服器,執行save命令期間,Redis不能處理其他命令,直到RDB過程完成為止。執行完成時候如果存在老的RDB檔案,就把新的替代掉舊的。我們的客戶端可能都是幾萬或者是幾十萬,這種方式顯然不可取。
“save m n”:表示m秒內資料集存在n次修改時,自動觸發bgsave。
redis.conf中預設配置:
save 900 1:表示900 秒內如果至少有 1 個 key 的值變化,則儲存
save 300 10:表示300 秒內如果至少有 10 個 key 的值變化,則儲存
save 60 10000:表示60 秒內如果至少有 10000 個 key 的值變化,則儲存
2、bgsave
執行該命令時,Redis會在後臺非同步進行快照操作,快照同時還可以響應客戶端請求。
具體操作是Redis程式執行fork操作建立子程式,RDB持久化過程由子程式負責,完成後自動結束。阻塞只發生在fork階段,一般時間很短。基本上 Redis 內部所有的RDB操作都是採用 bgsave 命令。
2.3、優缺點
-
優點
1.RDB是一個非常緊湊(compact)的檔案,它儲存了redis 在某個時間點上的資料集。這種檔案非常適合用於進行備份和災難恢復。
2.生成RDB檔案的時候,redis主程式會fork()一個子程式來處理所有儲存工作,主程式不需要進行任何磁碟IO操作。
3.RDB 在恢復大資料集時的速度比 AOF 的恢復速度要快。
-
缺點
1.RDB方式資料沒辦法做到實時持久化/秒級持久化。因為bgsave每次執行都要執行fork操作建立子程式,屬於重量級操作,如果不採用壓縮演算法(記憶體中的資料被克隆了一份,大致2倍的膨脹性需要考慮),頻繁執行成本過高(影響效能)
2.RDB檔案使用特定二進位制格式儲存,Redis版本演進過程中有多個格式的RDB版本,存在老版本Redis服務無法相容新版RDB格式的問題(版本不相容)
3.在一定間隔時間做一次備份,所以如果redis意外down掉的話,就會丟失最後一次快照後的所有修改(資料有丟失)
3、AOF
全量備份總是耗時的,AOF是一種更加高效的方式,工作機制很簡單,redis會將每一個收到的寫命令都通過write函式追加到檔案中。通俗的理解就是日誌記錄。
3.1、原理
通過儲存Redis伺服器所執行的寫命令來記錄資料庫狀態。
比如對於如下命令
set str1 "123"
sadd str2 "1" "2" "3"
lpush str3 "1" "2" "3"
RDB 持久化方式就是將 str1,str2,str3 這三個鍵值對儲存到 RDB檔案中,而 AOF 持久化則是將執行的 set,sadd,lpush 三個命令儲存到 AOF 檔案中。
3.2、配置
在redis.conf中,
- appendonly:預設值no,也就是說redis 預設使用的是rdb方式持久化,如果想要開啟 AOF 持久化方式,需要將 appendonly 修改為 yes。
- appendfilename :aof檔名,預設是"appendonly.aof"
- appendfsync:aof持久化策略的配置:
- no表示不執行fsync,由作業系統保證資料同步到磁碟,速度最快,但是不太安全;
- always表示每次寫入都執行fsync,以保證資料同步到磁碟,效率很低;
- everysec表示每秒執行一次fsync,可能會導致丟失這1s資料。通常選擇 everysec ,兼顧安全性和效率。
3.2、優缺點
-
優點
1.AOF可以更好的保護資料不丟失,一般AOF會每隔1秒,通過一個後臺執行緒執行一次fsync操作,最多丟失1秒鐘的資料。
2.AOF日誌檔案的命令通過非常可讀的方式進行記錄,這個特性非常適合做災難性的誤刪除的緊急恢復。例如,如果我們不小心錯用了 FLUSHALL 命令,在重寫還沒進行時,我們可以手工將最後的 FLUSHALL 命令去掉,然後再使用 AOF 來恢復資料。
-
缺點
1.對於具有相同資料的的 Redis,AOF 檔案通常會比 RDF 檔案體積更大。(當AOF檔案的大小超過所設定的閾值時,Redis就會啟動AOF檔案的內容壓縮,只保留可以恢復資料的最小指令集)
2.RDB 使用快照的形式來持久化整個 Redis 資料,而 AOF 只是將每次執行的命令追加到 AOF 檔案中,因此從理論上說,RDB 比 AOF 方式更健壯。官方文件也指出,AOF 的確也存在一些 BUG,這些 BUG 在 RDB 沒有存在。
4、如何選擇持久化方式?
如果可以忍受一小段時間內資料的丟失,毫無疑問使用 RDB 是最好的,定時生成 RDB 快照(snapshot)非常便於進行資料庫備份, 並且 RDB 恢復資料集的速度也要比 AOF 恢復的速度要快,而且使用 RDB 還可以避免 AOF 一些隱藏的 bug;否則就使用 AOF 重寫。但是一般情況下建議不要單獨使用某一種持久化機制,而是應該兩種一起用,在這種情況下,當redis重啟的時候會優先載入AOF檔案來恢復原始的資料,因為在通常情況下AOF檔案儲存的資料集要比RDB檔案儲存的資料集要完整。Redis後期官方可能都有將兩種持久化方式整合為一種持久化模型。
如果有學到東西,請點贊給予鼓勵,謝謝。