第十章 Redis安裝及配置
一、瞭解Redis
(一)Redis歷史
2008年,義大利的一家創業公司Merzia推出了一款基於MySQL的網站實時統計系統LLOOGG,然而沒過多久該公司的創始人 Salvatore Sanfilippo便對MySQL的效能感到失望,於是他決定親自為LLOOGG量身定做一個數據庫,並於2009年開發完成,這個資料庫就是Redis。 不過Salvatore Sanfilippo並不滿足只將Redis用於LLOOGG這一款產品,而是希望更多的人使用它,於是在同一年Salvatore Sanfilippo將Redis開源釋出,並開始和Redis的另一名主要的程式碼貢獻者Pieter Noordhuis一起繼續著Redis的開發,直到今天。
Salvatore Sanfilippo自己也沒有想到,短短的幾年時間,Redis就擁有了龐大的使用者群體。Hacker News在2012年釋出了一份資料庫的使用情況調查,結果顯示有近12%的公司在使用Redis。國內如新浪微博、街旁網、知乎網,國外如GitHub、Stack Overflow、Flickr等都是Redis的使用者。
VMware公司從2010年開始贊助Redis的開發, Salvatore Sanfilippo和Pieter Noordhuis也分別在3月和5月加入VMware,全職開發Redis。
(二)什麼是Redis
1. 什麼是NoSql?
為了解決高併發、高可擴充套件、高可用、大資料儲存問題而產生的資料庫解決方案,就是NoSql資料庫。
NoSQL,泛指非關係型的資料庫,NoSQL即Not-Only SQL,它可以作為關係型資料庫的良好補充。但是它不能替代關係型資料庫,而且它是儲存在記憶體中,所以它的訪問速度很快。
2. Nosql的資料庫分類
型別 |
相關產品 |
典型應用 |
資料模型 |
優勢 |
劣勢 |
鍵值(Key-Value)儲存資料庫 |
Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB |
內容快取,主要用於處理大量資料的高訪問負載。 |
一系列鍵值對 |
快速查詢 |
儲存的資料缺少結構化 |
列儲存資料庫 |
Cassandra,HBase |
分散式的檔案系統 |
以列簇式儲存,將同一列資料存在檔案系統中 |
查詢速度快,可擴充套件性強,更容易進行分散式擴充套件 |
功能相對侷限 |
文件型資料庫 |
CouchDB、MongoDB |
Web應用(與Key-Value類似,Value是結構化的) |
一系列鍵值對 |
資料結構要求不嚴格 |
查詢效能不高,而且缺乏統一的查詢語法 |
圖形(Graph)資料庫 |
Neo4J、InfoGrid、Infinite Graph |
社交網路 |
圖結構 |
利用圖結構相關演算法 |
需要對整個圖做計算才能得出結果,不容易做分散式的叢集方案。 |
3. 關於Redis
Redis是用C語言開發的一個開源的(BSD許可)、高效能的、基於鍵值對的快取與儲存系統,通過提供多種鍵值資料型別來適應不同場景下的快取與儲存需求。同時Redis的諸多高層級功能使其可以勝任訊息佇列、任務佇列等不同的角色。用於構建高效能,可擴充套件的Web應用程式
Redis是一個高效能的key-value資料庫。 Redis的出現,很大程度補償了memcached這類keyvalue儲存的不足,在部分場合可以對關係資料庫起到很好的補充作用。它提供了Python,Ruby,Erlang,PHP客戶端,使用很方便。
為了實現其出色的效能。Redis使用記憶體資料集。根據使用情況,你可以每隔一段時間將資料集轉儲到磁碟或通過將每個命令附加到日誌來保留它。如果你只需要功能豐富的網路記憶體快取,則可以選擇禁用永續性。
Redis的所有操作都是原子性的,意思就是要麼成功執行要麼失敗完全不執行。單個操作是原子性的。多個操作也支援事務,即原子性,通過MULTI和EXEC指令包起來。
4. Redis 與其他key-value快取產品比較
1)Redis支援資料的持久化,可以將記憶體中的資料儲存在磁碟中,重啟的時候可以再次載入進行使用。
2)Redis不僅僅支援簡單的key-value型別的資料,同時還提供list,set,zset,hash等資料結構的儲存。
3)Redis支援資料的備份,即master-slave模式的資料備份。
(三)Redis應用場景
1)快取(資料查詢、短連線、新聞內容、商品內容等等)。(最多使用)
2)分散式叢集架構中的session分離。
3)聊天室的線上好友列表。
4)任務佇列。(秒殺、搶購、12306等等)
5)應用排行榜。
6)網站訪問統計。
7)資料過期處理(可以精確到毫秒)
(四)Redis說明
預設埠:6379
預設資料庫:16個
伺服器端命令:redis-server
客戶端命令:redis-cli
切換資料庫:select 0-15,例如select 2 就是切換到第二個資料庫
二、Redis安裝
Redis版本規則說明:Redis約定次版本號(第一個小數點後的數字),為偶數的版本為穩定版本(例:1.2,2.0,2.2,2.4,2.6),奇數為非穩定版(例:2.9.x版本是Redis3.0曾經穩定的不穩定版本),生產環境下一般需要使用穩定版本。
1)下載redis
http://download.redis.io/releases/
2)Redis安裝環境
Redis安裝一般會在Linux系統下進行安裝,又因為Redis是使用c語言開發,所以需要c語言環境。
- Linux:CentOS7
- VMwareWorkstation:12
- C語言環境
3)Redis安裝
a)第一步:在VMware中安裝CentOS系統(Linux)。
b)第二步:在Linux系統中安裝c語言環境
[root@01node ~]# yum install gcc-c++ -y
c)第三步:將redis的原始碼包上傳到Linux系統
d)第四步:解壓原始碼包
[root@01node local]# tar -zxvf redis-5.0.8.tar.gz
e)第五步:進入redis包,然後執行make命令,編譯Redis的原始碼
f)第六步:進入解壓的src目錄下,執行make test測試是否可以安裝,出現綠色字體表示可以進行下一步安裝,命令如下所示:
[root@localhost src]# make test
注:如果出現以下錯誤請進入local目錄執行下列語句,安裝tcl後再執行maketest命令,否則請跳過以下步驟
進入local目錄
[root@01node redis]# cd ../
下載tcl包
[root@01node local]# wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz
[root@01node local]# tar xzvf tcl8.6.1-src.tar.gz
[root@01node local]# cd /usr/local/tcl8.6.1/unix/
[root@01node unix]# ./configure
[root@01node unix]# make
[root@01node unix]# make install
g)第七步:安裝
[root@01node src]# make PREFIX=/usr/local/redis install
三、Redis啟動、測試和關閉
安裝完Redis後下一步就是啟動它。在啟動之前需要先了解Redis包含的可執行檔案有哪些,如下表所示。使用時直接在命令列中輸入程式名稱即可執行。
(一)第一種啟動方式
進入Redis的安裝目錄,進入bin目錄下,執行redis-server
這樣其實已經啟動成功了,但是這屬於前端啟動,啟動redis之後,我們的控制檯就不能進行任何操作了。只能ctrl+c停止啟動。
(二)第二種啟動方式:後端啟動
首先編輯redis.conf配置檔案,找到daemonize no將其改為yes
[root@01node bin]# cd ../
[root@01node redis]# vi redis.conf
重新載入配置檔案,再次啟動
[root@01node redis]# ./bin/redis-server ./redis.conf
這樣redis就啟動了,可以通過ps -ef | grep -i redis來檢視是否啟動
[root@01node redis]# ps -ef | grep -i redis
(三)Redis簡單測試
[root@01node redis]# ./bin/redis-cli #啟動客戶端
127.0.0.1:6379> ping #測試網路是否暢通
PONG
127.0.0.1:6379> set name zhangsan # 通過鍵值對的方式定義name的值為zhangsan
OK
127.0.0.1:6379> get name #通過鍵獲取對應的值
"zhangsan"
127.0.0.1:6379> keys * #獲取所有的鍵資訊
1) "name"
127.0.0.1:6379> del name #刪除鍵
(integer) 1
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> exit #退出客戶端
(四)Redis關閉
[root@localhost redis]# ./bin/redis-cli shutdown
四、Redis入門
(一)Redis基礎命令
1.獲得符合規則的鍵名列表
KEYS pattern
pattern支援glob風格萬用字元格式,具體規則見下表:語法說明:
示例:
首先使用SET命令建立一個名為bar的鍵:
redis>SET bar 1
OK
使用KEYS * 獲取Redis中所有的鍵:
redis>KEYS *
1) “bar”
注意:
- KEYS命令需要遍歷Redis中所有鍵,當鍵的數量較多時會影響效能,不建議在生產環境中使用。
- Redis命令不區分大小寫,但一般採用採用大寫字母表示Redis命令。
2.判斷一個鍵是否存在
EXISTS key |
命令說明:如果鍵存在則返回整數型別1,否則返回0。
例如:
redis> EXISTS bar
(integer) 1
redis> EXISTS noexists
(integer) 0
3.刪除鍵
DEL key[key1 key2 ......]
命令說明:可以刪除一個或多個鍵,返回值是刪除的鍵的個數。
例如:
redis> DEL bar
(integer) 1
redis> DEL bar
(integer) 0
第二次執行DEL命令時,因為bar鍵已經被刪除,實際上並沒有刪除任何鍵,所以返回值為0。
技巧:
DEL命令的引數不支援萬用字元,但是可以結合Linux管道和xargs命令實現刪除符合所有規則的鍵。比如要刪除所有以‘user:’開頭的鍵,就可以執行以下程式碼:
redis-cli KEYS ”users:*” | xargs redis-cli DEL
另外,由於DEL命令支援多個鍵作為引數,所以還可以執行:
redis-cli DEL `redis-cli KEYS ”users:*”`
得到的效果相同,但是效能更高。
4.獲取鍵值得資料型別
TYPE key
例如:命令說明:TYPE命令用來獲得鍵值得資料型別,返回值可能是string(字串型別)、hash(雜湊型別)、list(列表型別)、set(集合型別)、zset(有序集合型別)
redis> SET foo 1
OK
redis> TYPE foo
string
redis>LPUSH bar 1
(integer) 1
redis > TYPE bar
list
#LPUSH 命令的作用是向指定的列表型別鍵中增加一個元素,如果鍵不存在則建立它。
key 相關命令:
這裡特別注意KEYS命令,雖然KEYS命令速度非常快,但是當Redis中百萬、千萬甚至過億資料的時候,掃描所有Redis的Key,速度仍然會下降,由於Redis是單執行緒模型,這將導致後面的命令阻塞直到KEYS命令執行完。
因此當Redis中儲存的資料達到了一定量級(經驗值從10W開始就值得注意了)的時候,必須警惕KEYS造成Redis整體效能下降。
(二)Redis支援的鍵值資料型別
1.字串資料型別
字串資料型別是Redis中最基本的資料型別,他能儲存任何形式的字串,包括二進位制資料。我們可以用其儲存使用者的郵箱、JSON化的物件甚至是一張圖片。一個字串型別的鍵允許儲存的資料最大容量是512MB。
字串型別是其他4種資料型別的基礎,其他資料型別和字串型別的差別從某種角度來說只是組織字串的形式不同。例如:列表型別的是以列表的形式組織字串,而集合型別是以集合的形式組織字串。
字串型別-命令
1)賦值與取值
SET key value
GET key
redis> SET key hello命令說明:SET和GET是Redis中最簡單的兩個命令,它們實現的功能和程式語言中的讀寫變數相似,如key='hello'在Redis中是這樣表示的:
ok
讀取鍵值:
redis> GET key
“hello”
當鍵不存在時會返回空結果。
2).遞增數字
INCR key
例如:命令說明:INCR命令是讓當前鍵值遞增,並返回遞增後的值。
redis> INCR num
(integer) 1
redis> INCR num
(integer) 2
當要操作的鍵不存在時會預設值為0,所以第一次遞增後的結果是1;當鍵值不是整數時Redis會提示錯誤。
redis>SET foo lorem
OK
redix>INCR foo
(error) ERR value is not an integer or out of range
3)增加指定的整數
INCRBY key increment
例如:命令說明:INCRBY命令與INCR命令基本一樣,只不過前者可以通過increment引數指定一次增加的數值。
redis>INCRBY bar 2
(integer) 2
redix>INCRBY bar 3
(integer) 5
4)減少指定的整數
DECR key
例如:命令說明:DECR命令與INCR命令用法相同,只不過是讓鍵值遞減。
redis>DECR bar
(integer)4
DECRBY命令與INCRBY命令用法也是相同的。
DECRBY key increment
5)增加指定的浮點數數
INCRBYFLOAT key increment
命令說明:INCRBYFLOAT命令類似於INCRBY命令,差別是前者可以遞增一個雙精度浮點數。
例如:
redis>INCRBYFLOAT bar 2.7
“6.7”
redis>INCRBYFLOAT bar 5E+4
“50006.699999999999999929”
6)向尾部追加值
APPEND key value
例如:命令說明:APPEND 命令的作用是向鍵值的末尾追加value。如果鍵不存在則將該鍵的值設定為value,相當於SET key value。返回值是追加後字串的總長度。
redis>SET key hello
OK
redis>APPEND key “world”
(integer) 12
7)獲取字串長度
SRELEN key
例如:命令說明:STELEN命令命令返回鍵值的長度,如果鍵不存在則返回0。
redis>SRELEN key
(integer) 12
redis>SET key 你好
OK
redis>STRLEN key
(integer) 6
前面提到字串型別可以儲存二進位制資料,所以它可以儲存任何編碼的字串。例子中的Redis接收到的是使用UTF-8編碼的中文,由於“你”和“好”兩個字的UTF-8編碼的長度都是3,所以最後得到的長度就是6。
8)同時獲得/設定多個鍵值
MGET key [key2...]
MSET key value [key2 value2...]
例如:命令說明:MGET/MSET命令與GET/SET命令相似,不過MGET/MSET可以同時獲得/設定多個鍵的鍵值。
redis>MSET key1 v1 key2 v2 key3 v3
OK
redis>GET key2
“v2”
redis>MGET key1 key3
1) “v1”
2) “v2”
9)位操作
GETBIT key offset
SETBIT key offset value
BITCOUNT key [start[ [end[
BITOP operation destkey key [key...]
例如:命令說明:一個位元組由8個二進位制組成,Redis提供了4個命令可以直接對二進位制位進行操作。
redis>SET foo bar //將foo鍵賦值為bar
OK
- GETBIT命令
bar的3個字母“b”、“a”、“r”對應的ASCII碼分別是98、97、114,轉換成二進位制後分別為1100010、1100001、1110010,所以foo鍵中的二進位制位結構如下所示:
b |
a |
r |
|||||||||||||||||||||
0 |
1 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
0 |
GETBIT命令可以獲得一個字串型別鍵指定位置的二進位制位的值(0或1),索引從0開始:
redis>GETBIT foo 0
(integer) 0
redis>GETBIT foo 6
(integer) 1
如果想要獲取的二進位制位的索引超出了鍵值的二進位制位的實際長度則預設位值是0。
redis>GETBIT foo 100000
(integer) 0
- SETBIT命令
SETBIT命令可以設定字串型別鍵指定位置的二進位制位的值,返回值是該位置的舊值。例如將foo鍵值設定為arr,可以通過位操作將foo鍵的二進位制位的索引第6位設為0,第七位設為1。
redis>SETBIT foo 6 0
(integer) 1
redis>SETBIT foo 7 1
(integer) 0
redis>GET foo
”arr“
redis>SETBIT nofoo 10 1
(integer) 0
redis>GETBIT nofoo 5
(integer) 0
如果要設定的位置超過了鍵值的二進位制位的長度,SETBIT命令會自動將中間的二進位制位設定為0,同理設定一個不存在的鍵的指定二進位制位的值會自動將其前面的位賦值為0。
- BITTOP命令
BITTOP命令可以對多個字串型別鍵進行位運算,並將結果儲存在destkey引數指定的鍵中。BITTOP命令支援的運算子操作有AND、OR 、XOR和NOT。例如:對bar和aar進行OR運算。
redis>SET foo1 bar
OK
redis>SET foo2 aar
OK
redis> BITTOP OR res foo1 foo2
(integer) 3
redis>GET res
“car”
BITTOP命令OR運算過程,如下圖:
2.雜湊資料型別
前面已經知道Redis是採用字典結構以鍵值對的形式儲存資料的,而雜湊型別(hash)的鍵值也是一種字典結構,其儲存了欄位(field)和欄位值的對映,但欄位值只能是字串,不支援其他的資料型別,換句話說,雜湊型別不能巢狀其他的資料型別。一個雜湊型別鍵可以包含至多232-1個欄位。
雜湊型別適合儲存物件:使用物件類別和ID構成鍵名,使用欄位表示物件的屬性,而欄位值則儲存屬性值。例如要儲存ID為2的汽車物件,可以分別使用名為color、name和price的3個欄位來儲存該車輛的顏色、名稱和價格。儲存結構如圖所示:
除了雜湊型別,Redis的其他資料型別同樣不支援資料型別巢狀。比如集合型別的每個元素都只能是字串,不能是另一個集合或者散列表等。
資料以二維表的形式儲存,要求所有的記錄都擁有同樣的屬性,無法單獨為某一條記錄增減屬性
思考
為ID為1的汽車增加生產日期屬性,例如:
ID |
color |
name |
price |
date |
1 |
黑色 |
寶馬 |
100萬 |
2018年10月1日 |
2 |
白色 |
奧迪 |
90萬 |
|
3 |
藍色 |
賓利 |
600萬 |
對於ID為2和3的兩條記錄而言date欄位是冗餘的。可想而知當不同的記錄需要不同的屬性時,表的欄位數量會越來越多以至於難以維護。而且當使用ORM將關係資料庫中的物件實體對映成程式中的實體時,修改表的結構往往意味著要中斷服務。為了防止這些問題,在關係資料庫中儲存這種半結構化資料還需要額外的表。
而Redis的雜湊型別則不存在這個問題。雖然我們在上圖中描述了汽車物件的儲存結構,但是這個結構只是人為的約定,Redis並不要求每個鍵都依據此結構儲存,我們完全可以自由的為任何鍵增減欄位而不影響其他鍵。
雜湊型別-命令
1)賦值與取值
HSET key field value
HGET key field
HMSET key field value [field value...]
HMSET key field[field...]
HGETALL key
redis> HSET car price 500命令說明:HSET命令用來給欄位賦值,而HGET命令用來獲得欄位的值。用法如下:
(integer)1
redis> HSET car price 500
(integer)1
redis> HSET car price 500
(integer)1
HSET命令的方便之處在於不區分插入和更新操作,這意味著修改資料時不用事先判斷欄位是否存在來決定要執行的是插入操作(insert)還是更新操作(update)。當執行的是插入操作時(即之前的欄位不存在)HSET命令會返回1,當執行的更新操作時(即之前的欄位已經存在)HSET命令會返回0。更進一步,當鍵本身不存在時,HSET命令還會自動建立它。
當需要同時設定多個欄位的值時,可以使用HMSET命令。例如:
HSET key field1 value1
HSET key field2 value2
使用HMSET命令可以改寫成:
HMSET key field1 value1 field2 value2
redis> HMGET car price name同樣的,HMGET命令可以同時獲得多個欄位的值:
1)”500”
2) “BMW”
如果想獲取鍵中所有欄位和欄位值卻不知道鍵中有哪些欄位時,可以使用HGETALL命令。例如:
redis> HGETALL car
1)”price”
2) “500”
3)”name”
4) “BMW”
2)判斷欄位是否存在
HEXISTS key field
例如:命令說明:HEXISTS命令用來判斷一個欄位是否存在,如果存在則返回1,否則返回0(如果鍵不存在也會返回0)。
redis> HEXISTS car model
(integer) 0
redis> HSET car model C200
(integer) 1
redis> HEXISTS car model
(integer) 1
3)當欄位不存在時賦值
HSETNX key field value
其實現可以表示為如下虛擬碼:命令說明:HSETNX命令與HSET命令類似,區別在於如果欄位已經存在,HSETNX命令將不執行任何操作。
def hsetnx ($key, $field,$value)
$isExists = HEXISTS $key ,$field
if $isExists is 0
HSET $key ,$field,$value
return 1
else
return 0
4)增加數字
HINCRBY key field increment
例如:命令說明:HINCRBY命令與字串型別的INCRBY命令類似,可以使欄位值增加指定的整數,雜湊型別沒有HINCR命令,但是可以通過HINCRBY key field 1來實現。
redis> HINCRBY person score 60
(integer) 0
之前person鍵不存在,HINCRBY命令會自動建立該鍵並預設score欄位在執行命令前的值為“0”。命令的返回值是增值後的欄位值。
5)刪除欄位
HDEL key field [field…]
例如:命令說明:HDEL命令可以刪除一個或者多個欄位,返回值是被刪除的欄位個數。
redis> HDEL car price
(integer) 1
redis> HDEL car price
(integer) 0
6)只獲得欄位名或欄位值
HKEYS key
HVALS key
例如:命令說明:有時僅僅需要獲取鍵中所有的欄位的名字或者所有的欄位值,那麼可以使用HKEYS或HVALS命令。
redis> HKEYS car
1)”name”
2)”model”
redis> HVALS car
1)”bmw”
2)”C200”
7)獲得欄位數量
HLEN key
redis> HLEN car例如:
(integer)2
3.列表型別
列表型別(list)可以儲存一個有序的字串列表,常用的操作是向列表兩端新增元素,或者獲得列表的某一個片段。
列表型別內部是使用雙向連結串列(double linked list)實現的,所以向列表兩端新增元素的時間複雜度為o(1),獲得越接近兩端的元素速度就越快。這意味著即使是一個有幾千萬個元素的列表,獲取頭部或者尾部的10條記錄也是極快的(和從只有20個元素的列表中獲取頭部或尾部的10條記錄的速度是一樣的)。
不過使用連結串列的代價是通過索引訪問元素比較慢,但是新插入的資料直接從隊尾插入,不需要管中間有多少資料。這一特性使列表型別能夠快速的完成關係資料庫難以應付的場景,如:社交網站的新鮮事,我們關心的只是最新的內容,使用列表型別儲存,即使新鮮事的總數達到幾千萬個,獲取其中最新的100條資料也是極快的。同樣因為在兩端插入記錄的時間複雜度是o(1),列表型別也適合來記錄日誌,可以保證加入新日誌的速度不會受到已有日誌數量的影響。藉助列表型別,Redis還可以作為佇列使用。
與雜湊型別鍵最多能容納的欄位數量相同,一個列表型別鍵最多能容納232-1個元素。
設想在iPad mini發售當天有1000個人在三里屯的蘋果店排隊等候購買,這是蘋果公司宣佈為了感謝大家的排隊支援,鉅額東獎勵排在第486位的顧客一部免費的iPad mini。為了找到第486位顧客,工作人員不得不從隊首一個一個數到第486位。但同時,無論隊伍多長,新來的人想要加入隊伍直接排在隊尾即可,和隊伍裡有多少人沒有任何的關係。這種情景與列表型別的特性很相似。
1.向列表兩端增加元素
LPUSH key value [value...]
RPUSH key value [value...]
例如:命令說明:LPUSH命令用了來向列表左邊增加元素,返回值表示增加元素後列表的長度。
redis> LPUSH numbers 1
(integer) 1
LPUSH命令還支援同時增加多個元素,例如:
redis> LPUSH numbers 2 3
(integer) 3
插入資料時LPUSH會向列表左邊加入“2”,然後再加入“3”。
向列表右邊增加元素,使用RPUSH命令,其用法與LPUSH命令一樣。
redis> RPUSH numbers 0 -1
(integer) 5
此時numbers鍵中的資料如下所示:
2.從列表兩端彈出元素
LPOP key
RPOP key
例如:從numbers列表的左邊彈出一個元素(也就是“3”)命令說明:有進有出,LPOP命令可以從列表左邊彈出一個元素。LPOP命令執行兩步操作:第一步是將列表左邊的元素從列表中移除,第二步是返回被移除的元素值。
redis> LPOP numbers
”3”
同樣,RPOP命令可以從列表右邊彈出一個元素:
redis> RPOP numbers
”-1”
結合上邊提到的4個命令可以使用列表型別來模擬棧和佇列的操作,如果想要把列表當做“棧”,則搭配使用LPUSH和LPOP或RPUSH和RPOP;如果想當成佇列,則搭配使用LPUSH和RPOP或RPUSH和LPOP。
3.獲取列表中元素的個數
LLEN key
命令說明:當鍵不存在時LLEN會返回0,LLEN命令的功能類似於SQL語句SELECT COUNT(*) FROM table_name,但是LLEN的時間複雜度為O(1),使用時Redis會直接讀取現成的值,而不需要象部分關係資料庫(如使用InnoDB儲存引擎的MYSQL表)那樣需要遍歷一遍資料表來統計條目數量。
例如:
redis> LLEN numbers
(integer) 3
4.獲得列表片段
LRANGE key start stop
例如:命令說明:LRANGE命令是列表型別最常用的命令之一,它能夠獲得列表中的某一片段。LRANGE命令將返回索引從start到stop之間的所有元素(包含兩端的元素)。Redis的列表起始索引為0。
redis>LRANGE numbers 0 2
1)”2”
2)”1”
3)”0”
LRANGE命令也支援負索引,表示從右邊開始計算序數,如“-1”表示最右邊第一個元素,“-2”表示最右邊第二個元素,以此類推:
redis>LRANGE numbers -2 -1
1)”1”
2)”0”
另外一些特殊情況如下:
1.如果start的索引位置比stop的索引位置靠後,則會返回空列表;
2.如果stop大於實際的索引範圍,則會返回到列表最右邊的元素。
redis>LRANGE numbers 1 999
1)”1”
2)”0”
LRANGE numbers 0 -1 可以獲得列表中所有的元素。
5.刪除列表中指定的值
LREM key count value
(1)當count>0 時LREM命令會從列表左邊開始刪除前count個值為value的元素。命令說明:LREM命令會刪除列表中前count個值為value的元素,返回值是實際刪除的元素個數,根據count值的不同,LREM命令的執行方式略有差異。
(2)當count<0時LREM命令會從列表右邊開始刪除前count個值為value的元素。
(3)當count=0時LREM命令會刪除所有值為value的元素。
例如:
redis>RPUSH numbers 2
(integer) 4
redis>LRANGE numbers 0 -1
1)“2”
2)“1”
3)“0”
4)“2”
#從右邊開始刪除第一個值為“2”的元素
redis>LREM numbers -1 2
(integer) 1
redis>LRANGE numbers 0 -1
1)“2”
2)“1”
3)“0”
6.獲得/設定指定索引的元素值
LINDEX key value
LSET key index value
例如:命令說明:如果要將列表型別當作陣列來用,LINDEX命令是必不可少的。LINDEX命令用來返回指定索引的元素,索引從0開始。
redis>LINDEX numbers 0
“2”
如果index是負數則表示從右邊開始計算的索引,最右邊元素的索引是-1。
redis>LINDEX numbers -1
“0”
LSET是另一個通過索引操作列表的命令,他會將索引為index的元素賦值為value。
例如:
redis>LSET numbers 1 7
OK
redis>LINDEX numbers 1
”7”
7.只保留列表指定片段
LTRIM key start end
例如:命令說明:LTRIM命令可以刪除指定索引範圍之外的所有元素,其指定列表範圍的方法和LRANGE命令相同。
redis>LRANGE numbers 0 -1
1)“1”
2)“2”
3)“7”
4)“3”
“0”
redis>LTRIM numbers 1 2
OK
redis>LRANGE numbers 0 1
1)“2”
2)“7”
LTRIM命令常和LPUSH命令一起使用用來限制列表中元素的數量,比如記錄日誌時只希望保留最近的100條日誌,則每次加入新元素時呼叫一次LTRIM命令即可:
LPUSH logs $newLog
LTRIM logs 0 99
8.向列表中插入元素
LINSERT key BEFORE | AFTER pivot value
例如:命令說明:LINSERT命令首先會在列表中從左到右查詢值為pivot的元素,然後根據第二個引數是BEFORE還是AFTER來決定將value插入到該元素的前面還是後面。LINSERT命令的返回值是插入後列表的元素個數。
redis>LRANGE numbers 0 -1
1) “2”
2) “7”
3) “0”
redis>LINSERT numbers AFTER 7 3
1) “2“
2) “7”
3) “3”
4)”0”
4.集合型別
集合的概念高中的數學課本就學習過。在集合中的每個元素都是不同的,且沒有順序。一個集合型別(set)鍵可以儲存至多232-1個字串。集合型別和列表型別有相似之處,但很容易將他們區分開來,如下所示:
集合型別 |
列表型別 |
|
儲存內容 |
至多232-1個字串 |
至多232-1個字串 |
有序性 |
否 |
是 |
唯一性 |
是 |
否 |
集合型別的常用操作是向集合中加入或刪除元素、判斷某個元素是否存在等,由於集合型別在Redis內部是使用值為空的散列表(hash table)實現的,所以這些操作的時間複雜度都是O(1)。最方便的是多個集合型別鍵之間還可以進行並集、交集和差集運算。
1.增加/刪除元素
SADD key member[member...]
SREM key member[member...]
SREM命令用來從集合中刪除一個或者多個元素,並返回刪除成功的個數。命令說明:SADD命令用來向集合中增加一個或者多個元素,如果鍵不存在則會自動建立。因為在一個集合中不能有相同的元素,所以如果要加入的元素已經存在於集合中就會忽略這個元素。本命令的返回值是成功加入的元素數量(忽略的元素不計在內)。
例如:
redis>SADD letters a
(integer) 1
redis>SADD letters a b c
(integer) 2
redis>SREM letters c d
(integer) 1
第二條SADD命令的返回值為2是因為元素“a”已經存在,所以實際上之加入了兩個元素。
由於元素”d”在集合中不存在,所以只刪除一個元素,返回值為1。
2.獲得集合中的所有元素
SMEMBERS key
命令說明:SMEMBERS命令會返回集合中的所有元素。
例如:
redis> SMEMBERS letters
1) ”b”
2) ”a”
3.判斷元素是否在集合中
SISMEMBER key member
命令說明:判斷一個元素是否在集合中是一個時間複雜度為O(1)的操作,無論集合中有多少個元素,SISMEMBER命令始終可以極快的返回結果。當值存在時SISMEMBER命令返回1,當值不存在或鍵不存在時返回0。
例如:
redis> SISMEMBER letters a
(integer) 1
redis> SISMEMBER letters b
(integer) 0
4.集合間的運算
SDIFF key [key...]
SINTER key [key...]
SUNION key [key...]
(1)SDIFF命令用來對多個集合執行差集運算。集合A 與集合B的差集表示為A-B,代表所有屬於A且不屬於B的元素構成的集合。例如:
{1,2,3}-{2,3,4} = {1}
{2,3,4}-{1,2,3} = {4}
SDIFF命令的使用方法如下:
redis> SADD setA 1 2 3
(integer) 3
redis> SADD setB 2 3 4
(integer) 3
redis> SDIFF setA setB
1) ”1”
redis> SDIFF setB setA
1) ”4”
命令說明:3個命令都是用來集合間運算的。
SDIFF命令支援同時傳入多個鍵,例如:
redis> SADD setC 2 3
(integer) 2
redis> SDIFF setA setB setC
1) ”1”
(2)SINTER命令用來對多個集合執行交集運算。集合A與集合B的交集表示為A∩B,代表所有屬於A且屬於B的元素構成的集合。例如:
{1,2,3}∩{2,3,4} = {2,3}
SINTER命令的使用方法如下:
redis> SINTER setA setB
1) ”2”
2) ”3”
redis> SDIFF setA setB setC
1) ”2”
2) ”3”
SINTER命令同樣支援同時
傳入多個鍵
(3)SUNION命令用來對多個集合執行並集運算。集合A與集合B的交集表示為A∪B,代表所有屬於A或屬於B的元素構成的集合。例如:
{1,2,3}∪{2,3,4} = {1,2,3,4}
SINTER命令同樣支援同時傳入多個鍵,如下所示:
redis> SINTER setA setB
1) ”1”
2) ”2”
3) ”3”
4) ”4”
redis> SDIFF setA setB setC
1) ”1”
2) ”2”
3) ”3”
4) ”4”
5.獲得集合中元素個數
SCARD key
命令說明:SCARD命令用來獲得集合中的元素個數。
例如:
redis> SMEMBERS letters
1) ”b”
2) ”a”
redis> SCARD letters
(integer) 2
6.進行集合運算並將結果儲存
SDIFFSTORE destination key [key ...]
SINTERSTORE destination key [key ...]
SUNIONSTORE destination key [key ...]
SDIFFSTORE命令和SDIFF命令功能一樣,唯一的區別就是前者不會直接返回運算結果,而是將結果儲存在destination鍵中。命令說明:
SDIFFSTORE命令常用於需要進行多步集合運算的場景中,如需要先計算差集再將結果和其他鍵計算交集。
SINTERSTORE命令和SUNIONSTORE命令與之類似,不再贅述。
7.隨機獲得集合中的元素
SRANDMEMBER key [count]
還可以傳遞count引數來一次隨機獲得多個元素,根據count的正負不同,具體表現也不同。命令說明:SRANDMEMBER命令用來隨機從集合中獲取一個元素。
(1)當count為正數時,SRANDMEMBER會隨機從集合裡獲得count個不重複的元素。如果count的值大於集合中的元素個數,則SRANDMEMBER會返回集合中的全部元素。
(2)當count為負數時,SRANDMEMBER會隨機從集合裡獲得|count|個的元素。這些元素可能會相同。
例如:
redis> SRANDMEMBER letters
”a”
redis> SRANDMEMBER letters
”b”
redis> SRANDMEMBER letters
”a”
redis> SADD letters c d
(integer) 2
redis> SRANDMEMBER letters 2
1)”a”
2)”b”
redis> SRANDMEMBER letters 100
1)”a”
2)”b”
3)”c”
4)”d”
redis> SRANDMEMBER letters -2
1)”b”
2)”b”
redis> SRANDMEMBER letters -6
1)”a”
2)”b“
3)”c”
4)”c”
5)”d”
6)”b”
//目前letters集合中共有“a”,”b”,”c”,”d”4個元素
8.從集合中彈出一個元素
SPOP key
例如:命令說明:SPOP命令與LPOP命令類似,但是由於集合型別的元素是無序的,所以SPOP命令會從集合中隨機選擇一個元素彈出。
redis> SPOP letters
”b”
redis> SMEMBERS letters
1)”a”
2)”c”
3)”d”
前邊學過LPOP命令作用是從列表左邊彈出一個元素(即返回元素的值並刪除它)
5.有序集合型別
有序集合型別(sorted set)的特點就是“有序”,與集合的區別也在於“有序”二字。在集合型別的基礎上有序集合型別為集合中的每個元素都關聯了一個分數,這使得我們不僅可以完成插入、刪除和判斷元素是否存在等集合型別支援的操作,還能獲得分數最高(最低)的前N個元素、獲得指定分數範圍內的元素等與分數有關的操作。雖然集合中每個元素都是不同的,但是他們的分數卻可以相同。
有序集合型別在某些方面和列表型別有些相似。
(1)二者都是有序的。
(2)二者都可以獲得某一範圍的元素。
但是二者有著很大的區別,這使得他們的應用場景也是不同的。
(1)列表型別是通過連結串列實現的,獲得靠近兩端的資料速度極快,而當元素增多後,訪問中間資料的速度會較慢,所以它適合實現如“新鮮事”或“日誌”這樣很少訪問中間元素的應用。
(2)有序集合型別是使用散列表和跳躍表(skip list)實現的,所以即使讀取位於中間部分的資料速度也很快(時間複雜度是O(log(N))。
(3)列表中不能簡單的調整某個元素的位置,但是有序集合可以(通過更改這個元素的分數)。
(4)有序集合型別要比列表型別更耗費記憶體。
有序集合型別是Redis的5種資料型別中最高階的型別。
1.增加數字
HINCRBY key field increment
例如:命令說明:HINCRBY命令與字串型別的INCRBY命令類似,可以使欄位值增加指定的整數,雜湊型別沒有HINCR命令,但是可以通過HINCRBY key field 1來實現。
redis> HINCRBY person score 60
(integer) 0
之前person鍵不存在,HINCRBY命令會自動建立該鍵並預設score欄位在執行命令前的值為“0”。命令的返回值是增值後的欄位值。
2.刪除欄位
HDEL key field [field…]
例如:命令說明:HDEL命令可以刪除一個或者多個欄位,返回值是被刪除的欄位個數。
redis> HDEL car price
(integer) 1
redis> HDEL car price
(integer) 0
3.只獲得欄位名或欄位值
HKEYS key
HVALS key
命令說明:有時僅僅需要獲取鍵中所有的欄位的名字或者所有的欄位值,那麼可以使用HKEYS或HVALS命令。
例如:
redis> HKEYS car
1)”name”
2)”model”
redis> HVALS car
1)”bmw”
2)”C200”
4.獲得欄位數量
HLEN key
redis> HLEN car例如:
(integer)2
INCR key |