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
Shell

這將在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
Shell

檢查Redis是否正在工作

[yiibai@ubuntu:~]$ redis-cli
Shell

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

redis 127.0.0.1:6379>
Shell

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

redis 127.0.0.1:6379> ping 
PONG
Shell

這表明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
Shell

示例

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

要獲取所有配置設置,請使用*代替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"
Shell

編輯配置

要更新配置,可以直接編輯redis.conf文件,也可以通過CONFIG set命令更新配置。

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

redis 127.0.0.1:6379> CONFIG SET CONFIG_SETTING_NAME NEW_CONFIG_VALUE
Shell

示例

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

3. Redis數據類型

Redis支持5種數據類型。

字符串

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

示例

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

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

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

散列/哈希

Redis散列/哈希(Hashes)是鍵值對的集合。Redis散列/哈希是字符串字段和字符串值之間的映射。因此,它們用於表示對象。

示例

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

在上述示例中,散列/哈希數據類型用於存儲包含用戶的基本信息的用戶對象。這裏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"
Shell

列表的最大長度爲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"
Shell

注意 - 在上面的示例中,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"
Shell

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

4. Redis命令

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

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

[yiibai@ubuntu:~]$ redis-cli
Shell

示例
以下示例說明了如何啓動Redis客戶端。

要啓動Redis客戶端,請打開終端並鍵入命令redis-cli。 這將連接到您的本地Redis服務器,現在可以運行任何的Redis命令了。

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

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

在遠程服務器上運行命令

要在Redis遠程服務器上運行命令,需要通過客戶端redis-cli連接到服務器

語法

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

示例
以下示例顯示如何連接到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
Shell

5. Redis鍵命令

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

語法

redis 127.0.0.1:6379> COMMAND KEY_NAME
Shell

示例

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)
Shell

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

Redis鍵命令

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

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

6. Redis字符串

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

redis 127.0.0.1:6379> COMMAND KEY_NAME
Shell

示例

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

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

Redis字符串命令

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

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

在上面的例子中,在名稱爲’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"
Shell

在上面的示例中,通過命令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"
Shell

在上面的示例中,通過命令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
Shell

現在,兩個客戶端在名稱爲“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"
Shell

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
Shell

示例

以下示例說明了如何啓動和執行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
Shell

11. Redis腳本

Redis腳本用於使用Lua解釋器來執行腳本。從Redis 2.6.0版開始內置到Redis中。使用腳本的命令是EVAL命令。

語法

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

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

示例

以下示例說明了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"
Shell

12. Redis連接

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

示例

以下示例說明客戶端如何向Redis服務器驗證自身,並檢查服務器是否正在運行。

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

Redis連接命令

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

序號命令說明
1AUTH password使用給定的密碼驗證服務器
2ECHO message打印給定的字符串信息
3PING檢查服務器是否正在運行
4QUIT關閉當前連接
5SELECT 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>
Shell

14. Redis備份

Redis數據庫可以使用安全的方案,使得進行連接的任何客戶端在執行命令之前都需要進行身份驗證。要保護Redis安全,需要在配置文件中設置密碼。

示例

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

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

默認情況下,此屬性爲空,這表示還沒有爲此實例設置密碼。您可以通過執行以下命令更改此屬性。

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

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

語法

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

127.0.0.1:6379> AUTH password
Shell

示例

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"
Shell

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"
Shell

默認情況下,此屬性設置爲10000(取決於操作系統的文件描述符限制的最大數量),但您可以更改此屬性。

示例

在以下示例中,我們已將客戶端的最大數目設置爲100000,並啓動服務器。

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

客戶端命令

編號命令描述
1CLIENT LIST返回連接到Redis服務器的客戶端列表
2CLIENT SETNAME爲當前連接分配/設置新的名稱
3CLIENT GETNAME返回由CLIENT SETNAME設置的當前連接的名稱
4CLIENT PAUSE這是一個連接控制命令,能夠將所有Redis客戶端按指定的時間量(以毫秒爲單位)掛起
5CLIENT 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
Shell

在上面的例子中,我們將使用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()); 
   } 
}
Java

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

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

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")); 
   } 
}
Java

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

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

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)); 
      } 
   } 
}
Java

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

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

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)); 
      } 
   } 
}
Java

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

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

19. 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; }
    }
C#

如何要想查看自己操作是否成功,也可以像MongoDB那樣下載一個客戶端工具,這裏推薦一款Redis Desktop Manager。這個工具就相當於SQL Server的客戶端工具一樣。通過這款工具可以查看Redis服務器中保存的數據和對應格式。其使用也非常簡單,只需要添加一個Redis服務連接即可。該工具的下載地址爲:http://pan.baidu.com/s/1sjp55Ul

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章