《Redis 入門指南》(第二版)
第一章
Redis 是什么
Redis (REmote Dictionary Server 遠程字典服務器)是一個開源的、高性能的、基于鍵值對的緩存與存儲系統,通過提供多種鍵值數據類型來適應不同場景下的緩存與存儲需要。同時 Redis 的諸多高級功能使其可以勝任消息隊列,任務隊列等不同的角色。
特性
存儲結構
Redis 它以字典結構存儲數據,并允許其它應用通過 TCP 協議讀取字典中的內容
目前 Redis 支持的數據類型(鍵值):
- 字符串類型
- 散列類型
- 列表類型
- 集合類型
- 有序集合類型
內存存儲與持久化
Redis 數據存儲在內存中。在一臺普通的筆記本電腦上,Redis 可以在一秒內讀寫超過 10 萬個鍵值。
如果程序退出內存,數據會丟失,不過 Redis 提供了對持久化的支持,可以將內存中的數據異步寫入到硬盤中,同時不影響繼續提供服務。
功能豐富
- Redis 可以為每個鍵設置生存時間(TTL),這一出色的性能讓 Redis 可以作為緩存系統來使用。
- Redis 支持持久化和豐富的數據類型
- Redis 列表類型鍵可以用來實現隊列,并且支持阻塞式讀取
PS: Redis 與 Memcached 性能上的區別, Redis 是單線程模型,而 Memcached 是多線程支持的,所以在多核服務器上后者的性能理論上相對更高一些。而 Redis 在性能上也是非常高的,所以不用擔心性能問題,而更多的去考慮功能問題。隨著 Redis 3.0 的推出,標志著 Memcached 幾乎成為了 Redis 的子集。同時 Redis 對集群的支持,也使得 Memcahced 原有的第三方集群工具不再成為優勢。
作為緩存系統, Redis 還可以限定數據占用的最大內存空間,在數據達到空間限制后,可以按照一定的規則自動淘汰不需要的鍵。
為什么使用 Redis
- Redis 提供了 100 多個命令,常用的只有十幾個,并且每個命令都很容易記憶。
- Redis 提供了幾十種編程語言的客戶端庫。
- Redis 是開源的
第二章
Redis 版本規則
Redis 規定次版本號(小數點后的數字)為偶數的版本是穩定版本(如 2.8 版本、3.0 版本),奇數為非穩定版,生產環境一般需要穩定版本
安裝
在 POSIX 系統中的安裝
$ wget http://download.redis.io/xxxx.3-0.tar.gz
$ tar zxvf xxxx-3.0.tar.gz
$ cd redis-stable
$ make
Redis 沒有外部依賴,安裝過程簡單。編譯后的 Redis 源代碼目錄的 src 文件夾中可以找到若干個可執行程序,最好在編譯后直接執行 make install
命令來將這些可執行程序復制到 /usr/local/bin
目錄中以便以后執行程序時可以不用輸入完整的路徑。
軟件包管理器中的 redis 比較古老,對升級和性能有影響,不推薦使用。
在 OS X 系統中的安裝
略
在 Windows 中的安裝
略
啟動和停止 Redis
直接啟動
$ redis-server
默認使用 Redis 會使用 6379 端口,通過 --port
參數可以自定義端口號:
$ redis-server --port 6380
注意在使用的時候也需要指定相應的端口:
$ redis-cli -p 6380
通過初始化腳本啟動 Redis
生產環境推薦使用此方法運行,可以使得 Redis 能隨系統自動運行。在 Redis 安裝目錄下有一個 utils 目錄中,有一個名為 redis_init_script
的初始化腳本文件。
具體方式,可以參考本書中第二章 2.2.1 小節。
但是完全沒有必要,可以執行安裝目錄下的 utils/install_server.sh
腳本。
$ ./install_server.sh
Please select the redis port for this instance: [6379]
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server]
Selected config:
Port : 6379
Config file : /etc/redis/6379.conf
Log file : /var/log/redis_6379.log
Data dir : /var/lib/redis/6379
Executable : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
需要注意的是第一步的時候可以選擇端口號,如果需要指定不同的端口或運行多個 Redis 服務器,可以多次執行該文件,然后指定不同的端口即可。
根據最后的提示,可以得知,在 345 的運行級別下,默認開機啟動的。可以執行 chkconfig
命令查看:
$ chkconfig --list redis_6379
redis_6379 0:關 1:關 2:開 3:開 4:開 5:開 6:關
停止 Redis
考慮到 Redis 有可能正在將內存中的數據同步到硬盤中,強行終止可能會造成數據丟失。正確停止的方式是向 Redis 發送 SHUTDOWN
命令:
$ redis-cli SHUTDOWN
注意,不是使用的默認端口需要加上端口號,如果端口號為 6380,則:
$ redis-cli -p 6380 SHUTDOWN
Redis 命令行客戶端
發送命令
通過 redis-cli
向 Redis 發送命令有兩種方式:
- 第一種方式是將命令作為
redis-cli
的參數執行,后面不跟參數會自動按照默認配置來執行,也可以通過指定-h
和-p
指定地址和端口,Redis 提供了 PING 命令來測試客戶端與 Redis 的連接是否正常,如果正常會收到 PONG; - 第二種方式是不附帶參數運行 redis-cli,這樣會進入交互模式,可以自由輸入命令,這種方式在要輸入多條命令時比較方便
命令返回值
1. 狀態回復
最簡單的一種答復,如執行 SET
會返回狀態 OK
表示成功。
redis> PING
PONG
2. 錯誤回復
當出現命令不存在或命令格式有錯誤等情況時會返回錯誤回復,錯誤回復以(error)開頭,并在后面跟上錯誤信息。
3. 整數回復
Redis 雖然沒有整數類型,但是提供了一些用于整數操作的命令,如遞增鍵值的 INCR
命令會以整數形式返回遞增后的鍵值。除此之外還有一些其它的操作,如獲取當前數據庫的鍵的數量的 DBSIZE
命令。
redis> INCR foo
(integer) 1
4. 字符串回復
是最常見的一種回復類型,當請求一個字符串類型的鍵的鍵值或一個其它類型鍵中的元素時,就會返回一個字符串,用引號包裹:
redis> GET foo
"1"
5. 多行字符串回復
多行字符串回復中的每行字符串都以一個序號開頭,如:
redis> keys *
1) "name"
2) "num"
配置
配置文件可以設置端口號、是否開啟持久化、日志級別等。可以在啟動 Redis 服務時指定配置文件,如:
$ redis-server /path/to/redis.conf
同時可以指定一些配置項,這樣會覆蓋配置文件里面的參數,如:
$ redis-server /path/to/redis.conf --loglevel warning
源代碼目錄中有一個配置文件的模板 redis.conf。
除此之外,還可以在 Redis 運行時通過 CONFIG SET
命令在不重新啟動 Redis 的情況下動態修改部分 Redis 配置:
redis> CONFIG SET loglevel warning
OK
PS:并不是所有配置都可以使用 CONFIG SET
命令修改。
查看配置:
redis> config get loglevel
1) "loglevel"
2) "notice"
第一行表示選項名,第二行即是選項值。
多數據庫
Redis 提供了多個用于存儲數據的字典,可以將其中的每個字典都理解成一個獨立的數據庫。
每個數據庫對外都是以一個從0開始的遞增數字命名, Redis 默認支持 16 個數據庫。可以通過配置參數 databases
來修改這一數字。 客戶端與 Redis 建立連接后會自動選擇 0 號數據庫,不過可以隨時使用 SELSECT
命令更換數據庫,如選擇 1 號數據庫:
redis> select 1
OK
- Redis 不支持自定義數據庫的名字,每個數據庫都以編號命名,開發者必須記錄哪些數據庫存儲了哪些數據。
- Redis 不支持為每個數據庫設置不同的訪問密碼,所以一個客戶端要么可以訪問全部庫,要么一個庫也不能訪問。
- Redis 多個數據庫之間并不是完全隔離的,如果
FLUSHALL
命令可以清空一個實例下的所有數據庫中的內容。不同的應用應該使用不同的 Redis 實例來存儲,由于 Redis 占用的內存只有 1MB 左右,所以不用擔心多個 Redis 實例會額外占用很多內存。
第三章
數據類型
熱身
幾個基礎命令:
1、獲取符合規則的鍵名列表
KEYS pattern
pattern
支持 glob 風格通配符格式:
-
?
匹配一個字符 -
*
匹配任意個(包括0個)字符 -
[]
匹配括號間的任一字符,可以使用-
表示一個范圍,如 a[b-d] 可以匹配 "ab"、"ac"、"ad" -
\x
匹配字母 x ,用于轉義符號,如要匹配 ? ,可以使用 ?
注意: KEYS
命令需要遍歷 Redis 中的所有鍵,當鍵的數量較多時會影響性能,不建議在生產環境中使用。
PS: Redis 不區分命令大小寫
2、判斷一個鍵是否存在
EXISTS key
如果存在返回 1,不存在返回 0.
3、刪除鍵
DEL key [key1 ... ]
可以刪除一個或多個鍵,返回值是刪除的鍵的個數。
Tips: DEL
命令參數不支持通配符,但可以做類似 Linux 的管道符的操作。比如要刪除以 "user:"開關的鍵,可以執行 redis-cli KEYS "user:*" | xargs redis-cli DEL
,另外由于 DEL
命令支持多個鍵作為參數,可以執行 redis-cli DEL 'redis-cli KEYS "user:*"'
(注意,里面是 "`" 號,操蛋的 markdown)。達到的效果一樣,但效率更高。
4、獲取得鍵值的數據類型
TYPE key
返回值可能是 string(字符串類型)、hash(散列)、list(列表類型)、set(集合類型)、zset(有序集合類型)。
字符串類型
介紹
它能存儲任何形式的字符串,包括二進制數據。一個字符串類型鍵允許存儲的數據的最大容量是 512MB。
命令
1、賦值與取值
SET key value
GET key
存值時如果有空格要加引號,取值當不存在時,會返回空結果。
2、遞增數字
INCR key
當存儲的字符串是整數時,INCR
命令的作用是讓當前鍵值遞增,并返回增后的值。
redis> INCR pv
(integer) 2
PS: 當要操作的鍵不存在時會默認鍵值為 0,所以第一次遞增后的結果是 1
PS: 如果 key 不是整數類型,會報錯
127.0.0.1:6379> SET name "Eden"
127.0.0.1:6379> INCR name
(error) ERR value is not an integer or out of range
PS: 不建議使用 GET
SET
方式去將一個值取出來,然后寫一個函數去自己實現它,如果兩個客戶端同時取出了這個 value,就會出競態條件。而 Redis 本身上原子操作的,無論多少個客戶端同時連接,都不會出現這種情況。
實踐
TIPS: Redis 鍵命名
Redis 本身對于鍵的命名并沒有強制的要求,但比較有用的實踐是用 “對象類型:對象ID:對象屬性” 來命名的,如
user:1:friends
。
對于多個單詞則推薦使用 “.” 分隔。
為了維護方便,命名一定要有意義。
如果用 Redis 作為數據庫,可以使用 INCR
命令來設置自增 ID。
存儲數據,如數組,我們需要使用序列化的函數(如PHP的 serialize
和 Javascript 的 JSON.stringify
),除此之外,字符串類型鍵可以存儲二進制數據,可以使用 MessagePack
進行序列化,速度更快,占用空間更小。
命令拾遺
- 增加指定的整數,
INCRBY key increment
與INCR
相似,只不過后者每次增加 1 個,前者可以指定數值。 - 減少指定的整數,
DECR key
和DECRBY key decrement
與INCR
相似,只不過是讓鍵值遞減。 - 增加指定浮點數,
INCRBYFLOAT key increment
,可以增加一個雙精度浮點數。incrbyfloat salary 100.23
。 - 向尾部追加值,
APPEND key value
向鍵值的尾部追加值,如果鍵不存在則將該鍵的值設置為 value,返回值是追加字符串后的總長度。 - 獲取字符串長度,
STRLEN key
,返回鍵值的長度,如果不存在則返回 0,計算中文時,如果為 utf-8 編碼,則每個中文相當于 3 個出字節。 - 同時獲取/設置多個鍵值,
MGET key [key1 key2 ...]
和MSET key value [key1 value1 ...]
,如果位數有錯誤,會報錯。 - 位操作,
GETBIT key offset
SETBIT key offset value
BITCOUNT key [start] [end]
BITOP operation destkey key [key ... ]
,略書 29 頁。
redis>incr c
(integer) 1
redis> incrby c 5
(integer) 6
redis>decr c
(integer) 5
redis> decrby c 3
(integer) 2
redis>incrbyfloat c 1.5
"3.5"
redis>set greeting Hello
OK
redis>append greeting " world."
(integer) 11
127.0.0.1:6379> mset name ZhangSan sex man age 18
OK
127.0.0.1:6379> mget name sex age
1) "ZhangSan"
2) "man"
3) "18"
散列類型 (hash)
介紹
散列類型的鍵值也是一種字典結構,其存儲了字段和字段值的映射,但字段值只能是字符串,不支持其它數據類型。換句話說,散列類型不能嵌套其他的數據類型。一個散列類型鍵可以包含至多 232 - 1個字段。
除了散列類型, Redis 的其他數據類型同樣不支持數據類型嵌套。比如集合類型的每個元素都只能是字符串,不能是另一個集合或散列表等
散列類型適合存儲對象:使用對象類別和 ID 構成鍵名,使用字段表示對象的屬性,而字段值則存儲屬性值。
命令
1、賦值與取值
HSET key field value
HGET key field
HMSET key field value [field value ...]
HMGET key field [field ...]
HGETALL key
HSET
命令不區分插入和更新操作,這意味著修改數據時不用事先判斷字段是否存在來決定要執行的是插入還是更新操作。
2、判斷字段是否存在
HEXISTS key field
如果存在則返回1,否則返回0(如果鍵不存在也會返回0)
3、當字段不存在時賦值
HSETNX key field value
PS:NX 表示 if not exists
4、增加數字
HINCRBY key field increment
散列類型沒有 HINCR 命令,但是可以通過 HINCRBY key filed 1 來實現,之前不存在的 key 會自動建立。
5、刪除字段
HDEL key field [field2 ...]
實踐
略
命令拾遺
1、只獲取字段名或字段值
HKEYS key
HVALS key
2、獲取字段數量
HLEN key
列表類型
介紹
列表類型可以存儲一個有序的字符串列表,常用的操作是向列表兩端添加元素,或者獲得列表的某一個片段。
列表類型內部是使用雙向鏈表實現的,所以向列表兩端添加元素的時間復雜度都是一樣的 O(1)。
不過使用鏈表的代價是通過索引訪問元素比較慢,也即從一個鏈表中獲取某一個元素,這種場景下不如 散列 類型。
借助鏈表的類型,Redis 還可以作為隊列使用,與散列類型鍵最多能容納的字段數量相同,一個列表類型鍵最多能容納 232 - 1 個元素。
命令
1、向列表兩端增加元素
// 向左邊增加元素,支持多個元素
LPUSH key value [value2 ... ]
// 向右邊增加元素,支持多個元素
RPUSH key value [value2 ... ]
2、從列表兩端彈出元素
// 從左邊彈出一個元素
LPOP key
// 從右邊彈出一個元素
RPOP key
彈出一個元素分兩步操作:一是將列表兩邊的某個元素刪除,二是返回該元素。
3、獲取列表中的元素個數
LLEN key
當鍵不存在時 LLEN
返回 0.
4、獲取列表片斷
LRANGE key start stop
返回從 start 到 stop 之間的元素(包括兩端的元素), Redis 的列表起始索引為 0。
LRANGE
命令在取得列表片段的同時不會像 LPOP
一樣刪除該片段。
LRANGE
命令也支持負數索引,表示從右邊開始計算序數。如 -1
就表示右邊第一個元素。
特殊情況:
- 如果 start 的索引位置比 stop 的位置靠后,則會返回空列表。
- 如果 stop 大于實際的索引范圍,則會返回到列表最右邊的元素。
5、刪除列表中指定的值
LREM key count value
刪除列表中前 count 個值為 value 的元素。返回值是實際刪除的元素的個數。
- 當 count > 0 時,
LREM
命令會從列表左邊開始刪除前 count 個值為 value 的元素。 - 當 count < 0 時,
LREM
命令會從列表右邊開始刪除前 |count| 個值為 value 的元素。 - 當 count = 0 時,
LREM
命令會刪除所有值為 value 的元素。
實踐
略 P45
命令拾遺
1、獲取 / 設置指定索引的元素
// 獲取索引為 index 的元素
LINDEX key index
// 設置索引為 index 的元素的值為 value
LSET key index value
索引從 0 開始,如果 index 是負數表示從右邊開始索引,右邊第一個元素的索引是 -1。
2、只保留列表指定片段
LTRIM key start end
刪除指定索引范圍之外的所有元素,指定列表范圍的方法和 LRANGE
相同。
LTRIM
命令常和 LPUSH
命令一起來限制列表中元素的數量,比如記錄一個日志時我們希望只保留最新的 100 條日志。
redis> LPUSH numbers 1
redis> LTRIM numbers 0 99
3、向列表中插入元素
LINSERT key BEFORE|AFTER pivot value
LINSERT
命令先會在列表中從左到右查找值為 pivot 的元素,然后根據第二個參數是 BEFORE 還是 AFTER 來決定將 value 插入到該元素的前面還是后面。
返回值為插入后列表的元素的個數。
PS:如果列表中有多個元素的值都是一樣的,也即有多個 pivot 的值,那么使用 LINSERT
命令只會插入到第一個元素的前面或后面。
4、將一個元素從一個列表轉到另一個列表
RPOPLPUSH source destination
RPOPLPUSH
會先從 source 列表類型鍵的右邊彈出一個元素,然后將其插入到 destination 的左邊。并返回這個元素的值。
當 source 和 destination 相同時,RPOPLPUSH 命令會不斷地將隊尾的元素移到隊首,這個特性可以實現一個網站監控系統,具體需求見 P48。
集合類型(set)
介紹
在集合中的每個元素都是不同的,且沒有順序。一個集合類型鍵可以存儲至多 232 - 1個字符串。
由于集合類型在 Redis 內部是使用值為空的散列表實現的,所以這些操作的時間復雜度都是 O(1)。最方便的是多個集合類型鍵之間還可以進行并集、交集和差集運算。
命令
1、增加刪除元素
// 向集合中增加一個或多個元素,如果鍵不存在則會自動創建
// 因為在一個集合中不能有相同元素,所以如果要加入的元素已經存在于集合中就會忽略這個元素
// 該命令返回成功加入的數量(忽略的元素不計在內)
SADD key member [member2 ...]
// 返回刪除成功的個數
SREM key member [member2 ...]
2、獲取集合中的所有元素
SMEMBERS key
返回集合中的所有元素
3、判斷元素是否在集合中
SISMEMBER key member
key 集合中如果存在 member 值則返回 1,如果不存在則返回 0。
4、集合間的運算
// 求差集
// 計算在 key 中出現,但在 key2 中沒出現,得到的結果與 key3 進行計算
SDIFF key [key2 key3 ...]
// 求交集
// 在 key 中出現,同時也在 key2 中出現
SINTER key [key2 key3 ...]
// 求并集
//
SUNION key [key2 key3 ...]
實踐
- 存儲文章標簽
- 通過標簽搜索文章
命令拾遺
1、獲取元素中集合的個數
SCARD key
2、進行集合運算并將結果存儲
SDIFFSTORE destination key [key2 ...]
SINTERSTORE destination key [key2 ...]
SUNIONSTORE destination key [key2 ...]
以上三個命令都將 SDIFF
SINTER
SUNION
計算得到的結果保存在鍵為 destination 的集合中。
3、隨機獲取集合中的元素
SRANDMEMBER key [count]
可以傳遞 count 參數來一次隨機獲取一個或多個元素。
根據 count 的正負不同,具體表現也不同:
- 當 count 為正數時,
SRANDMEMBER
會隨機從集合里獲得 count 個不重復的元素,如果 count 的值大于集合中的元素個數(SCARD
),則返回集合中的全部元素,這些元素不會重復的。 - 當 count 為負時,會隨機從集合里獲得 |count | 個元素,這些元素可能重復。
4、從集合中彈出一個元素
SPOP key
但由于集合類型的元素是無序的,所以 SPOP
命令會從集合中隨機選擇一個元素彈出。
有序集合類型
介紹
在集合類型的基礎上有序集合中的每個元素都關聯了一個分數,這使得我們不僅可以完成插入、刪除和判斷元素是否存在等集合類型的操作,還能夠獲得分數最高(或最低)的前N個元素,獲得指定分數范圍內的元素等與分數有關的操作。
集合中的元素是不同的,但它們中的分數是可以相同的。
有序集合與列表的相似點:
- 二者都是有序的。
- 二者都可以獲取一定范圍的元素。
有序集合與列表的不同點:
- 列表是通過鏈表實現的,獲取靠近兩端的數據非常快,而當元素增多后,訪問中間的元素會比較慢,所以列表比較適合實現如“新鮮事” 或 “日志”這樣很少訪問中間元素的應用;
- 有序集合類型是使用散列表和跳躍表實現的,即使位于中間部位的數據,速度也很快。
- 列表中不能簡單地調整某個元素的位置,但是不序集合可以(通過改變這個元素的分數)
- 有序集合要比列表類型更耗費內存
命令
1、增加元素
ZADD key score member [score2 member2 ...]
ZADD
命令用來向有序集合中加入一個元素和該元素的分數,如果該元素已經存在,則會用新的分數替換原有的分數, ZADD
命令的返回值是新加入到集合中的元素的個數(不包含之前已經存在的元素)
2、獲取元素的分數
ZSCORE key member
3、獲取排名在某個范圍的元素列表
ZRANGE key start stop [WITHSCORES]
ZREVRANGE key start stop [WITHSCORES]
ZRANGE
命令會按照元素分數從小到大的順序返回索引從 start 到 stop 之間的所有元素(包含兩端的元素),負數從后往前找(-1表示最后一個)。ZREVRANGE
命令會逆序查找。在尾部加上 WITHSCORE
可以連同分數一起查出來。
# 返回所有 keys 集合中的元素
redis> ZRANGE keys 0 -1
4、獲得指定分數范圍的元素
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset limit]
按元素分數從小到大的順序返回分數在 min 和 max 之間(包含 min 和 max)的元素。
如果希望分數范圍不包含端點值,可以在分數前加上“(”符號。
min 和 max 還支持無窮大, -inf
和 +inf
分別表示負無窮和正無窮。
offset 和 limit 類似于 SQL 語句。
# 獲取鍵為 scoreboard 的有序集合分數為80(不包含)到正無窮的元素
redis> ZRANGEBYSCORE scoreboard (80 +inf
5、增加某個元素的分數
ZINCRBY key increment member
ZINCRBY
命令可以增加一個元素的分數,返回值是更改后的分數。
實踐
略
命令拾遺
1、獲得集合中元素的數量
ZCARD key
2、獲取指定分數范圍內的元素個數
ZCOUNT key min max
min 和 max 參數的特性與 ZRANGEBYSCORE
命令中的一樣。
3、刪除一個或多個元素
ZREM key member [member2 ...]
返回值是成功刪除的元素的個數(不包含本身就不存在的元素)
4、按照排名范圍刪除元素
ZREMRANGEBYRANK key start stop
按元素分數從小到大的順序(即索引從0開始)刪除處在指定排名范圍內的元素,并返回刪除的元素數量。
5、按分數范圍刪除元素
ZREMRANGEBYSCORE key min max
刪除指定分數范圍內的元素,min 和 max 特性和 ZRANGEBYSCORE
一樣。返回值為刪除元素的數量。
6、獲得元素的排名
ZRANK key member
ZREVRANK key member
按元素分數從小到大的順序獲得指定的元素的排名(從0開始)。后者相反。
第四章
事務
- Redis 保證一個事務中的所有命令要么都執行,要么都不執行
- Redis 中的事務保證一個事務內的命令依次執行而不被其它命令插入
錯誤處理
# 事務開始
redis> MULTI
redis> set str A
redis> set str B
# 事務結束
redis> EXEC
- 語法錯誤。語法錯誤指命令不存在或者命令參數的個數不對,只要有一個命令有語法錯誤,執行
EXEC
命令后 Redis 就會直接返回錯誤,連語法正確的命令也不例外。 - 運行錯誤。指在命令執行時出現的錯誤,比如使用散列類型的命令操作集合類型的健,如果事務里的一條命令運行錯誤,其它命令會繼續執行(包含出錯命令之后的命令)。
WATCH 命令介紹
注意: 因為事務中的每個命令的執行結果都是最后一起返回的,所以無法將前一條命令的結果作為下一條命令的參數。
WATCH
命令可以監控一個或多個鍵,一旦其中有一個鍵被修改(或刪除),之后的事務就不會執行。監控一直持續到 EXEC
命令(事務中的命令是在 EXEC
之后才執行的,所以在 MULTI
命令后可以修改 WATCH
監控的鍵值)。這是一種防止競態條件的做法,如:
redis> set key 1
OK
redis> watch key
OK
redis> set key 2
OK
redis> multi
OK
redis> set key 3
QUEUED
redis> exec
(nil)
redis> get key
"2"
執行 EXEC
命令后會取消對所有鍵的監控,如果不想執行事務中的命令也可以使用 UNWATCH
命令來取消監控。
過期時間
設置過期時間命令
# 單位是秒
EXPIRE key time
# 單位是毫秒
PEXPIRE key microtime
查看過期時間命令
# 返回毫秒數
TTL key
# 返回秒數
PTTL key
PS:如果鍵不存在,返回值為 -2, 如果永久保存,返回值為 -1
取消過期時間
- 使用命令
PERSIST
,如果成功清除則返回 1, 否則返回 0(因為鍵不存在或鍵本來就是永久的)。 - 使用
SET
或GETSET
命令也會清除過期時間(設置永不過期 -1) - 使用
EXPIRE
能夠重新設置過期時間expire key time
其他只對鍵值進行操作的命令 (如 INCR
、 LPUSH
、 HSET
、 ZREM
),均不會影響鍵的過期時間。
訪問頻率限制
P76
緩存
修改 Redis 配置文件(/usr/redis/6379.conf
)。
- 限制 Redis 能夠使用的最大內存,
maxmemory
參數,單位是 Byte - 超過這個限制時 Redis 會依據
maxmemory-policy
參數指定的策略來刪除不需要的鍵,其策略參考 P78 頁 - 當超過限制時每次從數據庫中隨機刪除的幾個鍵的數量會依據
maxmemory-samples
參數來設置
排序
SORT
命令
SORT
命令可以對列表類型、集合類型和有序集合類型鍵進行排序,并且可以完成與關系數據庫中的連接查詢相類似的任務。
SORT key
除了可以排列數字外,SORT
命令可以通過 ALPHA
參數實現按字典順序排列非數字元素
SORT key ALPHA
SORT
命令默認是正序排序,還可以逆序排序
SORT key DESC
還可以支持 LIMIT
參數來返回指定范圍的結果
SORT key DESC LIMIT offset limit
BY
參數
語法
~ BY 參考鍵
其中參考鍵可以是字符串類型鍵或者是散列類型鍵的某個字段(表示為 鍵名->字段名),如果提供了 BY 參數, SORT 命令將不再依據元素自身的值進行排序,而是對每個元素使用元素的值替換參數鍵中的第一個 "*" 并獲取其值,其后依據該值對元素排序,如:
redis> SORT key BY posts:*->time DESC
上例中的posts:*->time 表示,有一個散列類型的鍵值為 posts 的數據類型數據,其中有一個屬性叫做 time
,以上就是根據這個 time 的值來做為排序的依據。
如果幾個元素的參考鍵值相同,則 SORT 命令會再比較元素本身的值來決定元素的順序。
當某個元素的參考鍵不存在時,會默認參考鍵的值為 0。