Redis(一)
Redis 教程
REmote DIctionary Server(Redis) 是一個由Salvatore Sanfilippo寫的key-value儲存系統。
Redis是一個開源的使用ANSI C語言編寫、遵守BSD協議、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API。
它通常被稱為資料結構伺服器,因為值(value)可以是 字串(String), 雜湊(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等型別。
Redis 簡介
Redis 是完全開源的,遵守 BSD 協議,是一個高效能的 key-value 資料庫。
Redis 與其他 key - value 快取產品有以下三個特點:
- Redis支援資料的持久化,可以將記憶體中的資料儲存在磁碟中,重啟的時候可以再次載入進行使用。
- Redis不僅僅支援簡單的key-value型別的資料,同時還提供list,set,zset,hash等資料結構的儲存。
- Redis支援資料的備份,即master-slave模式的資料備份。
Redis 優勢
- 效能極高– Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
- 豐富的資料型別 – Redis支援二進位制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 資料型別操作。
- 原子 – Redis的所有操作都是原子性的,意思就是要麼成功執行要麼失敗完全不執行。單個操作是原子性的。多個操作也支援事務,即原子性,通過MULTI和EXEC指令包起來。
- 豐富的特性– Redis還支援 publish/subscribe, 通知, key 過期等等特性。
Redis與其他key-value儲存有什麼不同?
-
Redis有著更為複雜的資料結構並且提供對他們的原子性操作,這是一個不同於其他資料庫的進化路徑。Redis的資料型別都是基於基本資料結構的同時對程式設計師透明,無需進行額外的抽象。
-
Redis執行在記憶體中但是可以持久化到磁碟,所以在對不同資料集進行高速讀寫時需要權衡記憶體,因為資料量不能大於硬體記憶體。在記憶體資料庫方面的另一個優點是,相比在磁碟上相同的複雜的資料結構,在記憶體中操作起來非常簡單,這樣Redis可以做很多內部複雜性很強的事情。同時,在磁碟格式方面他們是緊湊的以追加的方式產生的,因為他們並不需要進行隨機訪問。
Redis 配置
Redis 的配置檔案位於 Redis 安裝目錄下,檔名為redis.conf(Windows 名為 redis.windows.conf)。
你可以通過CONFIG命令檢視或設定配置項。
編輯配置
你可以通過修改 redis.conf 檔案或使用CONFIG set命令來修改配置。
語法
CONFIG SET命令基本語法:
redis 127.0.0.1:6379> CONFIG SET CONFIG_SETTING_NAME NEW_CONFIG_VALUE
例項
redis 127.0.0.1:6379> CONFIG SET loglevel "notice"
OK
redis 127.0.0.1:6379> CONFIG GET loglevel
1) "loglevel"
2) "notice"
Redis config命令的常見用法如下文:
https://www.runoob.com/redis/redis-conf.html
Redis 資料型別
Redis支援五種資料型別:string(字串),hash(雜湊),list(列表),set(集合)及zset(sorted set:有序集合)。
String(字串)
string 是 redis 最基本的型別,你可以理解成與 Memcached 一模一樣的型別,一個 key 對應一個 value。
string 型別是二進位制安全的。意思是 redis 的 string 可以包含任何資料。比如jpg圖片或者序列化的物件。
string 型別是 Redis 最基本的資料型別,string 型別的值最大能儲存 512MB。
例項
redis 127.0.0.1:6379> SET runoob "菜鳥教程"
OK
redis 127.0.0.1:6379> GET runoob
"菜鳥教程"
在以上例項中我們使用了 Redis 的SET和GET命令。鍵為 runoob,對應的值為菜鳥教程。
注意:一個鍵最大能儲存 512MB。
Hash(雜湊)
Redis hash 是一個鍵值(key=>value)對集合。
Redis hash 是一個 string 型別的 field 和 value 的對映表,hash 特別適合用於儲存物件。
例項
DEL runoob用於刪除前面測試用過的 key,不然會報錯:(error) WRONGTYPE Operation against a key holding the wrong kind of value
redis 127.0.0.1:6379> DEL runoob
redis 127.0.0.1:6379> HMSET runoob field1 "Hello" field2 "World"
"OK"
redis 127.0.0.1:6379> HGET runoob field1
"Hello"
redis 127.0.0.1:6379> HGET runoob field2
"World"
例項中我們使用了 RedisHMSET, HGET命令,HMSET設定了兩個field=>value對, HGET 獲取對應field對應的value。
每個 hash 可以儲存 232-1 鍵值對(40多億)。
List(列表)
Redis 列表是簡單的字串列表,按照插入順序排序。你可以新增一個元素到列表的頭部(左邊)或者尾部(右邊)。
例項
redis 127.0.0.1:6379> DEL runoob
redis 127.0.0.1:6379> lpush runoob redis
(integer) 1
redis 127.0.0.1:6379> lpush runoob mongodb
(integer) 2
redis 127.0.0.1:6379> lpush runoob rabitmq
(integer) 3
redis 127.0.0.1:6379> lrange runoob 0 10
1) "rabitmq"
2) "mongodb"
3) "redis"
redis 127.0.0.1:6379>
列表最多可儲存 232- 1 元素 (4294967295, 每個列表可儲存40多億)。
Set(集合)
Redis 的 Set 是 string 型別的無序集合。
集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是 O(1)。
sadd 命令
新增一個 string 元素到 key 對應的 set 集合中,成功返回 1,如果元素已經在集合中返回 0。
sadd key member
例項
redis 127.0.0.1:6379> DEL runoob
redis 127.0.0.1:6379> sadd runoob redis
(integer) 1
redis 127.0.0.1:6379> sadd runoob mongodb
(integer) 1
redis 127.0.0.1:6379> sadd runoob rabitmq
(integer) 1
redis 127.0.0.1:6379> sadd runoob rabitmq
(integer) 0
redis 127.0.0.1:6379> smembers runoob
1) "redis"
2) "rabitmq"
3) "mongodb"
注意:以上例項中 rabitmq 添加了兩次,但根據集合內元素的唯一性,第二次插入的元素將被忽略。
集合中最大的成員數為 232- 1(4294967295, 每個集合可儲存40多億個成員)。
zset(sorted set:有序集合)
Redis zset 和 set 一樣也是string型別元素的集合,且不允許重複的成員。
不同的是每個元素都會關聯一個double型別的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。
zset的成員是唯一的,但分數(score)卻可以重複。
zadd 命令
新增元素到集合,元素在集合中存在則更新對應score
zadd key score member
例項
redis 127.0.0.1:6379> DEL runoob
redis 127.0.0.1:6379> zadd runoob 0 redis
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 mongodb
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 rabitmq
(integer) 1
redis 127.0.0.1:6379> zadd runoob 0 rabitmq
(integer) 0
redis 127.0.0.1:6379> > ZRANGEBYSCORE runoob 0 1000
1) "mongodb"
2) "rabitmq"
3) "redis"
各個資料型別應用場景:
型別 | 簡介 | 特性 | 場景 |
---|---|---|---|
String(字串) | 二進位制安全 | 可以包含任何資料,比如jpg圖片或者序列化的物件,一個鍵最大能儲存512M | --- |
Hash(字典) | 鍵值對集合,即程式語言中的Map型別 | 適合儲存物件,並且可以像資料庫中update一個屬性一樣只修改某一項屬性值(Memcached中需要取出整個字串反序列化成物件修改完再序列化存回去) | 儲存、讀取、修改使用者屬性 |
List(列表) | 連結串列(雙向連結串列) | 增刪快,提供了操作某一段元素的API | 1,最新訊息排行等功能(比如朋友圈的時間線) 2,訊息佇列 |
Set(集合) | 雜湊表實現,元素不重複 | 1、新增、刪除,查詢的複雜度都是O(1) 2、為集合提供了求交集、並集、差集等操作 | 1、共同好友 2、利用唯一性,統計訪問網站的所有獨立ip 3、好友推薦時,根據tag求交集,大於某個閾值就可以推薦 |
Sorted Set(有序集合) | 將Set中的元素增加一個權重引數score,元素按score有序排列 | 資料插入集合時,已經進行天然排序 | 1、排行榜 2、帶權重的訊息佇列 |
注意:Redis支援多個數據庫,並且每個資料庫的資料是隔離的不能共享,並且基於單機才有,如果是叢集就沒有資料庫的概念。
Redis是一個字典結構的儲存伺服器,而實際上一個Redis例項提供了多個用來儲存資料的字典,客戶端可以指定將資料儲存在哪個字典中。這與我們熟知的在一個關係資料庫例項中可以建立多個數據庫類似,所以可以將其中的每個字典都理解成一個獨立的資料庫。
每個資料庫對外都是一個從0開始的遞增數字命名,Redis預設支援16個數據庫(可以通過配置檔案支援更多,無上限),可以通過配置databases來修改這一數字。客戶端與Redis建立連線後會自動選擇0號資料庫,不過可以隨時使用SELECT命令更換資料庫,如要選擇1號資料庫:
redis> SELECT 1
OK
redis [1] > GET foo
(nil)
然而這些以數字命名的資料庫又與我們理解的資料庫有所區別。首先Redis不支援自定義資料庫的名字,每個資料庫都以編號命名,開發者必須自己記錄哪些資料庫儲存了哪些資料。另外Redis也不支援為每個資料庫設定不同的訪問密碼,所以一個客戶端要麼可以訪問全部資料庫,要麼連一個數據庫也沒有許可權訪問。最重要的一點是多個數據庫之間並不是完全隔離的,比如FLUSHALL命令可以清空一個Redis例項中所有資料庫中的資料。綜上所述,這些資料庫更像是一種名稱空間,而不適宜儲存不同應用程式的資料。比如可以使用0號資料庫儲存某個應用生產環境中的資料,使用1號資料庫儲存測試環境中的資料,但不適宜使用0號資料庫儲存A應用的資料而使用1號資料庫B應用的資料,不同的應用應該使用不同的Redis例項儲存資料。由於Redis非常輕量級,一個空Redis例項佔用的內在只有1M左右,所以不用擔心多個Redis例項會額外佔用很多記憶體。
Redis 命令
Redis 命令用於在 redis 服務上執行操作。
要在 redis 服務上執行命令需要一個 redis 客戶端。Redis 客戶端在我們之前下載的的 redis 的安裝包中。
語法
Redis 客戶端的基本語法為:
$ redis-cli
在遠端服務上執行命令
如果需要在遠端 redis 服務上執行命令,同樣我們使用的也是redis-cli命令。
語法
$ redis-cli -h host -p port -a password
例項
以下例項演示瞭如何連線到主機為 127.0.0.1,埠為 6379 ,密碼為 mypass 的 redis 服務上。
$redis-cli -h 127.0.0.1 -p 6379 -a "mypass"
redis 127.0.0.1:6379>
redis 127.0.0.1:6379> PING
PONG
有時候會有中文亂碼。
要在 redis-cli 後面加上 --raw
redis-cli --raw
就可以避免中文亂碼了。(輸入亂碼設定cmd的編碼)
Redis 鍵(key)
Redis 鍵命令用於管理 redis 的鍵。
語法
Redis 鍵命令的基本語法如下:
redis 127.0.0.1:6379> COMMAND KEY_NAME
例項
redis 127.0.0.1:6379> SET runoobkey redis
OK
redis 127.0.0.1:6379> DEL runoobkey
(integer) 1
在以上例項中DEL是一個命令,runoobkey是一個鍵。 如果鍵被刪除成功,命令執行後輸出(integer) 1,否則將輸出(integer) 0
Redis keys 命令
下表給出了與 Redis 鍵相關的基本命令:
序號 | 命令及描述 |
---|---|
1 | DEL key 該命令用於在 key 存在時刪除 key。 |
2 | DUMP key 序列化給定 key ,並返回被序列化的值。 |
3 | EXISTS key 檢查給定 key 是否存在。 |
4 | EXPIRE keyseconds 為給定 key 設定過期時間,以秒計。 |
5 | EXPIREAT key timestamp EXPIREAT 的作用和 EXPIRE 類似,都用於為 key 設定過期時間。 不同在於 EXPIREAT 命令接受的時間引數是 UNIX 時間戳(unix timestamp)。 |
6 | PEXPIRE key milliseconds 設定 key 的過期時間以毫秒計。 |
7 | PEXPIREAT key milliseconds-timestamp 設定 key 過期時間的時間戳(unix timestamp) 以毫秒計 |
8 | KEYS pattern 查詢所有符合給定模式( pattern)的 key 。 |
9 | MOVE key db 將當前資料庫的 key 移動到給定的資料庫 db 當中。 |
10 | PERSIST key 移除 key 的過期時間,key 將持久保持。 |
11 | PTTL key 以毫秒為單位返回 key 的剩餘的過期時間。 |
12 | TTL key 以秒為單位,返回給定 key 的剩餘生存時間(TTL, time to live)。 |
13 | RANDOMKEY 從當前資料庫中隨機返回一個 key 。 |
14 | RENAME key newkey 修改 key 的名稱 |
15 | RENAMENX key newkey 僅當 newkey 不存在時,將 key 改名為 newkey 。 |
16 | SCAN cursor [MATCH pattern] [COUNT count] 迭代資料庫中的資料庫鍵。 |
17 | TYPE key 返回 key 所儲存的值的型別。 |
更多命令請參考:https://redis.io/commands
Redis 字串(String)
Redis 字串資料型別的相關命令用於管理 redis 字串值,基本語法如下:
語法
redis 127.0.0.1:6379> COMMAND KEY_NAME
例項
redis 127.0.0.1:6379> SET runoobkey redis
OK
redis 127.0.0.1:6379> GET runoobkey
"redis"
在以上例項中我們使用了SET和GET命令,鍵為runoobkey。
Redis 字串命令
下表列出了常用的 redis 字串命令:
序號 | 命令及描述 |
---|---|
1 | SET key value 設定指定 key 的值 |
2 | GET key 獲取指定 key 的值。 |
3 | GETRANGE key start end 返回 key 中字串值的子字元 |
4 | GETSET key value 將給定 key 的值設為 value ,並返回 key 的舊值(old value)。 |
5 | GETBIT key offset 對 key 所儲存的字串值,獲取指定偏移量上的位(bit)。 |
6 | MGET key1 [key2..] 獲取所有(一個或多個)給定 key 的值。 |
7 | SETBIT key offset value 對 key 所儲存的字串值,設定或清除指定偏移量上的位(bit)。 |
8 | SETEX key seconds value 將值 value 關聯到 key ,並將 key 的過期時間設為 seconds (以秒為單位)。 |
9 | SETNX key value 只有在 key 不存在時設定 key 的值。 |
10 | SETRANGE key offset value 用 value 引數覆寫給定 key 所儲存的字串值,從偏移量 offset 開始。 |
11 | STRLEN key 返回 key 所儲存的字串值的長度。 |
12 | MSET key value [key value ...] 同時設定一個或多個 key-value 對。 |
13 | MSETNX key value [key value ...] 同時設定一個或多個 key-value 對,當且僅當所有給定 key 都不存在。 |
14 | PSETEX key milliseconds value 這個命令和 SETEX 命令相似,但它以毫秒為單位設定 key 的生存時間,而不是像 SETEX 命令那樣,以秒為單位。 |
15 | INCR key 將 key 中儲存的數字值增一。 |
16 | INCRBY key increment 將 key 所儲存的值加上給定的增量值(increment) 。 |
17 | INCRBYFLOAT key increment 將 key 所儲存的值加上給定的浮點增量值(increment) 。 |
18 | DECR key 將 key 中儲存的數字值減一。 |
19 | DECRBY key decrement key 所儲存的值減去給定的減量值(decrement) 。 |
20 | APPEND key value 如果 key 已經存在並且是一個字串, APPEND 命令將指定的 value 追加到該 key 原來值(value)的末尾。 |
更多命令請參考:https://redis.io/commands
Redis 雜湊(Hash)
Redis hash 是一個 string 型別的 field(欄位) 和 value(值) 的對映表,hash 特別適合用於儲存物件。
Redis 中每個 hash 可以儲存 232- 1 鍵值對(40多億)。
例項
127.0.0.1:6379> HMSET runoobkey name "redis tutorial" description "redis basic commands for caching" likes 20 visitors 23000
OK
127.0.0.1:6379> HGETALL runoobkey
1) "name"
2) "redis tutorial"
3) "description"
4) "redis basic commands for caching"
5) "likes"
6) "20"
7) "visitors"
8) "23000"
在以上例項中,我們設定了 redis 的一些描述資訊(name, description, likes, visitors) 到雜湊表的runoobkey中。
Redis hash 命令
下表列出了 redis hash 基本的相關命令:
序號 | 命令及描述 |
---|---|
1 | HDEL key field1 [field2] 刪除一個或多個雜湊表字段 |
2 | HEXISTS key field 檢視雜湊表 key 中,指定的欄位是否存在。 |
3 | HGET key field 獲取儲存在雜湊表中指定欄位的值。 |
4 | HGETALL key 獲取在雜湊表中指定 key 的所有欄位和值 |
5 | HINCRBY key field increment 為雜湊表 key 中的指定欄位的整數值加上增量 increment 。 |
6 | HINCRBYFLOAT key field increment 為雜湊表 key 中的指定欄位的浮點數值加上增量 increment 。 |
7 | HKEYS key 獲取所有雜湊表中的欄位 |
8 | HLEN key 獲取雜湊表中欄位的數量 |
9 | HMGET key field1 [field2] 獲取所有給定欄位的值 |
10 | HMSET key field1 value1 [field2 value2 ] 同時將多個 field-value (域-值)對設定到雜湊表 key 中。 |
11 | HSET key field value 將雜湊表 key 中的欄位 field 的值設為 value 。 |
12 | HSETNX key field value 只有在欄位 field 不存在時,設定雜湊表字段的值。 |
13 | HVALS key 獲取雜湊表中所有值。 |
14 | HSCAN key cursor [MATCH pattern] [COUNT count] 迭代雜湊表中的鍵值對。 |
更多命令請參考:https://redis.io/commands
Redis 列表(List)
Redis列表是簡單的字串列表,按照插入順序排序。你可以新增一個元素到列表的頭部(左邊)或者尾部(右邊)
一個列表最多可以包含 232- 1 個元素 (4294967295, 每個列表超過40億個元素)。
例項
redis 127.0.0.1:6379> LPUSH runoobkey redis
(integer) 1
redis 127.0.0.1:6379> LPUSH runoobkey mongodb
(integer) 2
redis 127.0.0.1:6379> LPUSH runoobkey mysql
(integer) 3
redis 127.0.0.1:6379> LRANGE runoobkey 0 10
1) "mysql"
2) "mongodb"
3) "redis"
在以上例項中我們使用了LPUSH將三個值插入了名為runoobkey的列表當中。
Redis 列表命令
下表列出了列表相關的基本命令:
序號 | 命令及描述 |
---|---|
1 | BLPOP key1 [key2 ] timeout 移出並獲取列表的第一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止。 |
2 | BRPOP key1 [key2 ] timeout 移出並獲取列表的最後一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止。 |
3 | BRPOPLPUSH source destination timeout 從列表中彈出一個值,將彈出的元素插入到另外一個列表中並返回它; 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素為止。 |
4 | LINDEX key index 通過索引獲取列表中的元素 |
5 | LINSERT key BEFORE|AFTER pivot value 在列表的元素前或者後插入元素 |
6 | LLEN key 獲取列表長度 |
7 | LPOP key 移出並獲取列表的第一個元素 |
8 | LPUSH key value1 [value2] 將一個或多個值插入到列表頭部 |
9 | LPUSHX key value 將一個值插入到已存在的列表頭部 |
10 | LRANGE key start stop 獲取列表指定範圍內的元素 |
11 | LREM key count value 移除列表元素 |
12 | LSET key index value 通過索引設定列表元素的值 |
13 | LTRIM key start stop 對一個列表進行修剪(trim),就是說,讓列表只保留指定區間內的元素,不在指定區間之內的元素都將被刪除。 |
14 | RPOP key 移除列表的最後一個元素,返回值為移除的元素。 |
15 | RPOPLPUSH source destination 移除列表的最後一個元素,並將該元素新增到另一個列表並返回 |
16 | RPUSH key value1 [value2] 在列表中新增一個或多個值 |
17 | RPUSHX key value 為已存在的列表新增值 |
Redis 集合(Set)
Redis 的 Set 是 String 型別的無序集合。集合成員是唯一的,這就意味著集合中不能出現重複的資料。
Redis 中集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是 O(1)。
集合中最大的成員數為 232- 1 (4294967295, 每個集合可儲存40多億個成員)。
例項
redis 127.0.0.1:6379> SADD runoobkey redis
(integer) 1
redis 127.0.0.1:6379> SADD runoobkey mongodb
(integer) 1
redis 127.0.0.1:6379> SADD runoobkey mysql
(integer) 1
redis 127.0.0.1:6379> SADD runoobkey mysql
(integer) 0
redis 127.0.0.1:6379> SMEMBERS runoobkey
1) "mysql"
2) "mongodb"
3) "redis"
在以上例項中我們通過SADD命令向名為runoobkey的集合插入的三個元素。
Redis 集合命令
下表列出了 Redis 集合基本命令:
序號 | 命令及描述 |
---|---|
1 | SADD key member1 [member2] 向集合新增一個或多個成員 |
2 | SCARD key 獲取集合的成員數 |
3 | SDIFF key1 [key2] 返回第一個集合與其他集合之間的差異。 |
4 | SDIFFSTORE destination key1 [key2] 返回給定所有集合的差集並存儲在 destination 中 |
5 | SINTER key1 [key2] 返回給定所有集合的交集 |
6 | SINTERSTORE destination key1 [key2] 返回給定所有集合的交集並存儲在 destination 中 |
7 | SISMEMBER key member 判斷 member 元素是否是集合 key 的成員 |
8 | SMEMBERS key 返回集合中的所有成員 |
9 | SMOVE source destination member 將 member 元素從 source 集合移動到 destination 集合 |
10 | SPOP key 移除並返回集合中的一個隨機元素 |
11 | SRANDMEMBER key [count] 返回集合中一個或多個隨機數 |
12 | SREM key member1 [member2] 移除集合中一個或多個成員 |
13 | SUNION key1 [key2] 返回所有給定集合的並集 |
14 | SUNIONSTORE destination key1 [key2] 所有給定集合的並集儲存在 destination 集合中 |
15 | SSCAN key cursor [MATCH pattern] [COUNT count] 迭代集合中的元素 |