1. 程式人生 > >redis基本概念與操作

redis基本概念與操作

一.Redis入門

1. 什麼是Redis呢?

Redis 是一個開源軟體擁有( Berkly Software Distribution 許可 ),它是一個 記憶體資料結構存貯,通常被用於 資料庫 , 快取 , 訊息代理。 。 它支援: 字串 , 雜湊 , 列表 , 集合 , 陣列集合 , 點陣圖 , 高壓縮演算法以及地圖索引等資料結構。Redis 支援叢集,lua 指令碼,以及 LRU(近期最少使用 Least Recently Used )淘汰演算法,事物以及不同級別的 磁碟持久化,能夠提供一個高可用的 Redis Sentinel 的叢集方案。 從這段簡介中我們應該掌握一下幾點:

  1. Redis 是把資料存放在記憶體當中,所以它的執行速度會非常快
  2. Redis 具有多種資料儲存結構
  3. Redis 具有持久化的功能Redis 具有持久化的功能
  4. Redis 上的資料可以設定過期
  5. Redis 支援叢集,而且可以自動切換
  6. 跨平臺 支援多種語言客戶端

Redis 用途:

快取(StackOverFlow),資料庫(微博),訊息中介軟體(佇列,微博), 簡訊驗證等等

2. Redis的安裝

2-1 下載並解壓
通過 xshell 建立連線,下載 redis 並執行解壓
通過 wget 命令 下載網路上對應節點資源
wget  http://download.redis.io/releases/redis-3.2.8.tar.gz
tar  zvxf  redis-3.2.8.tar.gz

在這裡插入圖片描述 在這裡插入圖片描述

2-2 解壓後執行編譯與安裝

注意:執行 make 命令前 果 如果 s centos 沒有 c gcc 環境在編譯與安裝期間會出錯原因是沒有 gcc 環境造成!過 安裝通過 m yum 安裝 Gcc

yum install gcc

在這裡插入圖片描述 在這裡插入圖片描述 在這裡插入圖片描述

2-3 刪除原始解壓檔案 重新解壓檔案 並進入加壓後文件夾下執行安裝

在這裡插入圖片描述 在這裡插入圖片描述 在這裡插入圖片描述

2-4 啟動redis服務

當 redis 檔案被成功編譯並安裝後,執行 redis 服務啟動,對於 redis 服務啟動有兩種方式

  • 方式一:當前操作視窗啟動( 此時啟動之後當前視窗無法再繼續其他操作 !!!) 在這裡插入圖片描述
  • 方式二:以後臺程序方式啟動 以後臺程序方式啟動 redis ,此時需要修改 redis.conf 配置檔案中 daemonize 預設屬性 no 修改為 yes 通過 vim 命令開啟 redis3.2.8 資料夾下 redis.conf 檔案 vim redis.conf
    在這裡插入圖片描述 在這裡插入圖片描述 修改後儲存並退出, 後臺啟動 redis 服務 在這裡插入圖片描述 通過 linux 客戶端連線 redis 服務 在 src 目錄執行命令 ./redis-cli 連線 redis 伺服器 在這裡插入圖片描述 至此,redis 環境搭建成功,並可以通過 redis 客戶端命令列操作 redis 伺服器啦!!!

3.key相關指令介紹

exists key 檢測指定 key 是否存在,返回 1 表示存在, 0 不存在 del key1 key2 … keyN 刪除給定 key,返回刪除 key 的數目, 0 表示給定 key 都不存在 type key 返回給定 key 值的型別。 返回 none 表示 key 不存在,string 字元型別, list 連結串列型別 set 無序集合型別… keys pattern 返回匹配指定模式的所有 key randomkey 返回從當前資料庫中隨機選擇的一個 key,如果當前資料庫是空的,返回空串 rename oldkey newkey 重新命名一個 key,如果 newkey 存在,將會被覆蓋,返回1 表示成功,0 失敗。可能是 oldkey 不存在或者和 newkey 相同。 renamenx oldkey newkey 同上,但是如果 newkey 存在返回失敗。 expire key seconds 為 key 指定過期時間, 單位是秒。 返回 1 成功, 0 表示key 已經設定過過期時間或者不存在。 ttl key 返回設定過過期時間 key 的剩餘過期秒數。 -1 表示 key 不存在或者未設定過期時間。 select db-index 通過索引選擇資料庫, 預設連線的資料庫是 0,預設資料庫數是16 個。 返回 1表示成功, 0 失敗。 move key db-index 將 key 從當前資料庫移動到指定資料庫。返回 1 表示成功。0 表示 key不存在或者已經在指定資料庫中。 在這裡插入圖片描述 在這裡插入圖片描述

二.Redis的五種基本資料型別(重要)

redis 提供五種資料型別: string,hash,list,set 及sorted set

1. String 型別

1-1 概述

string 是最基本的型別,而且 string 型別是二進位制安全的。意思是 redis 的string 可以包含任何資料。比如 jpg 圖片或者序列化的物件。從內部實現來看其實string 可以看作 byte 組,最大上限是 1G 位元組。1G=1024MB

1-2 基本操作指令
  • set key value 設定 key 對應 string 型別的值, 返回 1 表示成功, 0 失敗。
  • setnx key value 如果 key 不存在, 設定 key 對應 string 型別的值。 如果key 已經存在,返回 0。
  • get key 獲取 key 對應的 string 值,如果 key 不存在返回 nil
  • getset key value 先獲取 key 的值,再設定 key 的值。如果 key 不存在返回 nil。
  • mget key1 key2 …keyN 一次獲取多個 key 的值,如果對應 key 不存在,則對應返回 nil。
  • mset key1 value1 …keyN valueN 一次設定多個 key 的值,成功返回 1表示所有的值都設定了,失敗返回 0 表示沒有任何值被設定。
  • msetnx key1 value1 …keyN valueN 一次設定多個 key 的值,但是不會覆蓋已經存在的 key
  • incr key 對 key 的值做++操作, 並返回新的值。 注意 incr 一個不是 int 的value 會返回錯誤, incr 一個不存在的 key,則設定 key 值為 1。
  • decr key 對 key 的值做–操作, decr 一個不存在 key,則設定 key 值為-1。
  • incrby key integer 對 key 加上指定值 , key 不存在時候會設定 key,並認為原來的 value 是 0。
  • decrby key integer 對 key 減去指定值。decrby 完全是為了可讀性,我們完全可以通過 incrby 一個負值來實現同樣效果,反之一樣
1-3應用場景

String 是最常用的一種資料型別,普通的 key/value 儲存都可以歸為此類,value 其實不僅是 String,也可以是數字:比如想知道什麼時候封鎖一個 IP 地址(訪問超過幾次)。INCRBY 命令讓這些變得很容易,通過原子遞增保持計數。等等…

2. Hash 型別

2-1 Hash的基本指令操作
  • hset key field value 設定 hash field 為指定值,如果 key 不存在,則建立
  • hget key field 獲取指定的 hash field。
  • hmget key filed1…fieldN 獲取全部指定的 hash filed。
  • hmset key filed1 value1 …filedN valueN 同時設定hash的多個 field。
  • hincrby key field integer 將指定的 hash filed 加上指定值。成功返回 hashfiled 變更後的值。
  • hexists key field 檢測指定 field 是否存在。
  • hdel key field 刪除指定的 hash field。
  • hlen key 返回指定 hash 的 field 數量
  • hkeys key 返回 hash 的所有 field。
  • hvals key 返回 hash 的所有 value。
  • hgetall key 返回 hash 的所有 filed 和 value。 在這裡插入圖片描述 在這裡插入圖片描述
2-2 應用場景

我們簡單舉個例項來描述下 Hash 的應用場景,比如我們要儲存一個使用者資訊物件資料,包 含以下資訊:

  • 使用者 ID,為查詢的 key,儲存的 value 使用者物件包含姓名 name,年齡 age,生日 birthday 等資訊,如果用普通的 key/value 結構來儲存,主要有以下 2 種儲存方式:

    • 第一種方式將使用者ID作為查詢key,把其他資訊封裝成一個物件以序列化的方式儲存, 如:set u001 “李三,18,20010101” 這種方式的缺點是,增加了序列化/反序列化的開銷,並且在需要修改其中一項資訊時,需要把整個物件取回,並且修改操作需要對併發進行保護,引入 CAS 等複雜問題。

    • 第二種方法是這個使用者資訊物件有多少成員就存成多少個 key-value 對兒,用使用者 ID+對應屬性的名稱作為唯一標識來取得對應屬性的值,如:

      mset user:001:name "李三" user:001:age 18  
      user:001:birthday "20010101"
      
  • 雖然省去了序列化開銷和併發問題,但是使用者 ID 為重複儲存,如果存在大量這樣的資料,記憶體浪費還是非常可觀的。那麼 Redis 提供的 Hash 很好的解決了這個問題,Redis 的 Hash 實際是內部儲存的Value 為一個 HashMap,並提供了直接存取這個 Map 成員的介面, 如:

    hmset user:001 name "李三" age 18 birthday "20010101"
    

也就是說,Key 仍然是使用者 ID,value 是一個 Map,這個 Map 的 key 是成員的屬性名,value 是屬性值,這樣對資料的修改和存取都可以直接通過其內部 Map 的 Key(Redis 裡稱內部 Map 的 key 為 field), 也就是通過key(使用者 ID) + field(屬性標籤) 操作對應屬性資料了,既不需要重複儲存資料,也不會帶來序列化和併發修改控制的問題。很好的解決了問題。這裡同時需要注意,Redis 提供了介面(hgetall)可以直接取到全部的屬性資料,但是如果內部 Map 的成員很多,那麼涉及到遍歷整個內部 Map 的操作,由於 Redis 單執行緒模型的緣故,這個遍歷操作可能會比較耗時,而另其它客戶端的請求完全不響應,這點需要格外注意。

  • 實現方式:上面已經說到 Redis Hash 對應 Value 內部實際就是一個 HashMap,實際這裡會有2 種不同實現,這個 Hash 的成員比較少時 Redis 為了節省記憶體會採用類似一維陣列的方式來緊湊儲存,而不會採用真正的 HashMap 結構,對應的 value redisObject 的encoding 為 zipmap,當成員數量增大時會自動轉成真正的 HashMap。

3. List 型別

3-1 List的基本操作指令
  • lpush key string 在 key 對應 list 的頭部新增字串元素,返回 1 表示成功, 0表示 key 存在且不是 list 型別。
  • rpush key string 在 key 對應 list 的尾部新增字串元素。
  • llen key 返回 key 對應 list 的長度, 如果 key 不存在返回 0, 如果 key 對應型別不是 list 返回錯誤。
  • lrange key start end 返回指定區間內的元素, 下標從 0 開始, 負值表示從後面計算, -1 表示倒數第一個元素 , key 不存在返回空列表。
  • ltrim key start end 擷取 list 指定區間內元素,成功返回 1, key 不存在返回錯誤。
  • lset key indexvalue 設定 list 中指定下標的元素值,成功返回 1, key 或者下標不存在返回錯誤。
  • lrem key count value 從 List 的頭部 ( count 正數)或尾部 ( count 負數)刪除一定數量 ( count)匹配 value 的元素,返回刪除的元素數量。 count 為 0時候刪除全部。例子:適合刪除重複的值如: 1 1 1 1 1 1 1 , lrem test 3 1b這樣會刪掉3個1
  • lpop key 從 list 的頭部刪除並返回刪除元素。如果 key 對應 list 不存在或者是空返回 nil,如果 key 對應值不是 list 返回錯誤。
  • rpop key 從 list 的尾部刪除並返回刪除元素。
  • blpop key1 …keyN timeout 從左到右掃描,返回對第一個非空 list 進行
  • lpop 操作並返回,比如 blpop list1 list2 list3 0 ,如果 list 不存在 list2,list3 都是非空則對 list2 做 lpop 並返回從 list2 中刪除的元素。如果所有的 list 都是空或不存在,則會阻塞 timeout 秒, timeout 為 0 表示一直阻塞。當阻塞時,如果有 client 對 key1…keyN 中的任意 key 進行 push 操作, 則第一在這個 key 上被阻塞的 client 會立即返回。 如果超時發生, 則返回 nil。有點像unix 的 select 或者 poll。
  • brpop 同 blpop,一個是從頭部刪除一個是從尾部刪除 在這裡插入圖片描述 在這裡插入圖片描述
3-2 應用場景

在這裡插入圖片描述 Lists 的另一個應用就是佇列,可以利用 Lists 的 PUSH 操作,將任務存在 List 中,然後工作執行緒再用 POP 操作將任務取出進行執行。 實現方式: Redis list 的實現為一個雙向連結串列,即可以支援反向查詢和遍歷,更方便操作,不過帶來了部分額外的記憶體開銷,Redis 內部的很多實現,包括髮送緩衝佇列等也都是用的這個資料結構。

4. Set 型別

4-1 概述

無序集合,最大可以包含(2 的 32 次方-1)個元素。 set 的是通過 hashtable ( HashMap: 執行緒不安全,效率高. 允許 key 或 value 為 null HashTable:執行緒安全,效率低. 不允許 key 或 value 為 null)實現的,所以新增, 刪除, 查詢的複雜度都是 O(1)。 hash table 會隨著新增或者刪除自動的調整大小。需要注意的是調整 hashtable 大小時候需要同步(獲取寫鎖)會阻塞其他讀寫操作。可能不久後就會改用跳錶( skip list)來實現。 跳錶已經在 sortedsets 中使用了。關於 set 集合型別除了基本的新增刪除操作, 其它有用的操作還包含集合的取並集(union), 交集(intersection),差集(difference)。通過這些操作可以很容易的實現 SNS 中的好友推薦和 blog 的 tag 功能

4-2 Set基本操作指令
  • sadd key member 新增一個 string 元素到 key 對應 set 集合中,成功返回 1,如果元素以及在集合中則返回 0, key 對應的 set 不存在則返回錯誤。
  • srem key member 從 key 對應 set 中移除指定元素,成功返回 1,如果 member在集合中不存在或者 key 不存在返回 0,如果 key 對應的不是 set 型別的值返回錯誤。
  • spop key 刪除並返回 key 對應 set 中隨機的一個元素,如果 set 是空或者 key不存在返回 nil。
  • srandmember key 同 spop,隨機取 set 中的一個元素,但是不刪除元素。
  • smove srckey dstkey member 從 srckey 對應 set 中移除 member 並新增到
  • stkey 對應 set 中,整個操作是原子的。 成功返回 1,如果 member 在 srckey 中不存在返回 0, 如果 key 不是 set 型別返回錯誤。
  • scard key 返回 set 的元素個數,如果 set 是空或者 key 不存在返回 0。
  • sismember key member 判斷 member 是否在 set 中,存在返回 1, 0 表示不存在或者 key 不存在。
  • sinter key1 key2 …… keyN 返回所有給定 key 的交集。
  • sinterstore dstkey key1 … keyN 返回所有給定 key 的交集, 並儲存交集存到 dstkey 下。(關鍵詞不區分大小寫的)
  • sunion key1 key2 … keyN 返回所有給定 key 的並集。
  • sunionstore dstkey key1 …keyN 返回所有給定 key 的並集, 並儲存並集到 dstkey 下。
  • sdiff key1 key2 …keyN 返回所有給定 key 的差集。
  • sdiffstore dstkey key1 …keyN 返回所有給定 key 的差集,並儲存差集到 dstkey 下。
  • smembers key 返回 key 對應 set 的所有元素,結果是無序的。 在這裡插入圖片描述
4-3 應用場景

Redis set 對外提供的功能與 list 類似是一個列表的功能,特殊之處在於 set 是可以自動排重的,當你需要儲存一個列表資料,又不希望出現重複資料時,set 是一個很好的選擇,並且 set 提供了判斷某個成員是否在一個 set 集合內的重要介面,這個也是 list所不能提供的。 比如在微博應用中,每個人的好友存在一個集合(set)中,這樣求兩個人的共同好友的操作,可能就只需要用求交集命令即可。 (新浪微博關注共同好友)Redis 還為集合提供了求交集、並集、差集等操作。 實現方式:set 的內部實現是一個 value 永遠為 null 的 HashMap,實際就是通過計hash的方式來快速排重的, 這也是set能提供判斷一個成員是否在集合內的原因

5. Sorted Set 型別

5-1 概述

Sorted Set 是有序集合, 它在 set 的基礎上增加了一個順序屬性,這一屬性在新增修改元素的時候可以指定, 每次指定後, 會自動重新按新的值調整順序。 可以理解了有兩列的 mysql 表,一列存 value,一列存順序。操作中 key 理解為sorted set 的名字,最多包含 2>32-1 個元素

5-2 基本操作指令
  • zadd key score member 新增元素到集合,元素在集合中存在則更新對應 score。
  • zrem key member 刪除指定元素, 1 表示成功,如果元素不存在返回 0。
  • zincrby key incrmember 增加對應 member 的 score 值, 然後移動元素並保持 skip list 保持有序。返回更新後的 score 值。
  • zrank key member 返回指定元素在集合中的排名(下標), 集合中元素是按 score從小到大排序的。
  • zrevrankkey member 同上,但是集合中元素是按 score 從大到小排序。
  • zrange key start end 類似 lrange 操作從集合中去指定區間的元素。返回的是有序結果
  • zrevrange key start end 同上,返回結果是按 score 逆序的。
  • zrangebyscore key min max 返回集合中 score 在給定區間的元素。(裡面的區間為閉區間[])
  • zcount key min max 返回集合中 score 在給定區間的數量。
  • zcard key 返回集合中元素個數。
  • zscore key element 返回給定元素對應的 score
5-3 應用場景

以某個條件為權重,比如按頂的次數排序. ZREVRANGE 命令可以用來按照得分來獲取前 100 名的使用者,ZRANK 可以用來獲取使用者排名,非常直接而且操作容易。 Redis sorted set 的使用場景與 set 類似,區別是 set 不是自動有序的,而 sortedset 可以通過使用者額外提供一個優先順序(score)的引數來為成員排序,並且是插入有序的,即自動排序。

比如:twitter 的 public timeline 可以以發表時間作為 score 來儲存,這樣獲取時就是自動按時間排好序的。
比如:全班同學成績的 SortedSets,value 可以是同學的學號,而 score 就可以是其考試得分,這樣資料插入集合的,就已經進行了天然的排序。
比如網易雲音樂排行榜實現;

另外還可以用 Sorted Sets 來做帶權重的佇列

比如普通訊息的 score 為 1,重要訊息的 score 為 2,然後工作執行緒可以選擇按 score 的倒序來獲取工作任務。讓重要的任務優先執行。

需要精準設定過期時間的應用

比如你可以把上面說到的 sorted set 的 score 值設定成過期時間的時間戳,那麼就可以簡單地通過過期時間排序,定時清除過期資料了,
不僅是清除 Redis 中的過期資料,你完全可以把 Redis 裡這個過期時間當成是對資料庫中資料的索引,用 Redis 來找出哪些資料
需要過期刪除,然後再精準地從資料庫中刪除相應的記錄