Redis快速入門


Redis是一個開源,高階的鍵值儲存和一個適用的解決方案,用於構建高效能,可延伸的Web應用程式。

Redis有三個主要特點,使它優越於其它鍵值資料儲存系統 -

  • Redis將其資料庫完全儲存在記憶體中,僅使用磁碟進行持久化。
  • 與其它鍵值資料儲存相比,Redis有一組相對豐富的資料型別。
  • Redis可以將資料複製到任意數量的從機中。

Redis官方網網站是:http://www.redis.io/ ,如下:

Redis的優點

以下是Redis的一些優點。

  • 異常快 - Redis非常快,每秒可執行大約110000次的設定(SET)操作,每秒大約可執行81000次的讀取/獲取(GET)操作。
  • 支援豐富的資料型別 - Redis支援開發人員常用的大多數資料型別,例如列表,集合,排序集和雜湊等等。這使得Redis很容易被用來解決各種問題,因為我們知道哪些問題可以更好使用地哪些資料型別來處理解決。
  • 操作具有原子性 - 所有Redis操作都是原子操作,這確保如果兩個用戶端並行存取,Redis伺服器能接收更新的值。
  • 多實用工具 - Redis是一個多實用工具,可用於多種用例,如:快取,訊息佇列(Redis本地支援發布/訂閱),應用程式中的任何短期資料,例如,web應用程式中的對談,網頁命中計數等。

Redis與其他鍵值儲存系統

  • Redis是鍵值資料庫系統的不同進化路線,它的值可以包含更複雜的資料型別,可在這些資料型別上定義原子操作。

  • Redis是一個記憶體資料庫,但在磁碟資料庫上是持久的,因此它代表了一個不同的權衡,在這種情況下,在不能大於儲存器(記憶體)的資料集的限制下實現非常高的寫和讀速度。

  • 記憶體資料庫的另一個優點是,它與磁碟上的相同資料結構相比,複雜資料結構在記憶體中儲存表示更容易操作。 因此,Redis可以做很少的內部複雜性。

1. Redis環境安裝組態

在本章中,您將了解和學習Redis的環境安裝設定。

在Ubuntu上安裝Redis

要在Ubuntu上安裝Redis,開啟終端並鍵入以下命令 -

[yiibai@ubuntu:~]$ sudo apt-get update 
[yiibai@ubuntu:~]$ sudo apt-get install redis-server

這將在Ubuntu機器上安裝Redis。

啟動Redis

[yiibai@ubuntu:~]$ redis-server
[2988] 07 Feb 17:09:42.485 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
[2988] 07 Feb 17:09:42.488 # Unable to set the max number of files limit to 10032 (Operation not permitted), setting the max clients configuration to 3984.
[2988] 07 Feb 17:09:42.490 # Warning: 32 bit instance detected but no memory lim
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 2.8.4 (00000000/0) 32 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in stand alone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 2988
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

[2988] 07 Feb 17:09:42.581 # Server started, Redis version 2.8.4
[2988] 07 Feb 17:09:42.582 # WARNING overcommit_memory is set to 0! Background s                                                                                        ' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_m
[2988] 07 Feb 17:09:42.582 * The server is now ready to accept connections on po

檢查Redis是否正在工作

[yiibai@ubuntu:~]$ redis-cli

這將開啟一個redis提示,如下所示 -

redis 127.0.0.1:6379>

在上面的提示中,127.0.0.1是計算機的IP地址,6379是執行Redis伺服器的埠。 現在鍵入以下PING命令。

redis 127.0.0.1:6379> ping 
PONG

這表明Redis已成功在您的計算機上安裝了。

在Ubuntu上安裝Redis桌面管理

要在Ubuntu上安裝Redis桌面管理器,可從 http://redisdesktop.com/download 下載該軟體包,安裝即可。

開啟下載的軟體包並安裝。

Redis桌面管理器將提供用於管理Redis的鍵和資料的UI。

2. Redis組態

在Redis中,在Redis的根目錄下有一個組態檔案(redis.conf)。當然您可以通過Redis CONFIG命令獲取和設定所有的Redis組態。

語法
以下是Redis中的CONFIG命令的基本語法。

redis 127.0.0.1:6379> CONFIG GET CONFIG_SETTING_NAME

範例

redis 127.0.0.1:6379> CONFIG GET loglevel  
1) "loglevel" 
2) "notice"

要獲取所有組態設定,請使用*代替CONFIG_SETTING_NAME

範例

redis 127.0.0.1:6379> CONFIG GET *
  1) "dbfilename"
  2) "dump.rdb"
  3) "requirepass"
  4) ""
  5) "masterauth"
  6) ""
  7) "unixsocket"
  8) ""
  9) "logfile"
 10) "/var/log/redis/redis-server.log"
 11) "pidfile"
 12) "/var/run/redis/redis-server.pid"
 13) "maxmemory"
 14) "3221225472"
 15) "maxmemory-samples"
 16) "3"
 17) "timeout"
 18) "0"
 19) "tcp-keepalive"
 20) "0"
 21) "auto-aof-rewrite-percentage"
 22) "100"
 23) "auto-aof-rewrite-min-size"
 24) "67108864"
 25) "hash-max-ziplist-entries"
 26) "512"
 27) "hash-max-ziplist-value"
 28) "64"
 29) "list-max-ziplist-entries"
 30) "512"
 31) "list-max-ziplist-value"
 32) "64"
 33) "set-max-intset-entries"
 34) "512"
 35) "zset-max-ziplist-entries"
 36) "128"
 37) "zset-max-ziplist-value"
 38) "64"
 39) "lua-time-limit"
 40) "5000"
 41) "slowlog-log-slower-than"
 42) "10000"
 43) "slowlog-max-len"
 44) "128"
 45) "port"
 46) "6379"
 47) "databases"
 48) "16"
 49) "repl-ping-slave-period"
 50) "10"
 51) "repl-timeout"
 52) "60"
 53) "repl-backlog-size"
 54) "1048576"
 55) "repl-backlog-ttl"
 56) "3600"
 57) "maxclients"
 58) "3984"
 59) "watchdog-period"
 60) "0"
 61) "slave-priority"
 62) "100"
 63) "min-slaves-to-write"
 64) "0"
 65) "min-slaves-max-lag"
 66) "10"
 67) "hz"
 68) "10"
 69) "no-appendfsync-on-rewrite"
 70) "no"
 71) "slave-serve-stale-data"
 72) "yes"
 73) "slave-read-only"
 74) "yes"
 75) "stop-writes-on-bgsave-error"
 76) "yes"
 77) "daemonize"
 78) "yes"
 79) "rdbcompression"
 80) "yes"
 81) "rdbchecksum"
 82) "yes"
 83) "activerehashing"
 84) "yes"
 85) "repl-disable-tcp-nodelay"
 86) "no"
 87) "aof-rewrite-incremental-fsync"
 88) "yes"
 89) "appendonly"
 90) "no"
 91) "dir"
 92) "/var/lib/redis"
 93) "maxmemory-policy"
 94) "noeviction"
 95) "appendfsync"
 96) "everysec"
 97) "save"
 98) "900 1 300 10 60 10000"
 99) "loglevel"
100) "notice"
101) "client-output-buffer-limit"
102) "normal 0 0 0 slave 268435456 67108864 60 pubsub 33554432 8388608 60"
103) "unixsocketperm"
104) "0"
105) "slaveof"
106) ""
107) "notify-keyspace-events"
108) ""
109) "bind"
110) "127.0.0.1"

編輯組態

要更新組態,可以直接編輯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"

3. Redis資料型別

Redis支援5種資料型別。

字串

Redis中的字串是一個位元組序列。Redis中的字串是二進位制安全的,這意味著它們的長度不由任何特殊的終止字元決定。因此,可以在一個字串中儲存高達512兆位元組的任何內容。

範例

redis 127.0.0.1:6379> set name "tw511.com" 
OK 
redis 127.0.0.1:6379> get name 
"tw511.com"

在上面的範例中,setget是Redis命令,name是Redis中使用的鍵,tw511.com是儲存在Redis中的字串的值。

註 - Redis命令不區分大小寫,如SET,Setset都是同一個命令。字串值的最大長度為 512MB。

雜湊/雜湊

Redis雜湊/雜湊(Hashes)是鍵值對的集合。Redis雜湊/雜湊是字串欄位和字串值之間的對映。因此,它們用於表示物件。

範例

redis 127.0.0.1:6379> HMSET ukey username "yiibai" password "passswd123" points 200

在上述範例中,雜湊/雜湊資料型別用於儲存包含使用者的基本資訊的使用者物件。這裡HMSETHGETALL是Redis的命令,而ukey是鍵的名稱。

每個雜湊/雜湊可以儲存多達2^32 - 1個健-值對(超過40億個)。

列表

Redis列表只是字串列表,按插入順序排序。您可以向Redis列表的頭部或尾部新增元素。

範例

redis 127.0.0.1:6379> lpush alist redis 
(integer) 1 
redis 127.0.0.1:6379> lpush alist mongodb 
(integer) 2 
redis 127.0.0.1:6379> lpush alist sqlite 
(integer) 3 
redis 127.0.0.1:6379> lrange alist 0 10  

1) "sqlite" 
2) "mongodb" 
3) "redis"

列表的最大長度為2^32 - 1個元素(4294967295,每個列表可容納超過40億個元素)。

集合

Redis集合是字串的無序集合。在Redis中,您可以新增,刪除和測試成員存在的時間O(1)複雜性。

範例

redis 127.0.0.1:6379> sadd yiibailist redis 
(integer) 1 
redis 127.0.0.1:6379> sadd yiibailist mongodb 
(integer) 1 
redis 127.0.0.1:6379> sadd yiibailist sqlite 
(integer) 1 
redis 127.0.0.1:6379> sadd yiibailist sqlite 
(integer) 0 
redis 127.0.0.1:6379> smembers yiibailist  

1) "sqlite" 
2) "mongodb" 
3) "redis"

注意 - 在上面的範例中,sqlite被新增了兩次,但是由於集合的唯一屬性,所以它只算新增一次。

一個集合中的最大成員數量為2^32 - 1(即4294967295,每個集合中元素數量可達40億個)個。

可排序集合

Redis可排序集合類似於Redis集合,是不重複的字元集合。 不同之處在於,排序集合的每個成員都與分數相關聯,這個分數用於按最小分數到最大分數來排序的排序集合。雖然成員是唯一的,但分數值可以重複。

範例

redis 127.0.0.1:6379> zadd yiibaiset 0 redis
(integer) 1 
redis 127.0.0.1:6379> zadd yiibaiset 0 mongodb
(integer) 1 
redis 127.0.0.1:6379> zadd yiibaiset 1 sqlite
(integer) 1 
redis 127.0.0.1:6379> zadd yiibaiset 1 sqlite
(integer) 0 
redis 127.0.0.1:6379> ZRANGEBYSCORE yiibaiset 0 1000  

1) "mongodb" 
2) "redis" 
3) "sqlite"

因為 ‘sqlite‘ 的排序值是 1 ,其它兩個元素的排序值是 0 ,所以 ‘sqlite‘ 排在最後一個位置上。

4. Redis命令

Redis命令是用於在Redis伺服器上執行一些操作。
要在Redis伺服器上執行命令,需要一個Redis用戶端。Redis用戶端在Redis包中有提供,這個包在我們前面的安裝教學中就有安裝過了。

語法
以下是Redis用戶端的基本語法。

[yiibai@ubuntu:~]$ redis-cli

範例
以下範例說明了如何啟動Redis用戶端。

要啟動Redis用戶端,請開啟終端並鍵入命令redis-cli。 這將連線到您的本地Redis伺服器,現在可以執行任何的Redis命令了。

[yiibai@ubuntu:~]$redis-cli 
redis 127.0.0.1:6379> 
redis 127.0.0.1:6379> PING  
PONG

在上面的範例中,連線到到在本地機器上執行的Redis伺服器並執行PING命令,該命令檢查伺服器是否正在執行。

在遠端伺服器上執行命令

要在Redis遠端伺服器上執行命令,需要通過用戶端redis-cli連線到伺服器

語法

[yiibai@ubuntu:~]$ redis-cli -h host -p port -a password

範例
以下範例顯示如何連線到Redis遠端伺服器,在主機(host)127.0.0.1,埠(port)6379上執行,並使用密碼為 mypass

[yiibai@ubuntu:~]$ 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

5. Redis鍵命令

Redis鍵命令用於管理Redis中的鍵。以下是使用redis鍵命令的語法。

語法

redis 127.0.0.1:6379> COMMAND KEY_NAME

範例

redis 127.0.0.1:6379> SET akey redis
OK 
redis 127.0.0.1:6379> DEL akey
(integer) 1
127.0.0.1:6379> GET akey
(nil)

在上面的例子中,DEL是Redis的命令,而akey是鍵的名稱。如果鍵被刪除,則命令的輸出將為(integer) 1,否則為(integer) 0

Redis鍵命令

下表列出了與鍵相關的一些基本命令。

編號 命令 描述
1 DEL key 此命令刪除一個指定鍵(如果存在)。
2 DUMP key 此命令返回儲存在指定鍵的值的序列化版本。
3 EXISTS key 此命令檢查鍵是否存在。
4 EXPIRE key seconds 設定鍵在指定時間秒數之後到期/過期。
5 EXPIREAT key timestamp 設定在指定時間戳之後鍵到期/過期。這裡的時間是Unix時間戳格式。
6 PEXPIRE key milliseconds 設定鍵的到期時間(以毫秒為單位)。
7 PEXPIREAT key milliseconds-timestamp 以Unix時間戳形式來設定鍵的到期時間(以毫秒為單位)。
8 KEYS pattern 查詢與指定模式匹配的所有鍵。
9 MOVE key db 將鍵移動到另一個資料庫。
10 PERSIST key 刪除指定鍵的過期時間,得永生。
11 PTTL key 獲取鍵的剩餘到期時間。
12 RANDOMKEY 從Redis返回一個隨機的鍵。
13 RENAME key newkey 更改鍵的名稱。
14 PTTL key 獲取鍵到期的剩餘時間(以毫秒為單位)。
15 RENAMENX key newkey 如果新鍵不存在,重新命名鍵。
16 TYPE key 返回儲存在鍵中的值的資料型別。

6. Redis字串

Redis字串命令用於管理Redis中的字串值。以下是使用Redis字串命令的語法。

redis 127.0.0.1:6379> COMMAND KEY_NAME

範例

redis 127.0.0.1:6379> SET mykey "redis" 
OK 
redis 127.0.0.1:6379> GET mykey 
"redis"

在上面的例子中,SETGET是redis中的命令,而mykey是鍵的名稱。

Redis字串命令

下表列出了一些用於在Redis中管理字串的基本命令。

編號 命令 描述說明
1 SET key value 此命令設定指定鍵的值。
2 GET key 獲取指定鍵的值。
3 GETRANGE key start end 獲取儲存在鍵上的字串的子字串。
4 GETSET key value 設定鍵的字串值並返回其舊值。
5 GETBIT key offset 返回在鍵處儲存的字串值中偏移處的位值。
6 MGET key1 [key2..] 獲取所有給定鍵的值
7 SETBIT key offset value 儲存在鍵上的字串值中設定或清除偏移處的位
8 SETEX key seconds value 使用鍵和到期時間來設定值
9 SETNX key value 設定鍵的值,僅當鍵不存在時
10 SETRANGE key offset value 在指定偏移處開始的鍵處覆蓋字串的一部分
11 STRLEN key 獲取儲存在鍵中的值的長度
12 MSET key value [key value …] 為多個鍵分別設定它們的值
13 MSETNX key value [key value …] 為多個鍵分別設定它們的值,僅當鍵不存在時
14 PSETEX key milliseconds value 設定鍵的值和到期時間(以毫秒為單位)
15 INCR key 將鍵的整數值增加1
16 INCRBY key increment 將鍵的整數值按給定的數值增加
17 INCRBYFLOAT key increment 將鍵的浮點值按給定的數值增加
18 DECR key 將鍵的整數值減1
19 DECRBY key decrement 按給定數值減少鍵的整數值
20 APPEND key value 將指定值附加到鍵

7. Redis雜湊

Redis Hashes是字串欄位和字串值之間的對映(類似於PHP中的陣列型別)。 因此,它們是表示物件的完美資料型別。

在Redis中,每個雜湊(雜湊)可以儲存多達4億個鍵-值對。

範例

redis 127.0.0.1:6379> HMSET myhash name "redis tutorial" 
description "redis basic commands for caching" likes 20 visitors 23000 
OK 
127.0.0.1:6379> HGETALL myhash
1) "field1"
2) "Hello"
3) "field2"
4) "World"
5) "name"
6) "redis tutorial"

在上面的例子中,在名稱為’myhash‘的雜湊中設定了Redis教學的詳細資訊(名稱,描述,喜歡,存取者)。

8. Redis列表

Redis列表只是字串列表,按插入順序排序。可以在列表的頭部或尾部新增Redis列表中的元素。

列表的最大長度為2^32 - 1個元素(即4294967295,每個列表可儲存超過40億個元素)。

範例

redis 127.0.0.1:6379> LPUSH mylist "redis" 
(integer) 1 
redis 127.0.0.1:6379> LPUSH mylist "mongodb"
(integer) 2 
redis 127.0.0.1:6379> LPUSH mylist "mysql"
(integer) 3 
redis 127.0.0.1:6379> LRANGE mylist 0 10  
1) "mysql" 
2) "mongodb" 
3) "redis"

在上面的範例中,通過命令LPUSH將三個值插入到名稱為「mylist」的Redis列表中。

8. Redis集合

Redis集合是唯一字串的無序集合。 唯一值表示集合中不允許鍵中有重複的資料。

在Redis中設定新增,刪除和測試成員的存在(恆定時間O(1),而不考慮集合中包含的元素數量)。列表的最大長度為2^32 - 1個元素(即4294967295,每組集合超過40億個元素)。

範例

redis 127.0.0.1:6379> SADD myset "redis" 
(integer) 1 
redis 127.0.0.1:6379> SADD myset "mongodb" 
(integer) 1 
redis 127.0.0.1:6379> SADD myset "mysql" 
(integer) 1 
redis 127.0.0.1:6379> SADD myset "mysql" 
(integer) 0 
redis 127.0.0.1:6379> SMEMBERS "myset"  
1) "mysql" 
2) "mongodb" 
3) "redis"

在上面的範例中,通過命令SADD將三個值插入到名稱為「myset」的Redis集合中。

9. Redis傳送訂閱

Redis發佈訂閱(pub/sub)是一種訊息通訊模式:傳送者(pub)傳送訊息,訂閱者(sub)接收訊息。
Redis 發布訂閱(pub/sub)實現了訊息系統,傳送者(在redis術語中稱為發布者)在接收者(訂閱者)接收訊息時傳送訊息。傳送訊息的鏈路稱為通道。

在Redis中,用戶端可以訂閱任意數量的通道。

範例

以下範例說明了發布使用者概念的工作原理。 在以下範例中,一個用戶端訂閱名為「redisChat」的通道。

redis 127.0.0.1:6379> SUBSCRIBE redisChat  
Reading messages... (press Ctrl-C to quit) 
1) "subscribe" 
2) "redisChat" 
3) (integer) 1

現在,兩個用戶端在名稱為「redisChat」的相同通道上發布訊息,並且上述訂閱的用戶端接收訊息。

redis 127.0.0.1:6379> PUBLISH redisChat "Redis is a great caching technique"  
(integer) 1  
redis 127.0.0.1:6379> PUBLISH redisChat "Learn redis by yiibai"  
(integer) 1   
1) "message" 
2) "redisChat" 
3) "Redis is a great caching technique" 
1) "message" 
2) "redisChat" 
3) "Learn redis by yiibai"

10. Redis事務

Redis事務允許在單個步驟中執行一組命令。以下是事務的兩個屬性:

  • 事務中的所有命令作為單個隔離操作並按順序執行。不可以在執行Redis事務的中間向另一個用戶端發出的請求。
  • Redis事務也是原子的。原子意味著要麼處理所有命令,要麼都不處理。

語法範例

Redis事務由命令MULTI命令啟動,然後需要傳遞一個應該在事務中執行的命令列表,然後整個事務由EXEC命令執行。

redis 127.0.0.1:6379> MULTI 
OK 
List of commands here 
redis 127.0.0.1:6379> EXEC

範例

以下範例說明了如何啟動和執行Redis事務。

redis 127.0.0.1:6379> MULTI 
OK 
redis 127.0.0.1:6379> SET mykey "redis" 
QUEUED 
redis 127.0.0.1:6379> GET mykey 
QUEUED 
redis 127.0.0.1:6379> INCR visitors 
QUEUED 
redis 127.0.0.1:6379> EXEC  
1) OK 
2) "redis" 
3) (integer) 1

11. Redis指令碼

Redis指令碼用於使用Lua直譯器來執行指令碼。從Redis 2.6.0版開始內建到Redis中。使用指令碼的命令是EVAL命令。

語法

以下是EVAL命令的基本語法。

redis 127.0.0.1:6379> EVAL script numkeys key [key ...] arg [arg ...]

範例

以下範例說明了Redis指令碼的工作原理。

redis 127.0.0.1:6379> EVAL "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 
key2 first second  
1) "key1" 
2) "key2" 
3) "first" 
4) "second"

12. Redis連線

Redis中的連線命令基本上是用於管理與Redis伺服器的用戶端連線。

範例

以下範例說明用戶端如何向Redis伺服器驗證自身,並檢查伺服器是否正在執行。

redis 127.0.0.1:6379> AUTH "password" 
OK 
redis 127.0.0.1:6379> PING 
PONG

Redis連線命令

下表列出了與Redis連線相關的一些基本命令。

序號 命令 說明
1 AUTH password 使用給定的密碼驗證伺服器
2 ECHO message 列印給定的字串資訊
3 PING 檢查伺服器是否正在執行
4 QUIT 關閉當前連線
5 SELECT index 更改當前連線的所選資料庫

13. Redis伺服器

Redis伺服器命令基本上是用於管理Redis伺服器。

範例

以下範例說明了如何獲取有關伺服器的所有統計資訊和資訊。

127.0.0.1:6379> info
# Server
redis_version:2.8.4
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:8f6097d7914679ca
redis_mode:standalone
os:Linux 3.19.0-25-generic i686
arch_bits:32
multiplexing_api:epoll
gcc_version:4.8.2
process_id:1004
run_id:1e53acea2aa628199c4e438a3ed815d96eebc036
tcp_port:6379
uptime_in_seconds:888450
uptime_in_days:10
hz:10
lru_clock:1861984
config_file:/etc/redis/redis.conf

# Clients
connected_clients:1
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0

# Memory
used_memory:424872
used_memory_human:414.91K
used_memory_rss:6709248
used_memory_peak:424464
used_memory_peak_human:414.52K
used_memory_lua:22528
mem_fragmentation_ratio:15.79
mem_allocator:jemalloc-3.4.1

# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1486607123
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok

# Stats
total_connections_received:1
total_commands_processed:263
instantaneous_ops_per_sec:0
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:257
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:4793

# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

# CPU
used_cpu_sys:24.65
used_cpu_user:15.84
used_cpu_sys_children:0.08
used_cpu_user_children:0.00

# Keyspace
db0:keys=14,expires=0,avg_ttl=0
db1:keys=1,expires=0,avg_ttl=0
127.0.0.1:6379>

14. Redis備份

Redis資料庫可以使用安全的方案,使得進行連線的任何用戶端在執行命令之前都需要進行身份驗證。要保護Redis安全,需要在組態檔案中設定密碼。

範例

下面的範例顯示了保護Redis範例的步驟。

127.0.0.1:6379> CONFIG get requirepass 
1) "requirepass" 
2) ""

預設情況下,此屬性為空,這表示還沒有為此範例設定密碼。您可以通過執行以下命令更改此屬性。

127.0.0.1:6379> CONFIG set requirepass "yiibai" 
OK 
127.0.0.1:6379> CONFIG get requirepass 
1) "requirepass" 
2) "yiibai"

設定密碼後,如果任何用戶端執行命令而不進行身份驗證,則會返回一個(error) NOAUTH Authentication required.的錯誤資訊。 因此,用戶端需要使用AUTH命令來驗證。

語法

以下是AUTH命令的基本語法。

127.0.0.1:6379> AUTH password

範例

127.0.0.1:6379> AUTH "yiibai" 
OK 
127.0.0.1:6379> SET mykey "Test value" 
OK 
127.0.0.1:6379> GET mykey 
"Test value"

15. Redis用戶端連線

Redis在組態的監聽TCP埠和Unix通訊端上等待和接受用戶端的連線(如果已啟用)。 當接受新的用戶端連線時,執行以下操作 -

  • 由於Redis使用複用和非阻塞I/O,因此用戶端通訊端處於非阻塞狀態。
  • 設定TCP_NODELAY選項是為了確保連線不延遲。
  • 建立可讀檔案事件,以便Redis能夠在通訊端上讀取新資料時收集用戶端查詢。

最大客戶數

在Redis組態檔案(redis.conf)中,有一個名稱為maxclients的屬性,它描述了可以連線到Redis的用戶端的最大數量。

以下是命令的基本語法。

127.0.0.1:6379> config get maxclients
1) "maxclients"
2) "3984"

預設情況下,此屬性設定為10000(取決於作業系統的檔案描述符限制的最大數量),但您可以更改此屬性。

範例

在以下範例中,我們已將用戶端的最大數目設定為100000,並啟動伺服器。

yiibai@ubuntu:~$ redis-server --maxclients 100000

用戶端命令

編號 命令 描述
1 CLIENT LIST 返回連線到Redis伺服器的用戶端列表
2 CLIENT SETNAME 為當前連線分配/設定新的名稱
3 CLIENT GETNAME 返回由CLIENT SETNAME設定的當前連線的名稱
4 CLIENT PAUSE 這是一個連線控制命令,能夠將所有Redis用戶端按指定的時間量(以毫秒為單位)掛起
5 CLIENT KILL 此命令關閉指定的用戶端連線。

16. Redis管道

Redis是一個TCP伺服器,支援請求/響應協定。 在Redis中,請求通過以下步驟完成:

  • 用戶端向伺服器傳送查詢,並從通訊端讀取,通常以阻塞的方式,用於伺服器響應。
  • 伺服器處理命令並將響應傳送回用戶端。

管道的意義

管道的基本含義是,用戶端可以向伺服器傳送多個請求,而不必等待回復,並最終在一個步驟中讀取回復。

範例

要檢查Redis管道,只需啟動Redis範例,並在終端中鍵入以下命令。

$(echo -en "PING\r\n SET tutorial redis\r\nGET tutorial\r\nINCR 
visitor\r\nINCR visitor\r\nINCR visitor\r\n"; sleep 10) | nc localhost 6379  
+PONG 
+OK 
redis 
:1 
:2 
:3

在上面的例子中,我們將使用PING命令檢查Redis連線。這裡設定了一個名稱為tutorial的字串,值為redis。 然後得到鍵值,並增加 visitor 數量三次。 在結果中,我們可以看到所有命令都提交到Redis一次,Redis在一個步驟中提供所有命令的輸出。

管道的好處

這種技術的好處是大大提高了協定效能。通過管道從連線到本地主機速度增加五倍,因特網連線的至少快一百倍。

17. Redis分割區

分割區是將資料拆分為多個Redis範例的過程,因此每個範例只包含一部分鍵。

分割區的優點

  • 它允許更大的資料庫,使用更多計算機的記憶體總和。如果沒有分割區,則限制為單個計算機可以支援的記憶體量。
  • 它允許將計算能力擴充套件到多個核心和多個計算機,並將網路頻寬擴充套件到多個計算機和網路介面卡。

分割區的缺點

  • 通常不支援涉及多個鍵的操作。 例如,如果兩個集合儲存在對映到不同Redis範例的鍵中,則不能執行兩個集合之間的交集操作。
  • 不能使用涉及多個鍵的Redis事務。
  • 分割區粒度是關鍵,因此不可能使用單個巨大的鍵(如非常大的排序集合)來分割資料集。
  • 使用分割區時,資料處理更複雜。 例如,必須處理多個RDB/AOF檔案,並獲得資料的備份,您需要聚合來自多個範例和主機的永續性檔案。
  • 新增和刪除容量可能很複雜。 例如,Redis Cluster支援大多數透明的資料重新平衡,具有在執行時新增和刪除節點的能力。但是,其他系統(如用戶端分割區和代理)不支援此功能。但可以使用一種叫作Presharding的技術來處理這方面的問題。

分割區型別

Redis中有兩種型別的分割區。假設有四個Redis範例:R0R1R2R3以許多代表使用者的鍵,如user:1user:2,…等等。

範圍分割區

範圍分割區通過將物件的範圍對映到特定的Redis範例來實現。假設在上面範例中,從ID 0到ID 10000的使用者將進入範例R0,而從ID 10001到ID 20000的使用者將進入範例R1,以此類推。

雜湊分割區

在這種型別的分割區中,使用雜湊函式(例如,模函式)將鍵轉換成數位,然後將資料儲存在不同的Redis範例中。

18. Java連線Redis

在Java程式中使用Redis之前,需要確保在機器上安裝了Redis的Java驅動程式和Java環境。可以先在將Java電腦上並組態好環境。

安裝

現在,讓我們看看如何設定Redis Java驅動程式。

Java連線到Redis伺服器

請參考以下一個簡單的範例程式碼 -

import redis.clients.jedis.Jedis; 

public class RedisJava { 
   public static void main(String[] args) { 
      //Connecting to Redis server on localhost 
      Jedis jedis = new Jedis("localhost"); 
      System.out.println("Connection to server sucessfully"); 
      //check whether server is running or not 
      System.out.println("Server is running: "+jedis.ping()); 
   } 
}

現在,編譯並執行上面的程式來測試與Redis伺服器的連線。可以根據需要更改路徑。假設jedis.jar的當前版本在當前路徑中可以使用。
執行上面程式碼,將生成以下結果 -

$javac RedisJava.java 
$java RedisJava 
Connection to server sucessfully 
Server is running: PONG

Redis Java字串範例

import redis.clients.jedis.Jedis; 

public class RedisStringJava { 
   public static void main(String[] args) { 
      //Connecting to Redis server on localhost 
      Jedis jedis = new Jedis("localhost"); 
      System.out.println("Connection to server sucessfully"); 
      //set the data in redis string 
      jedis.set("tutorial-name", "Redis tutorial"); 
      // Get the stored data and print it 
      System.out.println("Stored string in redis:: "+ jedis.get("tutorialname")); 
   } 
}

執行上面程式碼,將生成以下結果 -

$javac RedisStringJava.java 
$java RedisStringJava 
Connection to server sucessfully 
Stored string in redis:: Redis tutorial

Redis Java列表範例

import redis.clients.jedis.Jedis; 

public class RedisListJava { 
   public static void main(String[] args) { 
      //Connecting to Redis server on localhost 
      Jedis jedis = new Jedis("localhost"); 
      System.out.println("Connection to server sucessfully"); 

      //store data in redis list 
      jedis.lpush("tutorial-list", "Redis"); 
      jedis.lpush("tutorial-list", "Mongodb"); 
      jedis.lpush("tutorial-list", "Mysql"); 
      // Get the stored data and print it 
      List<String> list = jedis.lrange("tutorial-list", 0 ,5); 

      for(int i = 0; i<list.size(); i++) { 
         System.out.println("Stored string in redis:: "+list.get(i)); 
      } 
   } 
}

執行上面程式碼,將生成以下結果 -

$javac RedisListJava.java 
$java RedisListJava 
Connection to server sucessfully 
Stored string in redis:: Redis 
Stored string in redis:: Mongodb 
Stored string in redis:: Mysql

Redis Java鍵範例

import redis.clients.jedis.Jedis; 

public class RedisKeyJava { 
   public static void main(String[] args) { 
      //Connecting to Redis server on localhost 
      Jedis jedis = new Jedis("localhost"); 
      System.out.println("Connection to server sucessfully"); 
      //store data in redis list 
      // Get the stored data and print it 
      List<String> list = jedis.keys("*"); 

      for(int i = 0; i<list.size(); i++) { 
         System.out.println("List of stored keys:: "+list.get(i)); 
      } 
   } 
}

執行上面程式碼,將生成以下結果 -

$javac RedisKeyJava.java 
$java RedisKeyJava 
Connection to server sucessfully 
List of stored keys:: tutorial-name 
List of stored keys:: tutorial-list

19. PHP連線Redis

在php程式中使用Redis之前,需要確保在機器上安裝了Redis的PHP驅動程式和PHP環境。可以先在將PHP電腦上並組態好環境。

安裝

現在,讓我們看看如何設定Redis PHP驅動程式。
從github庫下載phpredis=> http://github.com/nicolasff/phpredis。 當下載它之後,提取檔案到phpredis目錄。在Ubuntu上,安裝以下擴充套件。

cd phpredis 
sudo phpize 
sudo ./configure 
sudo make 
sudo make install

現在,將「modules」檔案夾的內容複製並貼上到PHP擴充套件目錄中,並在php.ini中新增以下行。

extension = redis.so

現在,Redis PHP安裝完成!

使用連線到Redis伺服器

<?php 
   //Connecting to Redis server on localhost 
   $redis = new Redis(); 
   $redis->connect('127.0.0.1', 6379); 
   echo "Connection to server sucessfully"; 
   //check whether server is running or not 
   echo "Server is running: ".$redis->ping(); 
?>

當程式執行時,將產生以下結果。

Connection to server sucessfully 
Server is running: PONG

Redis PHP字串範例

<?php 
   //Connecting to Redis server on localhost 
   $redis = new Redis(); 
   $redis->connect('127.0.0.1', 6379); 
   echo "Connection to server sucessfully"; 
   //set the data in redis string 
   $redis->set("tutorial-name", "Redis tutorial"); 
   // Get the stored data and print it 
   echo "Stored string in redis:: " .$redis→get("tutorial-name"); 
?>

執行上面程式碼,將生成以下結果 -

Connection to server sucessfully 
Stored string in redis:: Redis tutorial

Redis php列表範例

<?php 
   //Connecting to Redis server on localhost 
   $redis = new Redis(); 
   $redis->connect('127.0.0.1', 6379); 
   echo "Connection to server sucessfully"; 
   //store data in redis list 
   $redis->lpush("tutorial-list", "Redis"); 
   $redis->lpush("tutorial-list", "Mongodb"); 
   $redis->lpush("tutorial-list", "Mysql");  

   // Get the stored data and print it 
   $arList = $redis->lrange("tutorial-list", 0 ,5); 
   echo "Stored string in redis:: "; 
   print_r($arList); 
?>

執行上面程式碼,將生成以下結果 -

Connection to server sucessfully 
Stored string in redis:: 
Redis 
Mongodb 
Mysql

Redis php鍵範例

<?php 
   //Connecting to Redis server on localhost 
   $redis = new Redis(); 
   $redis->connect('127.0.0.1', 6379); 
   echo "Connection to server sucessfully"; 
   // Get the stored keys and print it 
   $arList = $redis->keys("*"); 
   echo "Stored keys in redis:: " 
   print_r($arList); 
?>

執行上面程式碼,將生成以下結果 -

Connection to server sucessfully 
Stored string in redis:: 
tutorial-name 
tutorial-list

20. C#連線Redis

前面我們已經準備成功開啟Redis服務,其埠號為6379,接下來我們就看看如何使用C#語言來操作Redis。就如MongoDB一樣,要操作Redis服務,自然就需要下載C#的用戶端,這裡通過Nuget下載了「ServiceStack.Redis」用戶端,引入成功之後,就可以使用C#來對Redis服務進行操作了。

由於Redis一般是用來作為快取的,也就是一般我們把一些不經常改變的資料通過Redis快取起來,之後使用者的請求就不需要再存取資料庫,而可以直接從Redis快取中直接獲取,這樣就可以減輕資料庫伺服器的壓力以及加快響應速度。既然是用來做快取的,也就是通過指定key值來把對應Value儲存起來,之後再根據key值來獲得之前快取的值。具體的操作程式碼如下所示,這裡就不過多介紹了。

請參考以下程式碼 -

class Program
    {
        static void Main(string[] args)
        {
            //在Redis中儲存常用的5種資料型別:String,Hash,List,SetSorted set
            var client = new RedisClient("127.0.0.1", 6379);
            //AddString(client);
            //AddHash(client);
            //AddList(client);
            //AddSet(client);
            AddSetSorted(client);

            Console.ReadLine();
        }

        private static void AddString(RedisClient client)
        {
            var timeOut = new TimeSpan(0,0,0,30);
            client.Add("Test", "Learninghard", timeOut);
            while (true)
            {
                if (client.ContainsKey("Test"))
                {
                    Console.WriteLine("String Key: Test -Value: {0}, 當前時間: {1}", client.Get<string>("Test"), DateTime.Now);
                    Thread.Sleep(10000);
                }
                else
                {
                    Console.WriteLine("Value 已經過期了,當前時間:{0}", DateTime.Now);
                    break;
                }
            }

            var person = new Person() {Name = "Learninghard", Age = 26};
            client.Add("lh", person);
            var cachePerson = client.Get<Person>("lh");
            Console.WriteLine("Person's Name is : {0}, Age: {1}", cachePerson.Name, cachePerson.Age);
        }

        private static void AddHash(RedisClient client)
        {
            if (client == null) throw new ArgumentNullException("client");

            client.SetEntryInHash("HashId", "Name", "Learninghard");
            client.SetEntryInHash("HashId", "Age", "26");
            client.SetEntryInHash("HashId", "Sex", "男");

            var hashKeys = client.GetHashKeys("HashId");
            foreach (var key in hashKeys)
            {
                Console.WriteLine("HashId--Key:{0}", key);
            }

            var haskValues = client.GetHashValues("HashId");
            foreach (var value in haskValues)
            {
                Console.WriteLine("HashId--Value:{0}", value);
            }

            var allKeys = client.GetAllKeys(); //獲取所有的key。
            foreach (var key in allKeys)
            {
                Console.WriteLine("AllKey--Key:{0}", key);
            }
        }

        private static void AddList(RedisClient client)
        {
            if (client == null) throw new ArgumentNullException("client");

            client.EnqueueItemOnList("QueueListId", "1.Learnghard");  //入隊
            client.EnqueueItemOnList("QueueListId", "2.張三");
            client.EnqueueItemOnList("QueueListId", "3.李四");
            client.EnqueueItemOnList("QueueListId", "4.王五");
            var queueCount = client.GetListCount("QueueListId");

            for (var i = 0; i < queueCount; i++)
            {
                Console.WriteLine("QueueListId出隊值:{0}", client.DequeueItemFromList("QueueListId"));   //出隊(佇列先進先出)
            }

            client.PushItemToList("StackListId", "1.Learninghard");  //入棧
            client.PushItemToList("StackListId", "2.張三");
            client.PushItemToList("StackListId", "3.李四");
            client.PushItemToList("StackListId", "4.王五");

            var stackCount = client.GetListCount("StackListId");
            for (var i = 0; i < stackCount; i++)
            {
                Console.WriteLine("StackListId出棧值:{0}", client.PopItemFromList("StackListId"));   //出棧(棧先進後出)
            }
        }

        //它是string型別的無序集合。set是通過hash table實現的,新增,刪除和查詢,對集合我們可以取並集,交集,差集
        private static void AddSet(RedisClient client)
        {
            if (client == null) throw new ArgumentNullException("client");

            client.AddItemToSet("Set1001", "A");
            client.AddItemToSet("Set1001", "B");
            client.AddItemToSet("Set1001", "C");
            client.AddItemToSet("Set1001", "D");
            var hastset1 = client.GetAllItemsFromSet("Set1001");
            foreach (var item in hastset1)
            {
                Console.WriteLine("Set無序集合Value:{0}", item); //出來的結果是無須的
            }

            client.AddItemToSet("Set1002", "K");
            client.AddItemToSet("Set1002", "C");
            client.AddItemToSet("Set1002", "A");
            client.AddItemToSet("Set1002", "J");
            var hastset2 = client.GetAllItemsFromSet("Set1002");
            foreach (var item in hastset2)
            {
                Console.WriteLine("Set無序集合ValueB:{0}", item); //出來的結果是無須的
            }

            var hashUnion = client.GetUnionFromSets(new string[] { "Set1001", "Set1002" });
            foreach (var item in hashUnion)
            {
                Console.WriteLine("求Set1001和Set1002的並集:{0}", item); //並集
            }

            var hashG = client.GetIntersectFromSets(new string[] { "Set1001", "Set1002" });
            foreach (var item in hashG)
            {
                Console.WriteLine("求Set1001和Set1002的交集:{0}", item);  //交集
            }

            var hashD = client.GetDifferencesFromSet("Set1001", new string[] { "Set1002" });  //[返回存在於第一個集合,但是不存在於其他集合的資料。差集]
            foreach (var item in hashD)
            {
                Console.WriteLine("求Set1001和Set1002的差集:{0}", item);  //差集
            }

        }

        /*
        sorted set 是set的一個升級版本,它在set的基礎上增加了一個順序的屬性,這一屬性在新增修改.元素的時候可以指定,
        * 每次指定後,zset(表示有序集合)會自動重新按新的值調整順序。可以理解為有列的表,一列存 value,一列存順序。操作中key理解為zset的名字.
        */
        private static void AddSetSorted(RedisClient client)
        {
            if (client == null) throw new ArgumentNullException("client");

            client.AddItemToSortedSet("SetSorted1001", "A");
            client.AddItemToSortedSet("SetSorted1001", "B");
            client.AddItemToSortedSet("SetSorted1001", "C");
            var listSetSorted = client.GetAllItemsFromSortedSet("SetSorted1001");
            foreach (var item in listSetSorted)
            {
                Console.WriteLine("SetSorted有序集合{0}", item);
            }

            client.AddItemToSortedSet("SetSorted1002", "A", 400);
            client.AddItemToSortedSet("SetSorted1002", "D", 200);
            client.AddItemToSortedSet("SetSorted1002", "B", 300);

            // 升序獲取第一個值:"D"
            var list = client.GetRangeFromSortedSet("SetSorted1002", 0, 0);

            foreach (var item in list)
            {
                Console.WriteLine(item);
            }

            //降序獲取第一個值:"A"
            list = client.GetRangeFromSortedSetDesc("SetSorted1002", 0, 0);

            foreach (var item in list)
            {
                Console.WriteLine(item);
            }
        }
    }

    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

如何要想檢視自己操作是否成功,也可以像MongoDB那樣下載一個用戶端工具,這裡推薦一款Redis Desktop Manager。這個工具就相當於SQL Server的用戶端工具一樣。通過這款工具可以檢視Redis伺服器中儲存的資料和對應格式。其使用也非常簡單,只需要新增一個Redis服務連線即可。該工具的下載地址為:http://pan.baidu.com/s/1sjp55Ul