1. 程式人生 > 實用技巧 >Redis(一)

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 的SETGET命令。鍵為 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"

在以上例項中我們使用了SETGET命令,鍵為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]
迭代集合中的元素