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

Redis 是什麼

Redis開源內存 中的數據結構存儲系統,它能夠用做數據庫緩存消息中間件。它支持多種類型的數據結構,如 字符串strings散列 hashes列表 lists集合 sets有序集合 sorted sets 與範圍查詢, bitmaps, hyperloglogs 和 地理空間(geospatial) 索引半徑查詢。redis

Redis 還內置了 複製(replication),LUA腳本(Lua scripting), LRU驅動事件(LRU eviction),事務(transactions) 和不一樣級別的 磁盤持久化(persistence), 並經過 Redis哨兵(Sentinel)和自動 分區(Cluster)提供高可用性(high availability)。數據庫

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

NoSQL 是什麼

咱們知道 redis 是一種非關係型數據庫 NoSQL 。而爲何出現 NoSQLNoSQL 又是什麼呢?數組

單機數據庫的年代

在一個網站訪問量不大的時候,咱們使用一個數據庫就足以應對流量請求。 緩存

緩存 + 拆分

隨着訪問量的上升,一個數據庫已經不能知足咱們的需求了。爲了更高的性能,咱們在中間加上了一個緩存層而且將數據庫作了集羣、結構優化和讀寫分離。服務器

而這裏的緩存就是 NoSQL,固然作緩存也只是 NoSQL 的一種功能,就像 Redis 並不只僅有緩存這一種功能。好比它還能實現 簡單的消息隊列解決Session共享計數器排行榜好友關係處理 等等功能,可見 Redis 是一個很是強大工具,讓咱們來學習它吧!網絡

Redis 通用命令

首先咱們拋開數據類型來說關於 Redis 的通用命令。數據結構

操做 key 和 value

Redis 是一種 key value 存儲的緩存數據庫,全部的數據都有一個本身惟一的key。app

這裏爲了方便演示,我使用了字符串相關的設置命令 編程語言

  • keys [pattern] 獲取符合要求的全部key。時間複雜度爲 O(n),通常在生產環境中不使用,由於 Redis單線程的,執行耗時的任務會阻塞其餘任務。通常會使用 scan 命令替代(非阻塞)。

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

過時時間

Redis 中不少數據都是用來做爲緩存數據的,而做爲緩存就須要有過時時間,在 Redis 中提供了很強大的過時時間設置功能。

  • expire key seconds 爲某個 key 設置過時時間。
  • ttl key 查看某個 key 的剩餘時間,返回正數表明剩餘的時間,-1表明永久,-2表明已過時或不存在。

Redis 的五種基本數據類型

在上面我說到了不少 Redis 做爲緩存能實現的其餘功能,好比計數器,排行榜,好友關係等,這些實現的依據就是靠着 Redis 的數據結構。在整個 Redis 中一共有五種基本的數據結構(還有些高級數據結構之後會講),他們分別是 字符串strings散列 hashes列表 lists集合 sets有序集合 sorted sets

字符串 string

在絕大部分編程語言中都有 String 字符串類型,對於做爲數據庫的 Redis 也是必不可少的。

  • set key value 設置值
  • get key 獲取某個key的值
  • mset key1 value1 key2 value2 批量設置而且是原子的,能夠用來減小網絡時間消耗
  • mget key1 key2 批量獲取而且是原子的,能夠用來減小網絡時間消耗
  • incr key 自增指定key的值
  • decr key 自減指定key的值
  • incrby key value 自增指定數值
  • decrby key value 自減指定數值
  • incrbyfloat key floatvalue 增長指定浮點數 前面幾個操做就能夠用來實現計數器的功能。
  • setnx key value 若是不存在該key則能夠設置成功,不然會失敗,加上過時時間限制,則是redis實現分佈式鎖的一種方式(後面會提到)
  • set key value xx 與前面相反,若是存在則設置成功,不然失敗(至關於更新操做)
  • getset key newvalue 設置新值並返回舊值
  • append key value 爲本來內容追加內容
  • strlen key 獲取字符串長度
  • getrange key start end 獲取指定範圍的內容
  • setrange key index value 設置指定範圍的內容
  • setex key seconds value 設置值且設置過時時間
  • set key value ex seconds nx 爲不存在的key設置值且設置過時時間,分佈式鎖的實現方式

hash

其實咱們能夠理解 hash小型RedisRedis 在底層實現上和 Java 中的 HashMap 差很少,都是使用 數組 + 鏈表 的二維結構實現的。

不一樣的是,在 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 獲取所有
  • hdel key field 刪除某個key
  • hexists key field 判斷是否存在
  • hlen key 獲取指定key對應的字典中的存儲個數
  • hvals key 返回全部的value
  • hkeys key 返回全部的key
  • hincrby key field increValue 增長某個value的值(也能夠增長負數)
  • hincrbyfloat key field floatValue 增長某個value的值(浮點數)

list

Redis 中的列表至關於 Java 中的 LinkedList(雙向鏈表) ,也就是底層是經過 鏈表 來實現的,因此對於 list 來講 插入刪除操做很快,但 索引定位很是慢

Redis 提供了許多對於 list 的操做,如等操做,你能夠充分利用它們來實現一個 或者 隊列

下面咱們來看一下關於 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)謹慎使用
  • 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 更新某個索引的值
  • blpop key timeout 沒有則阻塞(timeout指定阻塞時間 爲0表明永久)
  • brpop key timeout 沒有則阻塞(timeout指定阻塞時間 爲0表明永久) 這兩個能夠用來實現消費者生產者

總結來講咱們可使用 左入又出或者右入左出 來實現隊列,左入左出或者右入右出 來實現棧

  • 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(無序集合),其中裏面的元素不能夠重複,咱們能夠利用它實現一些去重的功能。咱們還有對幾個集合進行取交集取並集等操做,這些操做就能夠獲取不一樣用戶之間的共同好友,共同愛好等等。

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

  • sadd key value 添加元素
  • sdel key value 刪除某個元素
  • sismember key value 判斷是不是集合中的元素
  • srandmember key count 隨機獲取指定個數的元素(不會影響集合結構)
  • spop key count 從集合中隨機彈出元素(會破壞結合結構)
  • smembers key 獲取集合全部元素 O(n)複雜度
  • scard key 獲取集合個數
  • sinter set1 set2 ... 獲取全部集合中的交集
  • sdiff set1 set2 ... 獲取全部集合中的差集
  • sunion set1 set2 ... 獲取全部集合中的並集

zset

Redis 中的 zset 是一個 有序集合,經過它能夠實現不少有意思的功能,好比學生成績排行榜,視頻播放量排行榜等等。

zset 中是使用 跳錶 來實現的,咱們知道只有數組這種連續的空間才能使用二分查找進行快速的定位,而鏈表是不能夠的。跳錶幫助鏈表查找的時候節省了不少時間(使用跳的方式來遍歷索引來進行有序插入),若是不瞭解跳錶的同窗能夠補習一下。

下面咱們來看一下關於 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 中的事務和管道

管道 Pipeline

在某些場景下咱們在一次操做中可能須要執行多個命令,而若是咱們只是一個命令一個命令去執行則會浪費不少網絡消耗時間,若是將命令一次性傳輸到 Redis 中去再執行,則會減小不少開銷時間。 可是須要注意的是 pipeline 中的命令並非原子性執行的,也就是說管道中的命令到達 Redis 服務器的時候可能會被其餘的命令穿插。

事務

關係型數據庫具備 ACID 特性,Redis 能保證A(原子性)和I(隔離性),D(持久性)看是否有配置 RDB或者 AOF 持久化操做,但沒法保證一致性,由於 Redis 事務不支持回滾

咱們能夠簡單理解爲 Redis 中的事務只是比 Pipeline 多了個原子性操做,也就是不會被其餘命令給分割,如上圖。

  • multi 事務開始的標誌

  • exec 事務執行

  • discard 清除在這個事務中放入隊列的全部命令,即解除整個事務。

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

  • unwatch key 解除監控

Redis經常使用命令總結

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

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

關於 Redis 的文章接下來還會再寫,若是感興趣能夠關注我(#^.^#)。

相關文章
相關標籤/搜索