Redis 教程 Java工程師學習知識點 Redis從單機到集羣,一步步教你環境部署以及使用 使用Spring + Jedis集成Redis

1. Redis簡介及安裝

1.1 Redis 簡介

Redis 是徹底開源免費的,遵照BSD協議,是一個高性能的key-value數據庫。html

Redis 與其餘 key - value 緩存產品有如下三個特色:node

  • Redis支持數據的持久化,能夠將內存中的數據保存在磁盤中,重啓的時候能夠再次加載進行使用。
  • Redis不只僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
  • Redis支持數據的備份,即master-slave模式的數據備份。

1.2 Redis 優點

  • 性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
  • 豐富的數據類型 – Redis支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操做。
  • 原子 – Redis的全部操做都是原子性的,同時Redis還支持對幾個操做全並後的原子性執行。
  • 豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過時等等特性。

1.3 Redis與其餘key-value存儲有什麼不一樣?

  • Redis有着更爲複雜的數據結構而且提供對他們的原子性操做,這是一個不一樣於其餘數據庫的進化路徑。Redis的數據類型都是基於基本數據結構的同時對程序員透明,無需進行額外的抽象。git

  • Redis運行在內存中可是能夠持久化到磁盤,因此在對不一樣數據集進行高速讀寫時須要權衡內存,由於數據量不能大於硬件內存。在內存數據庫方面的另外一個優勢是,相比在磁盤上相同的複雜的數據結構,在內存中操做起來很是簡單,這樣Redis能夠作不少內部複雜性很強的事情。同時,在磁盤格式方面他們是緊湊的以追加的方式產生的,由於他們並不須要進行隨機訪問。程序員

2. Redis基礎知識、數據類型、Keys的操做命令

2.1 數據類型

Redis支持五種數據類型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。github

2.2 Redis 鍵(key)

Redis 鍵命令用於管理 redis 的鍵。redis

語法算法

Redis 鍵命令的基本語法以下:mongodb

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緩存

2.2.1 Key命令

1    DEL key
該命令用於在 key 存在時刪除 key。
2    DUMP key 
序列化給定 key ,並返回被序列化的值。
3    EXISTS key 
檢查給定 key 是否存在。
4    EXPIRE key seconds
爲給定 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    TYPE key 
返回 key 所儲存的值的類型。

3. Redis對不一樣數據類型的操做命令使用

3.1 String(字符串)

string是redis最基本的類型,你能夠理解成與Memcached如出一轍的類型,一個key對應一個value。

string類型是二進制安全的。意思是redis的string能夠包含任何數據。好比jpg圖片或者序列化的對象 。

string類型是Redis最基本的數據類型,一個鍵最大能存儲512MB。

實例

redis 127.0.0.1:6379> SET name "runoob"
OK
redis 127.0.0.1:6379> GET name
"runoob"

在以上實例中咱們使用了 Redis 的 SET 和 GET 命令。鍵爲 name,對應的值爲 runoob

注意:一個鍵最大能存儲512MB。

3.2 Hash(哈希)

Redis hash 是一個鍵名對集合。

Redis hash是一個string類型的field和value的映射表,hash特別適合用於存儲對象。

實例

127.0.0.1:6379> HMSET user:1 username runoob password runoob points 200
OK
127.0.0.1:6379> HGETALL user:1
1) "username"
2) "runoob"
3) "password"
4) "runoob"
5) "points"
6) "200"

以上實例中 hash 數據類型存儲了包含用戶腳本信息的用戶對象。 實例中咱們使用了 Redis HMSET, HGETALL 命令,user:1爲鍵值。

每一個 hash 能夠存儲 232 -1 鍵值對(40多億)。

3.3 List(列表)

Redis 列表是簡單的字符串列表,按照插入順序排序。你能夠添加一個元素到列表的頭部(左邊)或者尾部(右邊)。

實例

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多億)。

3.4 Set(集合)

Redis的Set是string類型的無序集合。

集合是經過哈希表實現的,因此添加,刪除,查找的複雜度都是O(1)。

sadd 命令

添加一個string元素到,key對應的set集合中,成功返回1,若是元素已經在集合中返回0,key對應的set不存在返回錯誤。

sadd key member

實例

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) "rabitmq"
2) "mongodb"
3) "redis"

注意:以上實例中 rabitmq 添加了兩次,但根據集合內元素的惟一性,第二次插入的元素將被忽略。

集合中最大的成員數爲 232 - 1(4294967295, 每一個集合可存儲40多億個成員)。

3.5 zset(sorted set:有序集合)

Redis zset 和 set 同樣也是string類型元素的集合,且不容許重複的成員。

 

不一樣的是每一個元素都會關聯一個double類型的分數。redis正是經過分數來爲集合中的成員進行從小到大的排序。

zset的成員是惟一的,但分數(score)卻能夠重複。

zadd 命令

添加元素到集合,元素在集合中存在則更新對應score

zadd key score member 

實例

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) "redis"
2) "mongodb"
3) "rabitmq"

4. Redis核心配置分析

Redis 的配置文件位於 Redis 安裝目錄下,文件名爲 redis.conf。

你能夠經過 CONFIG 命令查看或設置配置項。

語法

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"

使用 * 號獲取全部配置項:

實例

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) ""
 11) "pidfile"
 12) "/var/run/redis.pid"
 13) "maxmemory"
 14) "0"
 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) "hll-sparse-max-bytes"
 40) "3000"
 41) "lua-time-limit"
 42) "5000"
 43) "slowlog-log-slower-than"
 44) "10000"
 45) "latency-monitor-threshold"
 46) "0"
 47) "slowlog-max-len"
 48) "128"
 49) "port"
 50) "6379"
 51) "tcp-backlog"
 52) "511"
 53) "databases"
 54) "16"
 55) "repl-ping-slave-period"
 56) "10"
 57) "repl-timeout"
 58) "60"
 59) "repl-backlog-size"
 60) "1048576"
 61) "repl-backlog-ttl"
 62) "3600"
 63) "maxclients"
 64) "4064"
 65) "watchdog-period"
 66) "0"
 67) "slave-priority"
 68) "100"
 69) "min-slaves-to-write"
 70) "0"
 71) "min-slaves-max-lag"
 72) "10"
 73) "hz"
 74) "10"
 75) "no-appendfsync-on-rewrite"
 76) "no"
 77) "slave-serve-stale-data"
 78) "yes"
 79) "slave-read-only"
 80) "yes"
 81) "stop-writes-on-bgsave-error"
 82) "yes"
 83) "daemonize"
 84) "no"
 85) "rdbcompression"
 86) "yes"
 87) "rdbchecksum"
 88) "yes"
 89) "activerehashing"
 90) "yes"
 91) "repl-disable-tcp-nodelay"
 92) "no"
 93) "aof-rewrite-incremental-fsync"
 94) "yes"
 95) "appendonly"
 96) "no"
 97) "dir"
 98) "/home/deepak/Downloads/redis-2.8.13/src"
 99) "maxmemory-policy"
100) "volatile-lru"
101) "appendfsync"
102) "everysec"
103) "save"
104) "3600 1 300 100 60 10000"
105) "loglevel"
106) "notice"
107) "client-output-buffer-limit"
108) "normal 0 0 0 slave 268435456 67108864 60 pubsub 33554432 8388608 60"
109) "unixsocketperm"
110) "0"
111) "slaveof"
112) ""
113) "notify-keyspace-events"
114) ""
115) "bind"
116) ""

4.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"

4.2 參數說明

redis.conf 配置項說明以下:

1. Redis默認不是以守護進程的方式運行,能夠經過該配置項修改,使用yes啓用守護進程

    daemonize no

2. 當Redis以守護進程方式運行時,Redis默認會把pid寫入/var/run/redis.pid文件,能夠經過pidfile指定

    pidfile /var/run/redis.pid

3. 指定Redis監聽端口,默認端口爲6379,做者在本身的一篇博文中解釋了爲何選用6379做爲默認端口,由於6379在手機按鍵上MERZ對應的號碼,而MERZ取自意大利歌女Alessia Merz的名字

    port 6379

4. 綁定的主機地址

    bind 127.0.0.1

5.當 客戶端閒置多長時間後關閉鏈接,若是指定爲0,表示關閉該功能

    timeout 300

6. 指定日誌記錄級別,Redis總共支持四個級別:debug、verbose、notice、warning,默認爲verbose

    loglevel verbose

7. 日誌記錄方式,默認爲標準輸出,若是配置Redis爲守護進程方式運行,而這裏又配置爲日誌記錄方式爲標準輸出,則日誌將會發送給/dev/null

    logfile stdout

8. 設置數據庫的數量,默認數據庫爲0,可使用SELECT <dbid>命令在鏈接上指定數據庫id

    databases 16

9. 指定在多長時間內,有多少次更新操做,就將數據同步到數據文件,能夠多個條件配合

    save <seconds> <changes>

    Redis默認配置文件中提供了三個條件:

    save 900 1

    save 300 10

    save 60 10000

    分別表示900秒(15分鐘)內有1個更改,300秒(5分鐘)內有10個更改以及60秒內有10000個更改。

10. 指定存儲至本地數據庫時是否壓縮數據,默認爲yes,Redis採用LZF壓縮,若是爲了節省CPU時間,能夠關閉該選項,但會致使數據庫文件變的巨大

    rdbcompression yes

11. 指定本地數據庫文件名,默認值爲dump.rdb

    dbfilename dump.rdb

12. 指定本地數據庫存放目錄

    dir ./

13. 設置當本機爲slav服務時,設置master服務的IP地址及端口,在Redis啓動時,它會自動從master進行數據同步

    slaveof <masterip> <masterport>

14. 當master服務設置了密碼保護時,slav服務鏈接master的密碼

    masterauth <master-password>

15. 設置Redis鏈接密碼,若是配置了鏈接密碼,客戶端在鏈接Redis時須要經過AUTH <password>命令提供密碼,默認關閉

    requirepass foobared

16. 設置同一時間最大客戶端鏈接數,默認無限制,Redis能夠同時打開的客戶端鏈接數爲Redis進程能夠打開的最大文件描述符數,若是設置 maxclients 0,表示不做限制。當客戶端鏈接數到達限制時,Redis會關閉新的鏈接並向客戶端返回max number of clients reached錯誤信息

    maxclients 128

17. 指定Redis最大內存限制,Redis在啓動時會把數據加載到內存中,達到最大內存後,Redis會先嚐試清除已到期或即將到期的Key,當此方法處理 後,仍然到達最大內存設置,將沒法再進行寫入操做,但仍然能夠進行讀取操做。Redis新的vm機制,會把Key存放內存,Value會存放在swap區

    maxmemory <bytes>

18. 指定是否在每次更新操做後進行日誌記錄,Redis在默認狀況下是異步的把數據寫入磁盤,若是不開啓,可能會在斷電時致使一段時間內的數據丟失。由於 redis自己同步數據文件是按上面save條件來同步的,因此有的數據會在一段時間內只存在於內存中。默認爲no

    appendonly no

19. 指定更新日誌文件名,默認爲appendonly.aof

     appendfilename appendonly.aof

20. 指定更新日誌條件,共有3個可選值: 
    no:表示等操做系統進行數據緩存同步到磁盤(快) 
    always:表示每次更新操做後手動調用fsync()將數據寫到磁盤(慢,安全) 
    everysec:表示每秒同步一次(折衷,默認值)

    appendfsync everysec

21. 指定是否啓用虛擬內存機制,默認值爲no,簡單的介紹一下,VM機制將數據分頁存放,由Redis將訪問量較少的頁即冷數據swap到磁盤上,訪問多的頁面由磁盤自動換出到內存中(在後面的文章我會仔細分析Redis的VM機制)

     vm-enabled no

22. 虛擬內存文件路徑,默認值爲/tmp/redis.swap,不可多個Redis實例共享

     vm-swap-file /tmp/redis.swap

23. 將全部大於vm-max-memory的數據存入虛擬內存,不管vm-max-memory設置多小,全部索引數據都是內存存儲的(Redis的索引數據 就是keys),也就是說,當vm-max-memory設置爲0的時候,實際上是全部value都存在於磁盤。默認值爲0

     vm-max-memory 0

24. Redis swap文件分紅了不少的page,一個對象能夠保存在多個page上面,但一個page上不能被多個對象共享,vm-page-size是要根據存儲的 數據大小來設定的,做者建議若是存儲不少小對象,page大小最好設置爲32或者64bytes;若是存儲很大大對象,則可使用更大的page,若是不 肯定,就使用默認值

     vm-page-size 32

25. 設置swap文件中的page數量,因爲頁表(一種表示頁面空閒或使用的bitmap)是在放在內存中的,,在磁盤上每8個pages將消耗1byte的內存。

     vm-pages 134217728

26. 設置訪問swap文件的線程數,最好不要超過機器的核數,若是設置爲0,那麼全部對swap文件的操做都是串行的,可能會形成比較長時間的延遲。默認值爲4

     vm-max-threads 4

27. 設置在向客戶端應答時,是否把較小的包合併爲一個包發送,默認爲開啓

    glueoutputbuf yes

28. 指定在超過必定的數量或者最大的元素超過某一臨界值時,採用一種特殊的哈希算法

    hash-max-zipmap-entries 64

    hash-max-zipmap-value 512

29. 指定是否激活重置哈希,默認爲開啓(後面在介紹Redis的哈希算法時具體介紹)

    activerehashing yes

30. 指定包含其它的配置文件,能夠在同一主機上多個Redis實例之間使用同一份配置文件,而同時各個實例又擁有本身的特定配置文件

    include /path/to/local.conf

5. Redis持久化概述,RDB原理、AOF原理分析

因爲Redis是基於內存的數據庫,爲了保證數據的可用性,Redis提供了兩種數據持久化機制:RDB和AOF,下面對這兩種持久化方式加以分析。

5.1 RDB

運行原理

RDB模式能夠在指定的時間間隔內生成內存中整個數據集的持久化快照。快照文件默認被存儲在當前文件夾中,名稱爲dump.rdb,能夠經過dir和dbfilename參數來修改默認值。

1.redis調用fork函數複製當前進行的一個副本-子進程 2.父進程繼續接收並處理客戶端發來的命令 3.子進行將內存中的數據寫入一個臨時的dump文件 4.子進程寫入完成後,會用新的臨時dump文件替換就的rdb文件 5.一次持久化完成
  • 1
  • 2
  • 3
  • 4
  • 5

在執行fork函數的時候,操做系統會使用寫時複製(copy-on-write)策略,也就是說在調用fork的一刻,父子進行有相同的內存模型,當父進程要修改其中的某片數據時,操做系統會將該片數據複製一份,從而保證不影響子進程。

rdb文件是通過壓縮的文件,佔用的空間比較小,更有利於傳輸,而且數據恢復速度也比較快。

RDB模式的優勢

1.rdb持久化文件很緊湊,佔用空間更小。 
2.rdb保存的是基於時間點的數據快照,更適合數據的備份和容災 
3.利用rdb文件進行數據恢復時,速度更快

RDB模式的缺點

1.會形成部分數據的丟失 
2.當數據集很是大時,fork操做會佔用不少系統資源,形成主服務進程假死

RDB模式適用的場景

1.數據備份 
2.可容忍部分數據丟失 
3.跨數據中心的容災備份

5.2 AOF

aof持久化 記錄服務器的全部寫操做,並在服務器啓動時從新執行這些命令來恢復數據集。aof文件中的命令所有以redis的協議格式存儲,新命令會追加到文件的末尾,同時,redis還會在後臺對aof文件進行重寫,使得aof文件的體積不會過大。

aof機制默認關閉,能夠經過appendonly = yes參數開啓aof機制,經過appendfilename = myaoffile.aof指定aof文件名稱。

對於觸發aof重寫機制也能夠經過配置文件來進行設置:

auto-aof-rewrite-percenttage = 100 auto-aof-rewrite-min-size 64mb
  • 1
  • 2

第一個參數是配置較前一個aof文件大小增加的百分比,第二個參數是配置觸發aof重寫的aof的最小的大小。

修改aof的fsync策略:

appendfsync=always 同步持久化每一次修改操做 appendfsync=everysec 每秒想aof文件同步一次 appendfsync=no 關閉向aof文件寫入修改
  • 1
  • 2
  • 3

aof的優勢

1.支持不一樣的fsync策略:no/always/everysec 
2.可以記錄全部寫操做,不會形成數據丟失 
3.aof重寫機制確保aof文件不會過大 
4.aof文件能夠很容易的讀懂

aof的缺點

1.雖然有aof重寫機制,單aof文件一般比rdb文件大 
2.在不一樣的fsync策略寫,redis性能會受到必定影響

6. Redis事務操做分析以及發佈訂閱模式的操做使用

6.1 Redis 事務

Redis 事務能夠一次執行多個命令, 而且帶有如下兩個重要的保證:

  • 事務是一個單獨的隔離操做:事務中的全部命令都會序列化、按順序地執行。事務在執行的過程當中,不會被其餘客戶端發送來的命令請求所打斷。
  • 事務是一個原子操做:事務中的命令要麼所有被執行,要麼所有都不執行。

一個事務從開始到執行會經歷如下三個階段:

  • 開始事務。
  • 命令入隊。
  • 執行事務。

6.1.1 實例

如下是一個事務的例子, 它先以 MULTI 開始一個事務, 而後將多個命令入隊到事務中, 最後由 EXEC 命令觸發事務, 一併執行事務中的全部命令:

redis 127.0.0.1:6379> MULTI
OK

redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days"
QUEUED

redis 127.0.0.1:6379> GET book-name
QUEUED

redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series"
QUEUED

redis 127.0.0.1:6379> SMEMBERS tag
QUEUED

redis 127.0.0.1:6379> EXEC
1) OK
2) "Mastering C++ in 21 days"
3) (integer) 3
4) 1) "Mastering Series"
   2) "C++"
   3) "Programming" 

6.1.2 事務命令

1    DISCARD 
取消事務,放棄執行事務塊內的全部命令。
2    EXEC 
執行全部事務塊內的命令。
3    MULTI 
標記一個事務塊的開始。
4    UNWATCH 
取消 WATCH 命令對全部 key 的監視。
5    WATCH key [key ...] 
監視一個(或多個) key ,若是在事務執行以前這個(或這些) key 被其餘命令所改動,那麼事務將被打斷。

 

6.2 Redis 發佈訂閱

Redis 發佈訂閱(pub/sub)是一種消息通訊模式:發送者(pub)發送消息,訂閱者(sub)接收消息。

Redis 客戶端能夠訂閱任意數量的頻道。

下圖展現了頻道 channel1 , 以及訂閱這個頻道的三個客戶端 —— client2 、 client5 和 client1 之間的關係:

pubsub1

當有新消息經過 PUBLISH 命令發送給頻道 channel1 時, 這個消息就會被髮送給訂閱它的三個客戶端:

pubsub2

6.2.1 實例

如下實例演示了發佈訂閱是如何工做的。在咱們實例中咱們建立了訂閱頻道名爲 redisChat:

redis 127.0.0.1:6379> SUBSCRIBE redisChat

Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat"
3) (integer) 1

如今,咱們先從新開啓個 redis 客戶端,而後在同一個頻道 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 runoob.com"

(integer) 1

# 訂閱者的客戶端會顯示以下消息
1) "message"
2) "redisChat"
3) "Redis is a great caching technique"
1) "message"
2) "redisChat"
3) "Learn redis by runoob.com"

6.2.2 發佈訂閱命令

1    PSUBSCRIBE pattern [pattern ...] 
訂閱一個或多個符合給定模式的頻道。
2    PUBSUB subcommand [argument [argument ...]] 
查看訂閱與發佈系統狀態。
3    PUBLISH channel message 
將信息發送到指定的頻道。
4    PUNSUBSCRIBE [pattern [pattern ...]] 
退訂全部給定模式的頻道。
5    SUBSCRIBE channel [channel ...] 
訂閱給定的一個或多個頻道的信息。
6    UNSUBSCRIBE [channel [channel ...]] 
指退訂給定的頻道。

7. Redis集羣搭建

Redis從單機到集羣,一步步教你環境部署以及使用

8. Redis主從複製原理分析

 

9. Redis的優化建議,最佳實踐

一、中止使用 KEYS *

Okay,以挑戰這個命令開始這篇文章,或許並非一個好的方式,但其確實多是最重要的一點。不少時候當咱們關注一個redis實例的統計數據,咱們會快速地輸入」KEYS *」命令,這樣key的信息會很明顯地展現出來。平心而論,從程序化的角度出發每每傾向於寫出下面這樣的僞代碼:

可是當你有1300萬個key時,執行速度將會變慢。由於KEYS命令的時間複雜度是O(n),其中n是要返回的keys的個數,這樣這個命令的複雜度就取決於數據庫的大小了。而且在這個操做執行期間,其它任何命令在你的實例中都沒法執行。

做爲一個替代命令,看一下 SCAN 吧,其容許你以一種更友好的方式來執行… SCAN 經過增量迭代的方式來掃描數據庫。這一操做基於遊標的迭代器來完成的,所以只要你以爲合適,你能夠隨時中止或繼續。

二、找出拖慢 Redis 的罪魁禍首

因爲 Redis 沒有很是詳細的日誌,要想知道在 Redis 實例內部都作了些什麼是很是困難的。幸運的是 Redis 提供了一個下面這樣的命令統計工具:

經過這個工具能夠查看全部命令統計的快照,好比命令執行了多少次,執行命令所耗費的毫秒數(每一個命令的總時間和平均時間)

只須要簡單地執行 CONFIG RESETSTAT 命令就能夠重置,這樣你就能夠獲得一個全新的統計結果。

三、 將 Redis-Benchmark 結果做爲參考,而不要一律而論

Redis 之父 Salvatore 就說過:「經過執行GET/SET命令來測試Redis就像在雨天檢測法拉利的雨刷清潔鏡子的效果」。不少時候人們跑到我這裏,他們想知道爲何本身的Redis-Benchmark統計的結果低於最優結果 。但咱們必需要把各類不一樣的真實狀況考慮進來,例如:

  • 可能受到哪些客戶端運行環境的限制?
  • 是同一個版本號嗎?
  • 測試環境中的表現與應用將要運行的環境是否一致?

Redis-Benchmark的測試結果提供了一個保證你的 Redis-Server 不會運行在非正常狀態下的基準點,可是你永遠不要把它做爲一個真實的「壓力測試」。壓力測試須要反應出應用的運行方式,而且須要一個儘量的和生產類似的環境。

四、Hashes 是你的最佳選擇

以一種優雅的方式引入 hashes 吧。hashes 將會帶給你一種史無前例的體驗。以前我曾看到過許多相似於下面這樣的key結構:

上面的例子中,foo 多是一個用戶的用戶名,其中的每一項都是一個單獨的 key。這就增長了 犯錯的空間,和一些沒必要要的 key。使用 hash 代替吧,你會驚奇地發現居然只須要一個 key :

五、設置 key 值的存活時間

不管何時,只要有可能就利用key超時的優點。一個很好的例子就是儲存一些諸如臨時認證key之類的東西。當你去查找一個受權key時——以OAUTH爲例——一般會獲得一個超時時間。這樣在設置key的時候,設成一樣的超時時間,Redis就會自動爲你清除!而再也不須要使用KEYS *來遍歷全部的key了,怎麼樣很方便吧?

六、 選擇合適的回收策略

既然談到了清除key這個話題,那咱們就來聊聊回收策略。當 Redis 的實例空間被填滿了以後,將會嘗試回收一部分key。根據你的使用方式,我強烈建議使用 volatile-lru 策略——前提是你對key已經設置了超時。但若是你運行的是一些相似於 cache 的東西,而且沒有對 key 設置超時機制,能夠考慮使用 allkeys-lru 回收機制。個人建議是先在這裏查看一下可行的方案。

七、若是你的數據很重要,請使用 Try/Except

若是必須確保關鍵性的數據能夠被放入到 Redis 的實例中,我強烈建議將其放入 try/except 塊中。幾乎全部的Redis客戶端採用的都是「發送即忘」策略,所以常常須要考慮一個 key 是否真正被放到 Redis 數據庫中了。至於將 try/expect 放到 Redis 命令中的複雜性並非本文要講的,你只須要知道這樣作能夠確保重要的數據放到該放的地方就能夠了。

八、不要耗盡一個實例

不管何時,只要有可能就分散多redis實例的工做量。從3.0.0版本開始,Redis就支持集羣了。Redis集羣容許你基於key範圍分離出部分包含主/從模式的key。完整的集羣背後的「魔法」能夠在這裏找到。但若是你是在找教程,那這裏是一個再適合不過的地方了。若是不能選擇集羣,考慮一下命名空間吧,而後將你的key分散到多個實例之中。關於怎樣分配數據,在redis.io網站上有這篇精彩的評論。

九、內核越多越好嗎?!

固然是錯的。Redis 是一個單線程進程,即便啓用了持久化最多也只會消耗兩個內核。除非你計劃在一臺主機上運行多個實例——但願只會是在開發測試的環境下!——不然的話對於一個 Redis 實例是不須要2個以上內核的。

十、高可用

到目前爲止 Redis Sentinel 已經通過了很全面的測試,不少用戶已經將其應用到了生產環境中(包括 ObjectRocket )。若是你的應用重度依賴於 Redis ,那就須要想出一個高可用方案來保證其不會掉線。固然,若是不想本身管理這些東西,ObjectRocket 提供了一個高可用平臺,並提供7×24小時的技術支持,有意向的話能夠考慮一下。

10. Redis的JAVA客戶端使用

使用  jedis.jar

連接測試:

package redis;

import redis.clients.jedis.Jedis;

public class RedisJava {
    public static void main(String[] args) {
        //鏈接本地的 Redis 服務
        Jedis jedis = new Jedis("localhost");
        System.out.println("鏈接成功");
        //查看服務是否運行
        System.out.println("服務正在運行: "+jedis.ping());
        jedis.close();
    }
}

String:

package redis;

import redis.clients.jedis.Jedis;

public class RedisStringJava {
     public static void main(String[] args) {
            //鏈接本地的 Redis 服務
            Jedis jedis = new Jedis("localhost");
            System.out.println("鏈接成功");
            //設置 redis 字符串數據
            jedis.set("name", "loveincode");
            // 獲取存儲的數據並輸出
            System.out.println("redis 存儲的字符串爲: "+ jedis.get("name"));
            jedis.close();
        }
}

11. Redis集成Spring的使用

使用Spring + Jedis集成Redis

 

學習筆記部分來自菜鳥教程:http://www.runoob.com/redis/ 、redis持久化:http://blog.csdn.net/zhangdong2012/article/details/53116213 

相關文章
相關標籤/搜索