Redis從入門到精通:中級篇

原文連接:http://www.cnblogs.com/xrq730/p/8944539.html,轉載請註明出處,謝謝html

 

本文目錄redis

上一篇文章以認識Redis爲主,寫了Redis系列的第一篇,如今開啓第二部分的學習,在本文中,咱們將看到如下內容:數據庫

  • Redis數據結構String、Hash、List、Set、SortedSet及相關操做,提一下Redis在3.2.0以後有新增了一種GEO的數據類型表示地理位置,不過本文這種數據結構略過
  • Redis其餘一些經常使用命令,分爲Key操做與服務器操做
  • Redis事務機制

主要以實戰爲主,但願經過本文可讓你們掌握Redis的基本使用。編程

原本這篇文章還準備加上Redis線程模型分析的,可是寫完發現篇幅實在太長,就把Redis線程模型放到最後一篇中了,也挺好的,本文專一於對Redis命令的講解。數組

另外說一下,本文講Redis中的數據結構,可是數據結構自己不在本文的講解範圍內,若是想知道Hash、List、Set等數據結構特色及使用場景,能夠本身查閱數據結構相關資料。服務器

 

String數據結構的基本操做數據結構

首先說一下數據結構String,這是Redis中最簡單的一種數據結構,和MemCache數據結構是同樣的,即Key-Value型的數據,根據Redis官方文檔,Value最大值爲512M異步

下面用表格來看一下String操做的相關命令:分佈式

命令 描述 用法
SET

(1)將字符串值Value關聯到Key工具

(2)Key已關聯則覆蓋,無視類型

(3)本來Key帶有生存時間TTL,那麼TTL被清除

SET key value [EX seconds] [PX milliseconds] [NX|XX]
GET

(1)返回key關聯的字符串值

(2)Key不存在返回nil

(3)Key存儲的不是字符串,返回錯誤,由於GET只用於處理字符串

GET key
MSET

(1)同時設置一個或多個Key-Value鍵值對

(2)某個給定Key已經存在,那麼MSET新值會覆蓋舊值

(3)若是上面的覆蓋不是但願的,那麼使用MSETNX命令,全部Key都不存在纔會進行覆蓋

(4)MSET是一個原子性操做,全部Key都會在同一時間被設置,不會存在有些更新有些沒更新的狀況

MSET key value [key value ...]
MGET

(1)返回一個或多個給定Key對應的Value

(2)某個Key不存在那麼這個Key返回nil

MGET key [key ...]
SETEX

(1)將Value關聯到Key

(2)設置Key生存時間爲seconds,單位爲秒

(3)若是Key對應的Value已經存在,則覆蓋舊值

(4)SET也能夠設置失效時間,可是不一樣在於SETNX是一個原子操做,即關聯值與設置生存時間同一時間完成

SETEX key seconds value
SETNX

(1)將Key的值設置爲Value,當且僅當Key不存在

(2)若給定的Key已經存在,SEXNX不作任何動做

SETNX key value

首先,演示一下SET、GET、SETEX的效果:

圖中咱們應該能看到SET、GET、SETNX幾個命令的效果了,在這以外,專門提兩點:

  • Redis的命令不區分大小寫
  • Redis的Key區分大小寫

接着咱們演示一下SETEX命令的效果:

這裏順帶介紹了TIME命令,它返回的是當前服務器Unix時間戳,但單位爲秒(一般Unix時間戳取的時間爲毫秒)。看到設置Redis-Expire這個Key,立刻獲取不失效,第26秒獲取的時候失效,關於失效,Redis的策略是這樣的:

  • 被動觸發,即GET的時候檢查一下Key是否失效
  • 主動觸發,後臺每1秒跑10次定時任務(經過redis.conf的hz參數配置,默認爲10,這個上文沒有寫),隨機選擇100個設置了過時時間的Key,對過時的Key進行失效

最後看一下MGET和MSET命令:

看到能夠同時設置多個Key-Value,也能夠同時獲取多個Key對應的Value,再次注意,Redis的Key是嚴格區分大小寫的。

 

特殊的String操做:INCR/DECR

前面介紹的是基本的Key-Value操做,下面介紹一種特殊的Key-Value操做即INCR/DECR,能夠利用Redis自動幫助咱們對一個Key對應的Value進行加減,用表格看一下相關命令:

命令 描述 用法
INCR

(1)Key中存儲的數字值+1,返回增長以後的值

(2)Key不存在,那麼Key的值被初始化爲0再執行INCR

(3)若是值包含錯誤類型或者字符串不能被表示爲數字,那麼返回錯誤

(4)值限制在64位有符號數字表示以內,即-9223372036854775808~9223372036854775807

INCR key
DECR

(1)Key中存儲的數字值-1

(2)其他同INCR

DECR key
INCRBY

(1)將key所存儲的值加上增量返回增長以後的值

(2)其他同INCR

INCRBY key increment
DECRBY

(1)將key所存儲的值減去減量decrement

(2)其他同INCR

DECRBY key decrement

下面實際看一下四個命令相關使用:

INCR/DECR在實際工做中仍是很是管用的,舉兩個例子:

  • 原先單機環境中統計在線人數,變成分佈式部署以後可使用INCR/DECR
  • 因爲Redis自己極高的讀寫性能,一些秒殺的場景庫存增減能夠基於Redis來作而不是直接操做DB

 

Hash數據結構相關操做

接着講一下Hash,Hash本質上和String是同樣的,無非String是純粹的Key-Value,Hash是外面套了一層東西,裏面仍是Key-Value,接着咱們用表格看一下Hash數據結構的相關命令:

命令 描述 用法
HSET

(1)將哈希表Key中的域field的值設爲value

(2)key不存在,一個新的Hash表被建立

(3)field已經存在,舊的值被覆蓋

HSET key field value
HGET (1)返回哈希表key中給定域field的值 HGET key field
HDEL

(1)刪除哈希表key中的一個或多個指定域

(2)不存在的域將被忽略

HDEL key filed [field ...]
HEXISTS (1)查看哈希表key中,給定域field是否存在,存在返回1,不存在返回0 HEXISTS key field
 HGETALL  (1)返回哈希表key中,全部的域和值  HGETALL key 
HINCRBY

 (1)爲哈希表key中的域field加上增量increment

(2)其他同INCR命令

HINCRYBY key filed increment 
HKEYS (1)返回哈希表key中的全部域  HKEYS key
HLEN (1)返回哈希表key中域的數量  HLEN key 
HMGET

(1)返回哈希表key中,一個或多個給定域的值

(2)若是給定的域不存在於哈希表,那麼返回一個nil值

HMGET key field [field ...]
HMSET

(1)同時將多個field-value對設置到哈希表key中

(2)會覆蓋哈希表中已存在的域

(3)key不存在,那麼一個空哈希表會被建立並執行HMSET操做

HMSET key field value [field value ...]
HVALS (1)返回哈希表key中全部的域和值 HVALS key

一樣的,實際看一下這些命令的相關使用:

稍亂,可是除了HMSET、HMGET之外把全部命令都演示到了。

 

List數據結構相關操做

接着咱們看一下Redis中的List,相關命令有:

命令 描述 用法
LPUSH

(1)將一個或多個值value插入到列表key的表頭

(2)若是有多個value值,那麼各個value值按從左到右的順序依次插入表頭

(3)key不存在,一個空列表會被建立並執行LPUSH操做

(4)key存在但不是列表類型,返回錯誤

LPUSH key value [value ...]
LPUSHX

(1)將值value插入到列表key的表頭,當且晉檔key存在且爲一個列表

(2)key不存在時,LPUSHX命令什麼都不作

LPUSHX key value
LPOP

(1)移除並返回列表key的頭元素

LPOP key
LRANGE

(1)返回列表key中指定區間內的元素,區間以偏移量start和stop指定

(2)start和stop都以0位底

(3)可以使用負數下標,-1表示列表最後一個元素,-2表示列表倒數第二個元素,以此類推

(4)start大於列表最大下標,返回空列表

(5)stop大於列表最大下標,stop=列表最大下標

LRANGE key start stop
LREM

(1)根據count的值,移除列表中與value相等的元素

(2)count>0表示從頭至尾搜索,移除與value相等的元素,數量爲count

(3)count<0表示從從尾到頭搜索,移除與value相等的元素,數量爲count

(4)count=0表示移除表中全部與value相等的元素

LREM key count value
LSET

(1)將列表key下標爲index的元素值設爲value

(2)index參數超出範圍,或對一個空列表進行LSET時,返回錯誤

LSET key index value
LINDEX

(1)返回列表key中,下標爲index的元素

LINDEX key index
LINSERT

(1)將值value插入列表key中,位於pivot前面或者後面

(2)pivot不存在於列表key時,不執行任何操做

(3)key不存在,不執行任何操做

LINSERT key BEFORE|AFTER pivot value
LLEN

(1)返回列表key的長度

(2)key不存在,返回0

LLEN key
LTRIM (1)對一個列表進行修剪,讓列表只返回指定區間內的元素,不存在指定區間內的都將被移除 LTRIM key start stop
RPOP (1)移除並返回列表key的尾元素 RPOP key
RPOPLPUSH

在一個原子時間內,執行兩個動做:

(1)將列表source中最後一個元素彈出並返回給客戶端

(2)將source彈出的元素插入到列表desination,做爲destination列表的頭元素

RPOPLPUSH source destination
RPUSH (1)將一個或多個值value插入到列表key的表尾 RPUSH key value [value ...]
RPUSHX

(1)將value插入到列表key的表尾,當且僅當key存在而且是一個列表

(2)key不存在,RPUSHX什麼都不作

RPUSHX key value

接着看一下這些命令的實際使用效果:

工具所限,LSET、LINSERT、RPOPLPUSH幾個命令無法演示,上面演示了其餘的基本命令,應該足以理解Redis的List了,操做List千萬注意區分LPUSH、RPUSH兩個命令,把數據添加到表頭和把數據添加到表尾是徹底不同的兩種結果

另外List還有BLPOP、BRPOP、BRPOPLPUSH三個命令沒有說,它們是幾個POP的阻塞版本,即沒有數據能夠彈出的時候將阻塞客戶端直到超時或者發現有能夠彈出的元素爲止

 

SET數據結構相關操做

接着咱們看一下SET數據結構的相關操做:

命令 描述 用法
SADD 

(1)將一個或多個member元素加入到key中,已存在在集合的member將被忽略

(2)假如key不存在,則只建立一個只包含member元素作成員的集合

(3)當key不是集合類型時,將返回一個錯誤 

SADD key number [member ...] 
SCARD   (1)返回key對應的集合中的元素數量  SCARD key
SDIFF  (1)返回一個集合的所有成員,該集合是第一個Key對應的集合和後面key對應的集合的差集  SDIFF key [key ...]
 SDIFFSTORE

(1)和SDIFF相似,但結果保存到destination集合而不是簡單返回結果集

(2) destination若是已存在,則覆蓋

SDIFFSTORE destionation key [key ...] 
 SINTER

 (1)返回一個集合的所有成員,該集合是全部給定集合的交集

(2)不存在的key被視爲空集

SINTER key [key ...] 
SINTERSTORE 

(1)和SINTER相似,但結果保存早destination集合而不是簡單返回結果集

(2)若是destination已存在,則覆蓋

(3)destination能夠是key自己

SINTERSTORE destination key [key ...] 
SISMEMBER  (1)判斷member元素是否key的成員,0表示不是,1表示是  SISMEMBER key member 
SMEMBERS

 (1)返回集合key中的全部成員

(2)不存在的key被視爲空集

SMEMBERS key 
SMOVE 

(1)原子性地將member元素從source集合移動到destination集合

(2)source集合中不包含member元素,SMOVE命令不執行任何操做,僅返回0

(3)destination中已包含member元素,SMOVE命令只是簡單作source集合的member元素移除

 SMOVE source desination member
SPOP

(1)移除並返回集合中的一個隨機元素,若是count不指定那麼隨機返回一個隨機元素

(2)count爲正數且小於集合元素數量,那麼返回一個count個元素的數組且數組中的元素各不相同

(3)count爲正數且大於等於集合元素數量,那麼返回整個集合

(4)count爲負數那麼命令返回一個數組,數組中的元素可能重複屢次,數量爲count的絕對值

SPOP key [count]
SRANDMEMBER

(1)若是count不指定,那麼返回集合中的一個隨機元素

(2)count同上

SRANDMEMBER key [count]
SREM (1)移除集合key中的一個或多個member元素,不存在的member將被忽略 SREM key member [member ...]
SUNION

(1)返回一個集合的所有成員,該集合是全部給定集合的並集

(2)不存在的key被視爲空集

SUNION key [key ...]
SUNIONSTORE

(1)相似SUNION,但結果保存到destination集合而不是簡單返回結果集

(2)destination已存在,覆蓋舊值

(3)destination能夠是key自己

SUNION destination key [key ...]

一樣,實際測試一下Set:

除了SINTER沒有用到,其餘應該比較全面地展現了Set的相關使用。

 

SortedSet數據結構相關操做

數據結構最後說一下SortedSet相關操做,最近有一個場景須要實現Redis分頁+高效移除數據,一會兒沒找到好的數據結構,後來想起了SortedSet才解決了問題,看來積累與儲備仍是很是有用的,

SortedSet顧名思義,即有序的Set,看下相關命令:

命令 描述 用法
ZADD

(1)將一個或多個member元素及其score值加入有序集key中

(2)若是member已是有序集的成員,那麼更新member對應的score並從新插入member保證member在正確的位置上

(3)score能夠是整數值或雙精度浮點數

ZADD key score member [[score member] [score member] ...]
ZCARD  (1)返回有序集key的元素個數 ZCARD key 
 ZCOUNT  (1) 返回有序集key中,score值>=min且<=max的成員的數量 ZCOUNT key min max 
ZRANGE 

 (1)返回有序集key中指定區間內的成員,成員位置按score從小到大排序

(2)具備相同score值的成員按字典序排列

(3)須要成員按score從大到小排列,使用ZREVRANGE命令

(4)下標參數start和stop都以0爲底,也能夠用負數,-1表示最後一個成員,-2表示倒數第二個成員

(5)可經過WITHSCORES選項讓成員和它的score值一併返回

ZRANGE key start stop [WITHSCORES] 
ZRANK

 (1)返回有序集key中成員member的排名,有序集成員按score值從小到大排列

(2)排名以0爲底,即score最小的成員排名爲0

(3)ZREVRANK命令可將成員按score值從大到小排名

ZRANK key number 
ZREM

(1)移除有序集key中的一個或多個成員,不存在的成員將被忽略

(2)當key存在但不是有序集時,返回錯誤 

ZREM key member [member ...] 
ZREMRANGEBYRANK (1)移除有序集key中指定排名區間內的全部成員  ZREMRANGEBYRANK key start stop 
ZREMRANGEBYSCORE (1)移除有序集key中,全部score值>=min且<=max之間的成員  ZREMRANGEBYSCORE key min max 

還有若干不是很經常使用的命令沒有寫,就略過了,有興趣的能夠本身看一下,接着看一下SortedSet實際使用: 

這個地方排名的時候稍微注意下,和咱們認爲的排名有些微區別,好比1 1 2 3,因爲有兩個1,所以3正序的Rank應當爲2(以0爲下標),但實際上會是3,因此Rank應當理解爲元素在集合中的下標位置更加準確

 

Redis的Key相關操做

寫完了Redis的數據結構,接着咱們看下Redis的Key相關操做:

命令 描述 用法
DEL

(1)刪除給定的一個或多個key

(2)不存在的Key將被忽略

DEL key [key ...]
EXISTS (1)檢查給定key是否存在 EXISTS key
EXPIRE

(1)爲給定key設置生存時間,key過時時它會被自動刪除

(2)對一個已經指定生存時間的Key設置執行EXPIRE,新的值會代替舊的值

EXPIRE key seconds
EXPIREAT (1)同EXPIRE,但此命令指定的是UNIX時間戳,單位爲秒 EXPIRE key timestamp
KEYS

(1)查找全部符合給定模式pattern的key,下面舉一下例子

(2)KEYS *匹配全部key

(3)KEYS h?llo匹配hello、hallo、hxllo等

(4)KEYS h*llo匹配hllo、heeeeello等

(5)KEYS h[ae]llo匹配hello和hallo

(6)特殊符號想當作查找內容經的使用\

KEYS pattern

MIGRATE 

 (1)原子性地將key從當前實例傳送到目標實例指定的數據庫上

(2)原數據庫Key刪除,新數據庫Key增長

(3)阻塞進行遷移的兩個實例,直到遷移成功、遷移失敗、等待超時三個之一發生

MIGRATE host port key destination-db timeout [COPY] [REPLACE] 

 MOVE

 (1)將當前數據庫的key移動到給定數據庫的db中

(2)執行成功的條件爲當前數據庫有key,給定數據庫沒有key

MOVE key db 
PERSIST   (1)移除給定key的生存時間,將key變爲持久的 PERSIST key
RANDOMKEY  (1)從當前數據庫隨機返回且不刪除一個key, RANDOMKEY 
RENAME

(1)將key更名爲newkey

(2)當key和newkey相同或key不存在,報錯

(3)newkey已存在,RENAME將覆蓋舊值

RENAME key newkey
TTL (1)以秒爲單位,返回給定的key剩餘生存時間 TTL key
PTTL (1)以毫秒爲單位,返回給定的key剩餘生存時間 PTTL key
TYPE (1)返回key鎖存儲的值的類型 TYPE key

簡單看一下實際使用:

這裏特別注意KEYS命令,雖然KEYS命令速度很是快,可是當Redis中百萬、千萬甚至過億數據的時候,掃描全部Redis的Key,速度仍然會降低,因爲Redis是單線程模型,這將致使後面的命令阻塞直到KEYS命令執行完。

所以當Redis中存儲的數據達到了必定量級(經驗值從10W開始就值得注意了)的時候,必須警戒KEYS形成Redis總體性能降低

 

系統相關命令

接着介紹一下部分系統相關命令:

命令 描述 用法
BGREWRITEAOF (1)手動觸發AOF重寫操做,用於減少AOF文件體積 BGREWRITEAOF
BGSAVE (1)後臺異步保存當前數據庫的數據到磁盤 BGSAVE
CLIENT KILL

(1)關閉地址爲ip:port的客戶端

(2)因爲Redis爲單線程設計,所以噹噹前命令執行完以後纔會關閉客戶端

CLIENT KILL ip:port
CLIENT LIST (1)以可讀的格式,返回全部鏈接到服務器的客戶端信息和統計數據 CLIENT LIST
CONFIG GET

(1)取得運行中的Redis服務器配置參數

(2)支持*

CONFIG GET parameter
CONFIG RESETSTAT (1)重置INFO命令中的某些統計數據,例如Keyspace hits、Keyspace misses等 CONFIG RESETSTAT
CONFIG REWRITE (1)對啓動Redis時指定的redis.conf文件進行改寫 CONFIG REWRITE
CONFIG SET

(1)動態調整Redis服務器的配置而無需重啓

(2)修改後的配置當即生效

CONFIG SET parameter value
SELECT

(1)切換到指定數據庫,數據庫索引index用數字指定,以0做爲起始索引值

(2)默認使用0號數據庫

SELECT index
DBSIZE (1)返回當前數據庫的Key的數量 DBSIZE
DEBUG OBJECT

(1)這是一個調試命令,不該當被客戶端使用

(2)key存在時返回有關信息,key不存在時返回錯誤

DEBUG OBJECT key
FLUSHALL (1)清空整個Redis服務器的數據 FLUSHALL
FLUSHDB (1)清空當前數據庫中的全部數據 FLUSHDB
INFO

(1)以一種易於解釋且易於閱讀的格式,返回Redis服務器的各類信息和統計數值

(2)經過給定可選參數section,可讓命令只返回某一部分信息

INFO [section]
LASTSAVE (1)返回最近一次Redis成功將數據保存到磁盤上的時間,以UNIX時間戳格式表示 LASTSAVE
MONITOR (1)實時打印出Redis服務器接收到的命令,調試用 MONITOR
SHUTDOWN

(1)中止全部客戶端

(2)若是至少有一個保存點在等待,執行SAVE命令

(3)若是AOF選項被打開,更新AOF文件

(4)關閉Redis服務器

SHUTDOWN [SAVE|NOSAVE]

看下命令的使用演示:

SELECT命令忘了,想起來的時候數據庫已經清空了就算了,使用SELECT後控制檯會變成"127.0.0.1:6379[3]>",即帶上數據庫的index。

 

Redis的事務

最後,本文簡單說一下Redis的事務機制,首先Redis的事務是由DISCARD、EXEC、MULTI、UNWATCH、WATCH五個命令來保證的:

命令 描述 用法
DISCARD

(1)取消事務

(2)若是正在使用WATCH命令監視某個/某些key,那麼取消全部監視,等同於執行UNWATCH

DISCARD
EXEC

(1)執行全部事務塊內的命令

(2)若是某個/某些key正處於WATCH命令監視之下且事務塊中有和這個/這些key相關的命令,那麼EXEC命令只在這個/這些key沒有被其餘命令改動的狀況下才會執行並生效,不然該事務被打斷

EXEC
MULTI

(1)標記一個事務塊的開始

(2)事務塊內的多條命令會按照前後順序被放入一個隊列中,最後由EXEC命令原子性地執行

MULTI
UNWATCH

(1)取消WATCH命令對全部key的監視

(2)若是WATCH以後,EXEC/DISCARD命令先被執行了,UNWATCH命令就不必執行了

UNWATCH
WATCH (1)監視一個/多個key,若是在事務執行以前這個/這些key被其餘命令改動,那麼事務將被打斷 WATCH key [key ...]

首先咱們看一下事務沒有被打斷的狀況:

看到開啓事務以後,全部的命令返回的都是QUEUED,即放入隊列,而不是直接執行。

接着模擬一下事務被打斷的狀況,WATCH一下Number這個Key,我另外起了一個Redis客戶端INCR了一下Number,結果爲:

看到,並無命令被執行,返回nil即事務被打斷。

接着簡單說一下事務,和數據庫相似的,事務保證的是兩點:

  • 隔離,全部命令序列化、按順序執行,事務執行過程當中不會被其餘客戶端發來的命令打斷
  • 原子性,事務中的命令要麼所有執行,要麼所有不執行

另外,Redis的事務並不支持回滾,這個其實網上已經說法挺多了,大體上是兩個緣由:

  • Redis命令只會由於語法而失敗(且這些問題不能再入隊時被發現),或是命令用在了錯誤類型的鍵上面,也就是說,從實用性角度來講,失敗的命令是因爲編程錯誤形成的,而這些錯誤應該在開發的過程當中被發現而不該該出如今生產環境中
  • Redis內部能夠保持簡單且快速,由於不須要對回滾進行支持

總而言之,對Redis來講,回滾沒法解決編程錯誤帶來的問題,所以還不如更簡單、更快速地無回滾處理事務。

 

下期預告

最後預告一下最後一篇文章會寫的內容,四部分:

  • Redis線程模型
  • Redis的RDB
  • Redis的AOF
  • Redis的集羣方式

喜歡的朋友能夠關注一下最後一篇文章。

相關文章
相關標籤/搜索