Redis基礎你掌握多少了?來查漏補缺?

FrancisQ發表於2019-11-08

Redis 是什麼

Redis開源記憶體 中的資料結構儲存系統,它可以用作資料庫快取訊息中介軟體。它支援多種型別的資料結構,如 字串strings雜湊 hashes列表 lists集合 sets有序集合 sorted sets 與範圍查詢, bitmaps, hyperloglogs 和 地理空間(geospatial) 索引半徑查詢。

Redis 還內建了 複製(replication),LUA指令碼(Lua scripting), LRU驅動事件(LRU eviction),事務(transactions) 和不同級別的 磁碟持久化(persistence), 並通過 Redis哨兵(Sentinel)和自動 分割槽(Cluster)提供高可用性(high availability)。

嗯,沒錯這就是 redis 中文官方網站上面的介紹,簡潔明瞭。

NoSQL 是什麼

我們知道 redis 是一種非關係型資料庫 NoSQL 。而為什麼出現 NoSQLNoSQL 又是什麼呢?

單機資料庫的年代

在一個網站訪問量不大的時候,我們使用一個資料庫就足以應對流量請求。

Redis基礎你掌握多少了?來查漏補缺?

快取 + 拆分

隨著訪問量的上升,一個資料庫已經不能滿足我們的需求了。為了更高的效能,我們在中間加上了一個快取層並且將資料庫做了叢集、結構優化和讀寫分離。

Redis基礎你掌握多少了?來查漏補缺?

而這裡的快取就是 NoSQL,當然做快取也只是 NoSQL 的一種功能,就像 Redis 並不僅僅有快取這一種功能。比如它還能實現 簡單的訊息佇列解決Session共享計數器排行榜好友關係處理 等等功能,可見 Redis 是一個非常強大工具,讓我們來學習它吧!

Redis 通用命令

首先我們拋開資料型別來講關於 Redis 的通用命令。

Redis基礎你掌握多少了?來查漏補缺?

操作 key 和 value

Redis 是一種 key value 儲存的快取資料庫,所有的資料都有一個自己唯一的key。

這裡為了方便演示,我使用了字串相關的設定命令

  • keys [pattern] 獲取符合要求的所有key。時間複雜度為 O(n),一般在生產環境中不使用,因為 Redis單執行緒的,執行耗時的任務會阻塞其他任務。一般會使用 scan 命令替代(非阻塞)。

Redis基礎你掌握多少了?來查漏補缺?

  • dbsize 獲取當前儲存資料個數。
  • exists key 判斷是否存在該key
  • del key 刪除指定資料
  • type key 獲取指定key的資料型別
  • rename key newkey 重新命名

Redis基礎你掌握多少了?來查漏補缺?

過期時間

Redis 中很多資料都是用來作為快取資料的,而作為快取就需要有過期時間,在 Redis 中提供了很強大的過期時間設定功能。

  • expire key seconds 為某個 key 設定過期時間。
  • ttl key 檢視某個 key 的剩餘時間,返回正數代表剩餘的時間,-1代表永久,-2代表已過期或不存在。

Redis基礎你掌握多少了?來查漏補缺?

Redis 的五種基本資料型別

在上面我說到了很多 Redis 作為快取能實現的其他功能,比如計數器,排行榜,好友關係等,這些實現的依據就是靠著 Redis 的資料結構。在整個 Redis 中一共有五種基本的資料結構(還有些高階資料結構以後會講),他們分別是 字串strings雜湊 hashes列表 lists集合 sets有序集合 sorted sets

字串 string

在絕大部分程式語言中都有 String 字串型別,對於作為資料庫的 Redis 也是必不可少的。

Redis基礎你掌握多少了?來查漏補缺?

  • set key value 設定值
  • get key 獲取某個key的值
  • mset key1 value1 key2 value2 批量設定並且是原子的,可以用來減少網路時間消耗
  • mget key1 key2 批量獲取並且是原子的,可以用來減少網路時間消耗
    Redis基礎你掌握多少了?來查漏補缺?
  • incr key 自增指定key的值
  • decr key 自減指定key的值
  • incrby key value 自增指定數值
  • decrby key value 自減指定數值
  • incrbyfloat key floatvalue 增加指定浮點數 前面幾個操作就可以用來實現計數器的功能。
    Redis基礎你掌握多少了?來查漏補缺?
  • setnx key value 如果不存在該key則可以設定成功,否則會失敗,加上過期時間限制,則是redis實現分散式鎖的一種方式(後面會提到)
  • set key value xx 與前面相反,如果存在則設定成功,否則失敗(相當於更新操作)
    Redis基礎你掌握多少了?來查漏補缺?
  • getset key newvalue 設定新值並返回舊值
  • append key value 為原本內容追加內容
  • strlen key 獲取字串長度
  • getrange key start end 獲取指定範圍的內容
  • setrange key index value 設定指定範圍的內容
    Redis基礎你掌握多少了?來查漏補缺?
  • setex key seconds value 設定值且設定過期時間
  • set key value ex seconds nx 為不存在的key設定值且設定過期時間,分散式鎖的實現方式
    Redis基礎你掌握多少了?來查漏補缺?

hash

Redis基礎你掌握多少了?來查漏補缺?

其實我們可以理解 hash小型RedisRedis 在底層實現上和 Java 中的 HashMap 差不多,都是使用 陣列 + 連結串列 的二維結構實現的。

Redis基礎你掌握多少了?來查漏補缺?

不同的是,在 Redis 中字典的值只能是字串,而且他們 rehash 的方式不一樣,在 Redis 中使用的是 漸進式rehash

在 rehash 的時候會保留新舊兩個 hash 字典,在資料遷移的時候會將舊字典中的內容一點一點遷移到新字典中,查詢的同時會查詢兩個 hash 字典,等資料全部遷移完成才會將新字典代替就字典。

下面我們來看一下關於 hash 的基本操作。

  • hset key field value 設定字典中某個key的值
  • hsetnx key field value 設定字典中某個key的值(不存在的)
  • hmset key field1 value1 field2 value2 ... 批量設定
  • hget key field 獲取字典中某個key的值
  • hmget key field1 field2 批量獲取
  • hgetall key 獲取全部
    Redis基礎你掌握多少了?來查漏補缺?
  • hdel key field 刪除某個key
  • hexists key field 判斷是否存在
  • hlen key 獲取指定key對應的字典中的儲存個數
  • hvals key 返回所有的value
  • hkeys key 返回所有的key
    Redis基礎你掌握多少了?來查漏補缺?
  • hincrby key field increValue 增加某個value的值(也可以增加負數)
  • hincrbyfloat key field floatValue 增加某個value的值(浮點數)
    Redis基礎你掌握多少了?來查漏補缺?

list

Redis 中的列表相當於 Java 中的 LinkedList(雙向連結串列) ,也就是底層是通過 連結串列 來實現的,所以對於 list 來說 插入刪除操作很快,但 索引定位非常慢

Redis基礎你掌握多少了?來查漏補缺?

Redis 提供了許多對於 list 的操作,如等操作,你可以充分利用它們來實現一個 或者 佇列

Redis基礎你掌握多少了?來查漏補缺?

下面我們來看一下關於 list 的基本操作。

  • lpush key item1 item2 item3... 從左入棧
  • rpush key item1 item2 item3... 從右入棧
  • lpop key 從左出棧
  • rpop key 從右出棧
  • lindex key index 獲取指定索引的元素 O(n)謹慎使用
  • lrange key start end 獲取指定範圍的元素 O(n)謹慎使用
    Redis基礎你掌握多少了?來查漏補缺?
  • linsert key before|after item newitem 在指定元素的前面或者後面新增新元素
  • lrem key count value 刪除指定個數值為value的元素
    • count = 0 :刪除所有值為value的元素
    • count > 0 :從左到右刪除 count 個值為 value 的元素
    • count < 0 :從右到做刪除 |count| 個值為 value 的元素
  • ltrim key start end 保留指定範圍的元素
  • lset key index newValue 更新某個索引的值
    Redis基礎你掌握多少了?來查漏補缺?
  • blpop key timeout 沒有則阻塞(timeout指定阻塞時間 為0代表永久)
  • brpop key timeout 沒有則阻塞(timeout指定阻塞時間 為0代表永久) 這兩個可以用來實現消費者生產者
    Redis基礎你掌握多少了?來查漏補缺?

總結來說我們可以使用 左入又出或者右入左出 來實現佇列,左入左出或者右入右出 來實現棧

  • lpush + lpop = Stack
  • rpush + rpop = Stack**
  • lpush + rpop = Queue
  • rpush + lpop = Queue
  • lpush/rpush + ltrim = Capped List (定長列表)
  • lpush + brpop = Message Queue (訊息佇列)
  • rpush + blpop = Message Queue (訊息佇列)

set

Redis 中的 set 相當於 Java 中的 HashSet(無序集合),其中裡面的元素不可以重複,我們可以利用它實現一些去重的功能。我們還有對幾個集合進行取交集取並集等操作,這些操作就可以獲取不同使用者之間的共同好友,共同愛好等等。

Redis基礎你掌握多少了?來查漏補缺?

下面我們就來看一下關於 set 的一些基本操作。

  • sadd key value 新增元素
  • sdel key value 刪除某個元素
  • sismember key value 判斷是否是集合中的元素
  • srandmember key count 隨機獲取指定個數的元素(不會影響集合結構)
  • spop key count 從集合中隨機彈出元素(會破壞結合結構)
  • smembers key 獲取集合所有元素 O(n)複雜度
  • scard key 獲取集合個數
    Redis基礎你掌握多少了?來查漏補缺?
  • sinter set1 set2 ... 獲取所有集合中的交集
  • sdiff set1 set2 ... 獲取所有集合中的差集
  • sunion set1 set2 ... 獲取所有集合中的並集
    Redis基礎你掌握多少了?來查漏補缺?

zset

Redis 中的 zset 是一個 有序集合,通過它可以實現很多有意思的功能,比如學生成績排行榜,視訊播放量排行榜等等。

Redis基礎你掌握多少了?來查漏補缺?

zset 中是使用 跳錶 來實現的,我們知道只有陣列這種連續的空間才能使用二分查詢進行快速的定位,而連結串列是不可以的。跳錶幫助連結串列查詢的時候節省了很多時間(使用跳的方式來遍歷索引來進行有序插入),如果不瞭解跳錶的同學可以補習一下。

Redis基礎你掌握多少了?來查漏補缺?

下面我們來看一下關於 zset 的一些基本操作。

  • zadd key score element 新增,score用於排序,value需要唯一,由於使用的跳錶,時間複雜度為 O(logn)。
  • zrem key element 刪除某元素 O(1)時間複雜度
  • zscore key element 獲取某個元素的分數
  • zincrby key incrScore element 增加某個元素的分數
  • zrange key start end [withscores] 獲取指定索引範圍的元素 加上withscores則返回分數 O(logn + m)時間複雜度
  • zrangebyscore key minScore maxScore [withscores] 獲取指定分數範圍的元素 加上withscores則返回分數,O(logn + m)時間複雜度
  • zcard key 獲取有序集合長度
    Redis基礎你掌握多少了?來查漏補缺?

Redis 中的事務和管道

管道 Pipeline

在某些場景下我們在一次操作中可能需要執行多個命令,而如果我們只是一個命令一個命令去執行則會浪費很多網路消耗時間,如果將命令一次性傳輸到 Redis 中去再執行,則會減少很多開銷時間。 但是需要注意的是 pipeline 中的命令並不是原子性執行的,也就是說管道中的命令到達 Redis 伺服器的時候可能會被其他的命令穿插。

Redis基礎你掌握多少了?來查漏補缺?

Redis基礎你掌握多少了?來查漏補缺?

事務

關係型資料庫具有 ACID 特性,Redis 能保證A(原子性)和I(隔離性),D(永續性)看是否有配置 RDB或者 AOF 持久化操作,但無法保證一致性,因為 Redis 事務不支援回滾

我們可以簡單理解為 Redis 中的事務只是比 Pipeline 多了個原子性操作,也就是不會被其他命令給分割,如上圖。

  • multi 事務開始的標誌

  • exec 事務執行

    Redis基礎你掌握多少了?來查漏補缺?

  • discard 清除在這個事務中放入佇列的所有命令,即解除整個事務。

  • watch key 在事務開始前監控某個元素,如果在提交事務的時候發現這個元素的值被其他客戶端更改了則事務會執行失敗。

  • unwatch key 解除監控

    Redis基礎你掌握多少了?來查漏補缺?

Redis常用命令總結

Redis基礎你掌握多少了?來查漏補缺?

好了,這就是這篇文章全部的內容了,對於 Redis 你還有多少遺忘的或者沒學習到的呢?

如果文章對你有幫助的話,請給我點個贊哦(#^.^#)

關於 Redis 的文章接下來還會再寫,如果感興趣可以關注我(#^.^#)。

相關文章