Redis概念和基礎
Redis是一種支援key-value等多種資料結構的儲存系統。可用於快取,事件釋出或訂閱,高速佇列等場景。支援網路,提供字串,雜湊,列表,佇列,集合結構直接存取,基於記憶體,可持久化。
什麼是Redis
Redis是一款記憶體快取記憶體資料庫。支援key-value儲存系統,支援豐富的資料型別,如:string,list,set,zset,hash
可用於快取,事件釋出和訂閱,高速佇列,分散式鎖等場景
用c語言開發,效率高
為什麼使用Redis
- 讀寫效能優異
- 資料型別豐富
- 原子性
- 豐富的特性
- 持久化
- 釋出訂閱
- 分散式
Redis下載與安裝
下載地址: Redis中文網
Windows版
只需將壓縮包解壓到對應的資料夾即可
啟動: 直接點選redis-server.exe開啟redis即可
linux版
-
將Redis安裝包傳到linux中
-
解壓安裝包
tar -zxvf redis-4.0.0.tar.gz -C /usr/local
-
安裝Redis的依賴環境gcc
yum install gcc-c++
-
進入
/usr/local/redis-4.0.0
目錄,進行編譯# 進入目錄 cd /usr/local/redis-4.0.0
開啟編譯 make
-
進入Redis的src目錄,進行安裝
# 進入src目錄 cd src
進行安裝 make install
啟動與停止
-
使用Redis-server啟動,預設埠號為6379
# 進入目錄
cd /usr/local/redis-4.0.0/src
啟動
./redis-server
-
連線服務
這時我們的頁面應該是Redis系統介面,我們需要重開一個頁面進行Redis操作
我們透過cli連線服務
進入目錄
cd /usr/local/redis-4.0.0/src
連線服務
./redis-cli
檢視資料
keys *
可以使用Ctrl+C退出系統
Ctrl+C
-
關閉Redis服務
# 查詢Redis伺服器程序號
ps -ef|grep redis
關閉程序
kill -9 程序號
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) ""
編輯配置
可以透過修改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"OKredis 127.0.0.1:6379> CONFIG GET loglevel 1) "loglevel"2) "notice"
引數說明:
redis.conf 配置項說明如下:
- Redis預設不是以守護程序的方式執行,可以透過該配置項修改,使用yes啟用守護程序
daemonize no
- 當Redis以守護程序方式執行時,Redis預設會把pid寫入/var/run/redis.pid檔案,可以透過pidfile指定
pidfile /var/run/redis.pid
- 指定Redis監聽埠,預設埠為6379,作者在自己的一篇博文中解釋了為什麼選用6379作為預設埠,因為6379在手機按鍵上MERZ對應的號碼,而MERZ取自義大利歌女Alessia Merz的名字
port 6379
- 繫結的主機地址
bind 127.0.0.1
5.當客戶端閒置多長時間後關閉連線,如果指定為0,表示關閉該功能
timeout 300
- 指定日誌記錄級別,Redis總共支援四個級別:debug、verbose、notice、warning,預設為verbose
loglevel verbose
- 日誌記錄方式,預設為標準輸出,如果配置Redis為守護程序方式執行,而這裡又配置為日誌記錄方式為標準輸出,則日誌將會傳送給/dev/null
logfile stdout
- 設定資料庫的數量,預設資料庫為0,可以使用SELECT
<dbid>
命令在連線上指定資料庫id
databases 16
- 指定在多長時間內,有多少次更新操作,就將資料同步到資料檔案,可以多個條件配合
save <seconds>
<changes>
Redis預設配置檔案中提供了三個條件:
save 900 1
save 300 10
save 60 10000
分別表示900秒(15分鐘)內有1個更改,300秒(5分鐘)內有10個更改以及60秒內有10000個更改。
- 指定儲存至本地資料庫時是否壓縮資料,預設為yes,Redis採用LZF壓縮,如果為了節省CPU時間,可以關閉該選項,但會導致資料庫檔案變的巨大
rdbcompression yes
- 指定本地資料庫檔名,預設值為dump.rdb
dbfilename dump.rdb
- 指定本地資料庫存放目錄
dir ./
- 設定當本機為slav服務時,設定master服務的IP地址及埠,在Redis啟動時,它會自動從master進行資料同步
slaveof <masterip>
<masterport>
- 當master服務設定了密碼保護時,slav服務連線master的密碼
masterauth <master-password>
- 設定Redis連線密碼,如果配置了連線密碼,客戶端在連線Redis時需要透過AUTH
<password>
命令提供密碼,預設關閉
requirepass foobared
- 設定同一時間最大客戶端連線數,預設無限制,Redis可以同時開啟的客戶端連線數為Redis程序可以開啟的最大檔案描述符數,如果設定 maxclients 0,表示不作限制。當客戶端連線數到達限制時,Redis會關閉新的連線並向客戶端返回max number of clients reached錯誤資訊
maxclients 128
- 指定Redis最大記憶體限制,Redis在啟動時會把資料載入到記憶體中,達到最大記憶體後,Redis會先嚐試清除已到期或即將到期的Key,當此方法處理 後,仍然到達最大記憶體設定,將無法再進行寫入操作,但仍然可以進行讀取操作。Redis新的vm機制,會把Key存放記憶體,Value會存放在swap區
maxmemory <bytes>
- 指定是否在每次更新操作後進行日誌記錄,Redis在預設情況下是非同步的把資料寫入磁碟,如果不開啟,可能會在斷電時導致一段時間內的資料丟失。因為 redis本身同步資料檔案是按上面save條件來同步的,所以有的資料會在一段時間內只存在於記憶體中。預設為no
appendonly no
- 指定更新日誌檔名,預設為appendonly.aof
appendfilename appendonly.aof
-
指定更新日誌條件,共有3個可選值:
no:表示等作業系統進行資料快取同步到磁碟(快)
always:表示每次更新操作後手動呼叫fsync()將資料寫到磁碟(慢,安全)
everysec:表示每秒同步一次(折衷,預設值)
appendfsync everysec
- 指定是否啟用虛擬記憶體機制,預設值為no,簡單的介紹一下,VM機制將資料分頁存放,由Redis將訪問量較少的頁即冷資料swap到磁碟上,訪問多的頁面由磁碟自動換出到記憶體中(在後面的文章我會仔細分析Redis的VM機制)
vm-enabled no
- 虛擬記憶體檔案路徑,預設值為/tmp/redis.swap,不可多個Redis例項共享
vm-swap-file /tmp/redis.swap
- 將所有大於vm-max-memory的資料存入虛擬記憶體,無論vm-max-memory設定多小,所有索引資料都是記憶體儲存的(Redis的索引資料 就是keys),也就是說,當vm-max-memory設定為0的時候,其實是所有value都存在於磁碟。預設值為0
vm-max-memory 0
- Redis swap檔案分成了很多的page,一個物件可以儲存在多個page上面,但一個page上不能被多個物件共享,vm-page-size是要根據儲存的 資料大小來設定的,作者建議如果儲存很多小物件,page大小最好設定為32或者64bytes;如果儲存很大大物件,則可以使用更大的page,如果不 確定,就使用預設值
vm-page-size 32
- 設定swap檔案中的page數量,由於頁表(一種表示頁面空閒或使用的bitmap)是在放在記憶體中的,,在磁碟上每8個pages將消耗1byte的記憶體。
vm-pages 134217728
- 設定訪問swap檔案的執行緒數,最好不要超過機器的核數,如果設定為0,那麼所有對swap檔案的操作都是序列的,可能會造成比較長時間的延遲。預設值為4
vm-max-threads 4
- 設定在向客戶端應答時,是否把較小的包合併為一個包傳送,預設為開啟
glueoutputbuf yes
- 指定在超過一定的數量或者最大的元素超過某一臨界值時,採用一種特殊的雜湊演算法
hash-max-zipmap-entries 64
hash-max-zipmap-value 512
- 指定是否啟用重置雜湊,預設為開啟(後面在介紹Redis的雜湊演算法時具體介紹)
activerehashing yes
- 指定包含其它的配置檔案,可以在同一主機上多個Redis例項之間使用同一份配置檔案,而同時各個例項又擁有自己的特定配置檔案
include /path/to/local.conf
HyperLogLog
HyperLogLog 是用來做基數統計的演算法
優點:
在輸入元素的數量或體積非常非常大時,計算基數所需的空間總是固定的,並且很小的。
在 Redis 裡面,每個 HyperLogLog 鍵只需要花費 12 KB 記憶體,就可以計算接近 2^64 個不同元素的基 數。這和計算基數時,元素越多耗費記憶體就越多的集合形成鮮明對比。
但是,因為 HyperLogLog 只會根據輸入元素來計算基數,而不會儲存輸入元素本身,所以 HyperLogLog 不能像集合那樣,返回輸入的各個元素。
什麼是基數?
比如資料集 {1, 3, 5, 7, 5, 7, 8}, 那麼這個資料集的基數集為 {1, 3, 5 ,7, 8}, 基數(不重複元素)為5。 基數估計就是在誤差可接受的範圍內,快速計算基數。
Redis HyperLogLog 命令
序號 | 命令及描述 |
---|---|
1 | PFADD key element [element ...](https://www.redis.net.cn/order/3629.html) 新增指定元素到 HyperLogLog 中。 |
2 | PFCOUNT key [key ...](https://www.redis.net.cn/order/3630.html) 返回給定 HyperLogLog 的基數估算值。 |
3 | PFMERGE destkey sourcekey [sourcekey ...](https://www.redis.net.cn/order/3631.html) 將多個 HyperLogLog 合併為一個 HyperLogLog |
釋出訂閱
Redis 釋出訂閱(pub/sub)是一種訊息通訊模式:傳送者(pub)傳送訊息,訂閱者(sub)接收訊息。
Redis 客戶端可以訂閱任意數量的頻道。
下圖展示了頻道 channel1 , 以及訂閱這個頻道的三個客戶端 —— client2 、 client5 和 client1 之間的關係:
當有新訊息透過 PUBLISH 命令傳送給頻道 channel1 時, 這個訊息就會被髮送給訂閱它的三個客戶端:
Redis 釋出訂閱命令
序號 | 命令及描述 |
---|---|
1 | PSUBSCRIBE pattern [pattern ...](https://www.redis.net.cn/order/3632.html) 訂閱一個或多個符合給定模式的頻道。 |
2 | PUBSUB subcommand [argument argument ...]檢視訂閱與釋出系統狀態。 |
3 | PUBLISH channel message 將資訊傳送到指定的頻道。 |
4 | PUNSUBSCRIBE [pattern pattern ...] 退訂所有給定模式的頻道。 |
5 | SUBSCRIBE channel [channel ...](https://www.redis.net.cn/order/3636.html) 訂閱給定的一個或多個頻道的資訊。 |
6 | UNSUBSCRIBE [channel channel ...] 指退訂給定的頻道。 |
事務
Redis事務可以一次執行多個命令,並且帶有以下兩個重要的保證:
事務是一個獨立的隔離操作:事務中的所有命令都會序列化,按順序地執行。事務在執行過程中,不會被其他客戶端傳送來的命令請求所打斷
事務是一個原子操作
一個事務從開始到執行會經歷以下三個階段:
- 開始事務
- 命令入隊
- 執行事務
事務命令
序號 | 命令及描述 |
---|---|
1 | DISCARD 取消事務,放棄執行事務塊內的所有命令 |
2 | EXEC 執行事務塊內的命令 |
3 | MULTI 標記一個事務塊的開始 |
4 | UNWATCH 取消WATCH命令對所有key的監視 |
5 | WATCH key [key ....] 監視一個(或多個)key,如果在事務執行之前這個(或這些)key被其他命令所改動,那麼事務將被打斷 |
例項
以下是一個事務的例子, 它先以 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"
資料備份與恢復
備份
Redis SAVE
命令用於建立當前資料庫的備份,該命令將在Redis安裝目錄中建立dump.rdb
語法:
redis 127.0.0.1:6379> SAVE
OK
恢復
如果需要恢復資料,只需將備份檔案 (dump.rdb) 移動到 redis 安裝目錄並啟動服務即可。獲取 redis 目錄可以使用 CONFIG 命令,如下所示:
redis 127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/usr/local/redis/bin"
以上命令 CONFIG GET dir 輸出的 redis 安裝目錄為 /usr/local/redis/bin。
Bgsave
建立 redis 備份檔案也可以使用命令 BGSAVE,該命令在後臺執行。
127.0.0.1:6379> BGSAVE
Background saving started
安全
可以透過Redis的配置檔案設定密碼引數,這樣客戶端連線到Redis服務就需要密碼驗證,這樣可以讓你的Redis服務更安全
可以透過以下命令檢視是否設定了密碼驗證:
127.0.0.1:6379> CONFIG get requirepass
1) "requirepass"
2) ""
預設情況下requirepass引數是空的,這就意味著你無需透過密碼驗證就可以連線到Redis服務
可以透過以下命令來修改引數:
127.0.0.1:6379> CONFIG set requirepass "w3cschool.cc"
OK
127.0.0.1:6379> CONFIG get requirepass
1) "requirepass"
2) "w3cschool.cc"
設定密碼後,客戶端連線 redis 服務就需要密碼驗證,否則無法執行命令。
語法
AUTH 命令基本語法格式如下:
127.0.0.1:6379> AUTH password
127.0.0.1:6379> AUTH "w3cschool.cc"
OK
127.0.0.1:6379> SET mykey "Test value"
OK
127.0.0.1:6379> GET mykey
"Test value"
效能測試
Redis 效能測試是透過同時執行多個命令實現的。
語法
redis 效能測試的基本命令如下:
redis-benchmark [option] [option value]
redis 效能測試工具可選引數如下所示:
序號 | 選項 | 描述 | 預設值 |
---|---|---|---|
1 | -h | 指定伺服器主機名 | 127.0.0.1 |
2 | -p | 指定伺服器埠 | 6379 |
3 | -s | 指定伺服器 socket | |
4 | -c | 指定併發連線數 | 50 |
5 | -n | 指定請求數 | 10000 |
6 | -d | 以位元組的形式指定 SET/GET 值的資料大小 | 2 |
7 | -k | 1=keep alive 0=reconnect | 1 |
8 | -r | SET/GET/INCR 使用隨機 key, SADD 使用隨機值 | |
9 | -P | 透過管道傳輸 <numreq> 請求 |
1 |
10 | -q | 強制退出 redis。僅顯示 query/sec 值 | |
11 | --csv | 以 CSV 格式輸出 | |
12 | -l | 生成迴圈,永久執行測試 | |
13 | -t | 僅執行以逗號分隔的測試命令列表。 | |
14 | -I | Idle 模式。僅開啟 N 個 idle 連線並等待。 |
例項
以下例項同時執行 10000 個請求來檢測效能:
redis-benchmark -n 100000
PING_INLINE: 141043.72 requests per second
PING_BULK: 142857.14 requests per second
SET: 141442.72 requests per second
GET: 145348.83 requests per second
INCR: 137362.64 requests per second
LPUSH: 145348.83 requests per second
LPOP: 146198.83 requests per second
SADD: 146198.83 requests per second
SPOP: 149253.73 requests per second
LPUSH (needed to benchmark LRANGE): 148588.42 requests per second
LRANGE_100 (first 100 elements): 58411.21 requests per second
LRANGE_300 (first 300 elements): 21195.42 requests per second
LRANGE_500 (first 450 elements): 14539.11 requests per second
LRANGE_600 (first 600 elements): 10504.20 requests per second
MSET (10 keys): 93283.58 requests per second
例項
以下例項我們使用了多個引數來測試 redis 效能:
redis-benchmark -h 127.0.0.1 -p 6379 -t set,lpush -n 100000 -q
SET: 146198.83 requests per second
LPUSH: 145560.41 requests per second
以上例項中主機為 127.0.0.1,埠號為 6379,執行的命令為 set,lpush,請求數為 10000,透過 -q 引數讓結果只顯示每秒執行的請求數。