您好,登錄后才能下訂單哦!
這篇文章主要介紹了Redis全面知識點有哪些的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Redis全面知識點有哪些文章都會有所收獲,下面我們一起來看看吧。
Redis 簡介
Redis 是完全開源免費的,遵守 BSD 協議,是一個高性能的 key - value 數據庫
Redis 與 其他 key - value 緩存產品有以下三個特點:
Redis 支持數據持久化,可以將內存中的數據保存在磁盤中,重啟的時候可以再次加載進行使用。
Redis 不僅僅支持簡單的 key - value 類型的數據,同時還提供 list,set,zset,hash 等數據結構的存儲
Redis 支持數據的備份,即 master - slave 模式的數據備份
Redis 優勢
性能極高 – Redis 讀的速度是 110000 次 /s, 寫的速度是 81000 次 /s 。
豐富的數據類型 - Redis 支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操作。
原子性 - Redis 的所有操作都是原子性的,意思就是要么成功執行要么失敗完全不執行。單個操作是原子性的。多個操作也支持事務,即原子性,通過 MULTI 和 EXEC 指令包起來。
其他特性 - Redis 還支持 publish/subscribe 通知,key 過期等特性。
Redis 數據類型
Redis 支持 5 中數據類型:string(字符串),hash(哈希),list(列表),set(集合),zset(sorted set:有序集合)
string
string 是 redis 最基本的數據類型。一個 key 對應一個 value。
string 是二進制安全的。也就是說 redis 的 string 可以包含任何數據。比如 jpg 圖片或者序列化的對象。
string 類型是 redis 最基本的數據類型,string 類型的值最大能存儲 512 MB。
理解:string 就像是 java 中的 map 一樣,一個 key 對應一個 value
127.0.0.1:6379> set hello world OK 127.0.0.1:6379> get hello "world"
hash
Redis hash 是一個鍵值對(key - value)集合。Redis hash 是一個 string 類型的 key 和 value 的映射表,hash 特別適合用于存儲對象。
理解:可以將 hash 看成一個 key - value 的集合。也可以將其想成一個 hash 對應著多個 string。
與 string 區別:string 是 一個 key - value 鍵值對,而 hash 是多個 key - value 鍵值對。
// hash-key 可以看成是一個鍵值對集合的名字,在這里分別為其添加了 sub-key1 : value1、 sub-key2 : value2、sub-key3 : value3 這三個鍵值對 127.0.0.1:6379> hset hash-key sub-key1 value1 (integer) 1 127.0.0.1:6379> hset hash-key sub-key2 value2 (integer) 1 127.0.0.1:6379> hset hash-key sub-key3 value3 (integer) 1 // 獲取 hash-key 這個 hash 里面的所有鍵值對 127.0.0.1:6379> hgetall hash-key 1) "sub-key1" 2) "value1" 3) "sub-key2" 4) "value2" 5) "sub-key3" 6) "value3" // 刪除 hash-key 這個 hash 里面的 sub-key2 鍵值對 127.0.0.1:6379> hdel hash-key sub-key2 (integer) 1 127.0.0.1:6379> hget hash-key sub-key2 (nil) 127.0.0.1:6379> hget hash-key sub-key1 "value1" 127.0.0.1:6379> hgetall hash-key 1) "sub-key1" 2) "value1" 3) "sub-key3" 4) "value3"
list
Redis 列表是簡單的字符串列表,按照插入順序排序。我們可以網列表的左邊或者右邊添加元素。
127.0.0.1:6379> rpush list-key v1 (integer) 1 127.0.0.1:6379> rpush list-key v2 (integer) 2 127.0.0.1:6379> rpush list-key v1 (integer) 3 127.0.0.1:6379> lrange list-key 0 -1 1) "v1" 2) "v2" 3) "v1" 127.0.0.1:6379> lindex list-key 1 "v2" 127.0.0.1:6379> lpop list (nil) 127.0.0.1:6379> lpop list-key "v1" 127.0.0.1:6379> lrange list-key 0 -1 1) "v2" 2) "v1"
我們可以看出 list 就是一個簡單的字符串集合,和 Java 中的 list 相差不大,區別就是這里的 list 存放的是字符串。list 內的元素是可重復的。
set
redis 的 set 是字符串類型的無序集合。集合是通過哈希表實現的,因此添加、刪除、查找的復雜度都是 O(1)
127.0.0.1:6379> sadd k1 v1 (integer) 1 127.0.0.1:6379> sadd k1 v2 (integer) 1 127.0.0.1:6379> sadd k1 v3 (integer) 1 127.0.0.1:6379> sadd k1 v1 (integer) 0 127.0.0.1:6379> smembers k1 1) "v3" 2) "v2" 3) "v1" 127.0.0.1:6379> 127.0.0.1:6379> sismember k1 k4 (integer) 0 127.0.0.1:6379> sismember k1 v1 (integer) 1 127.0.0.1:6379> srem k1 v2 (integer) 1 127.0.0.1:6379> srem k1 v2 (integer) 0 127.0.0.1:6379> smembers k1 1) "v3" 2) "v1"
redis 的 set 與 java 中的 set 還是有點區別的。
redis 的 set 是一個 key 對應著 多個字符串類型的 value,也是一個字符串類型的集合,但是和 redis 的 list 不同的是 set 中的字符串集合元素不能重復,但是 list 可以。
Zset
redis zset 和 set 一樣都是 字符串類型元素的集合,并且集合內的元素不能重復。
不同的是,zset 每個元素都會關聯一個 double 類型的分數。redis 通過分數來為集合中的成員進行從小到大的排序。
zset 的元素是唯一的,但是分數(score)卻可以重復。
127.0.0.1:6379> zadd zset-key 728 member1 (integer) 1 127.0.0.1:6379> zadd zset-key 982 member0 (integer) 1 127.0.0.1:6379> zadd zset-key 982 member0 (integer) 0 127.0.0.1:6379> zrange zset-key 0 -1 withscores 1) "member1" 2) "728" 3) "member0" 4) "982" 127.0.0.1:6379> zrangebyscore zset-key 0 800 withscores 1) "member1" 2) "728" 127.0.0.1:6379> zrem zset-key member1 (integer) 1 127.0.0.1:6379> zrem zset-key member1 (integer) 0 127.0.0.1:6379> zrange zset-key 0 -1 withscores 1) "member0" 2) "982"
zset 是按照分數的大小來排序的。
發布訂閱
一般不用 Redis 做消息發布訂閱。
簡介
Redis 發布訂閱 (pub/sub) 是一種消息通信模式:發送者 (pub) 發送消息,訂閱者 (sub) 接收消息。
Redis 客戶端可以訂閱任意數量的頻道。
下圖展示了頻道 channel1 , 以及訂閱這個頻道的三個客戶端 —— client2 、 client5 和 client1 之間的關系:
學Redis這篇就夠了
當有新消息通過 PUBLISH 命令發送給頻道 channel1 時, 這個消息就會被發送給訂閱它的三個客戶端:
學Redis這篇就夠了
實例
以下實例演示了發布訂閱是如何工作的。在我們實例中我們創建了訂閱頻道名為 redisChat:
127.0.0.1:6379> SUBsCRIBE redisChat Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "redisChat"
現在,我們先重新開啟個 redis 客戶端,然后在同一個頻道 redisChat 發布兩次消息,訂閱者就能接收到消息。
127.0.0.1:6379> PUBLISH redisChat "send message" (integer) 1 127.0.0.1:6379> PUBLISH redisChat "hello world" (integer) 1 # 訂閱者的客戶端顯示如下 1) "message" 2) "redisChat" 3) "send message" 1) "message" 2) "redisChat" 3) "hello world"
事務
redis 事務一次可以執行多條命令,服務器在執行命令期間,不會去執行其他客戶端的命令請求。
事務中的多條命令被一次性發送給服務器,而不是一條一條地發送,這種方式被稱為流水線,它可以減少客戶端與服務器之間的網絡通信次數從而提升性能。
Redis 最簡單的事務實現方式是使用 MULTI 和 EXEC 命令將事務操作包圍起來。
批量操作在發送 EXEC 命令前被放入隊列緩存。
收到 EXEC 命令后進入事務執行,事務中任意命令執行失敗,其余命令依然被執行。也就是說 Redis 事務不保證原子性。
在事務執行過程中,其他客戶端提交的命令請求不會插入到事務執行命令序列中。
一個事務從開始到執行會經歷以下三個階段:
開始事務。
命令入隊。
執行事務。
實例
以下是一個事務的例子, 它先以 MULTI 開始一個事務, 然后將多個命令入隊到事務中, 最后由 EXEC 命令觸發事務, 一并執行事務中的所有命令:
redis 127.0.0.1:6379> MULTI OK redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days" QUEUED redis 127.0.0.1:6379> GET book-name QUEUED redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series" QUEUED redis 127.0.0.1:6379> SMEMBERS tag QUEUED redis 127.0.0.1:6379> EXEC 1) OK 2) "Mastering C++ in 21 days" 3) (integer) 3 4) 1) "Mastering Series" 2) "C++" 3) "Programming"
單個 Redis 命令的執行是原子性的,但 Redis 沒有在事務上增加任何維持原子性的機制,所以 Redis 事務的執行并不是原子性的。
事務可以理解為一個打包的批量執行腳本,但批量指令并非原子化的操作,中間某條指令的失敗不會導致前面已做指令的回滾,也不會造成后續的指令不做。
這是官網上的說明 From redis docs on transactions:
It's important to note that even when a command fails, all the other commands in the queue are processed – Redis will not stop the processing of commands.
比如:
redis 127.0.0.1:7000> multi OK redis 127.0.0.1:7000> set a aaa QUEUED redis 127.0.0.1:7000> set b bbb QUEUED redis 127.0.0.1:7000> set c ccc QUEUED redis 127.0.0.1:7000> exec 1) OK 2) OK 3) OK
如果在 set b bbb 處失敗,set a 已成功不會回滾,set c 還會繼續執行。
Redis 事務命令
下表列出了 redis 事務的相關命令:
序號命令及描述:
1. DISCARD 取消事務,放棄執行事務塊內的所有命令。
2. EXEC 執行所有事務塊內的命令。
3. MULTI 標記一個事務塊的開始。
4. UNWATCH 取消 WATCH 命令對所有 key 的監視。
5. WATCH key [key …]監視一個 (或多個) key ,如果在事務執行之前這個 (或這些) key 被其他命令所改動,那么事務將被打斷。
持久化
Redis 是內存型數據庫,為了保證數據在斷電后不會丟失,需要將內存中的數據持久化到硬盤上。
RDB 持久化
將某個時間點的所有數據都存放到硬盤上。
可以將快照復制到其他服務器從而創建具有相同數據的服務器副本。
如果系統發生故障,將會丟失最后一次創建快照之后的數據。
如果數據量大,保存快照的時間會很長。
AOF 持久化
將寫命令添加到 AOF 文件(append only file)末尾。
使用 AOF 持久化需要設置同步選項,從而確保寫命令同步到磁盤文件上的時機。
這是因為對文件進行寫入并不會馬上將內容同步到磁盤上,而是先存儲到緩沖區,然后由操作系統決定什么時候同步到磁盤。
選項同步頻率always每個寫命令都同步eyerysec每秒同步一次no讓操作系統來決定何時同步
always 選項會嚴重減低服務器的性能
everysec 選項比較合適,可以保證系統崩潰時只會丟失一秒左右的數據,并且 Redis 每秒執行一次同步對服務器幾乎沒有任何影響。
no 選項并不能給服務器性能帶來多大的提升,而且會增加系統崩潰時數據丟失的數量。
隨著服務器寫請求的增多,AOF 文件會越來越大。Redis 提供了一種將 AOF 重寫的特性,能夠去除 AOF 文件中的冗余寫命令。
復制
通過使用 slaveof host port 命令來讓一個服務器成為另一個服務器的從服務器。
一個從服務器只能有一個主服務器,并且不支持主主復制。
連接過程
主服務器創建快照文件,即 RDB 文件,發送給從服務器,并在發送期間使用緩沖區記錄執行的寫命令。
快照文件發送完畢之后,開始像從服務器發送存儲在緩沖區的寫命令。
從服務器丟棄所有舊數據,載入主服務器發來的快照文件,之后從服務器開始接受主服務器發來的寫命令。
主服務器每執行一次寫命令,就向從服務器發送相同的寫命令。
主從鏈
隨著負載不斷上升,主服務器無法很快的更新所有從服務器,或者重新連接和重新同步從服務器將導致系統超載。
為了解決這個問題,可以創建一個中間層來分擔主服務器的復制工作。中間層的服務器是最上層服務器的從服務器,又是最下層服務器的主服務器。
哨兵
Sentinel(哨兵)可以監聽集群中的服務器,并在主服務器進入下線狀態時,自動從從服務器中選舉處新的主服務器。
分片
分片是將數據劃分為多個部分的方法,可以將數據存儲到多臺機器里面,這種方法在解決某些問題時可以獲得線性級別的性能提升。
假設有 4 個 Redis 實例 R0, R1, R2, R3, 還有很多表示用戶的鍵 user:1, user:2, … , 有不同的方式來選擇一個指定的鍵存儲在哪個實例中。
最簡單的是范圍分片,例如用戶 id 從 0 ~ 1000 的存儲到實例 R0 中,用戶 id 從 1001 ~ 2000 的存儲到實例 R1中,等等。但是這樣需要維護一張映射范圍表,維護操作代價高。
還有一種是哈希分片。使用 CRC32 哈希函數將鍵轉換為一個數字,再對實例數量求模就能知道存儲的實例。
根據執行分片的位置,可以分為三種分片方式:
客戶端分片:客戶端使用一致性哈希等算法決定應當分布到哪個節點。
代理分片:將客戶端的請求發送到代理上,由代理轉發到正確的節點上。
服務器分片:Redis Cluster。
關于“Redis全面知識點有哪些”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Redis全面知識點有哪些”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。