Redis

小郑[努力版]發表於2024-11-09

Redis概念和基礎

Redis是一種支援key-value等多種資料結構的儲存系統。可用於快取,事件釋出或訂閱,高速佇列等場景。支援網路,提供字串,雜湊,列表,佇列,集合結構直接存取,基於記憶體,可持久化。

什麼是Redis

Redis是一款記憶體快取記憶體資料庫。支援key-value儲存系統,支援豐富的資料型別,如:string,list,set,zset,hash

可用於快取,事件釋出和訂閱,高速佇列,分散式鎖等場景

用c語言開發,效率高

為什麼使用Redis

  • 讀寫效能優異
  • 資料型別豐富
  • 原子性
  • 豐富的特性
  • 持久化
  • 釋出訂閱
  • 分散式

Redis下載與安裝

下載地址: Redis中文網

Windows版

只需將壓縮包解壓到對應的資料夾即可

啟動: 直接點選redis-server.exe開啟redis即可

linux版

  1. 將Redis安裝包傳到linux中

  2. 解壓安裝包

    tar -zxvf redis-4.0.0.tar.gz -C /usr/local

  3. 安裝Redis的依賴環境gcc

    yum install gcc-c++

  4. 進入/usr/local/redis-4.0.0目錄,進行編譯

    # 進入目錄 cd /usr/local/redis-4.0.0

    開啟編譯 make

  5. 進入Redis的src目錄,進行安裝

    # 進入src目錄 cd src

    進行安裝 make install

啟動與停止

  1. 使用Redis-server啟動,預設埠號為6379

    # 進入目錄

    cd /usr/local/redis-4.0.0/src

    啟動

    ./redis-server

  2. 連線服務

    這時我們的頁面應該是Redis系統介面,我們需要重開一個頁面進行Redis操作

    我們透過cli連線服務

    進入目錄

    cd /usr/local/redis-4.0.0/src

    連線服務

    ./redis-cli

    檢視資料

    keys *

    可以使用Ctrl+C退出系統

    Ctrl+C

  3. 關閉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 配置項說明如下:

  1. Redis預設不是以守護程序的方式執行,可以透過該配置項修改,使用yes啟用守護程序

daemonize no

  1. 當Redis以守護程序方式執行時,Redis預設會把pid寫入/var/run/redis.pid檔案,可以透過pidfile指定

pidfile /var/run/redis.pid

  1. 指定Redis監聽埠,預設埠為6379,作者在自己的一篇博文中解釋了為什麼選用6379作為預設埠,因為6379在手機按鍵上MERZ對應的號碼,而MERZ取自義大利歌女Alessia Merz的名字

port 6379

  1. 繫結的主機地址

bind 127.0.0.1

5.當客戶端閒置多長時間後關閉連線,如果指定為0,表示關閉該功能

timeout 300

  1. 指定日誌記錄級別,Redis總共支援四個級別:debug、verbose、notice、warning,預設為verbose

loglevel verbose

  1. 日誌記錄方式,預設為標準輸出,如果配置Redis為守護程序方式執行,而這裡又配置為日誌記錄方式為標準輸出,則日誌將會傳送給/dev/null

logfile stdout

  1. 設定資料庫的數量,預設資料庫為0,可以使用SELECT <dbid>命令在連線上指定資料庫id

databases 16

  1. 指定在多長時間內,有多少次更新操作,就將資料同步到資料檔案,可以多個條件配合

save <seconds> <changes>

Redis預設配置檔案中提供了三個條件:

save 900 1

save 300 10

save 60 10000

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

  1. 指定儲存至本地資料庫時是否壓縮資料,預設為yes,Redis採用LZF壓縮,如果為了節省CPU時間,可以關閉該選項,但會導致資料庫檔案變的巨大

rdbcompression yes

  1. 指定本地資料庫檔名,預設值為dump.rdb

dbfilename dump.rdb

  1. 指定本地資料庫存放目錄

dir ./

  1. 設定當本機為slav服務時,設定master服務的IP地址及埠,在Redis啟動時,它會自動從master進行資料同步

slaveof <masterip> <masterport>

  1. 當master服務設定了密碼保護時,slav服務連線master的密碼

masterauth <master-password>

  1. 設定Redis連線密碼,如果配置了連線密碼,客戶端在連線Redis時需要透過AUTH <password>命令提供密碼,預設關閉

requirepass foobared

  1. 設定同一時間最大客戶端連線數,預設無限制,Redis可以同時開啟的客戶端連線數為Redis程序可以開啟的最大檔案描述符數,如果設定 maxclients 0,表示不作限制。當客戶端連線數到達限制時,Redis會關閉新的連線並向客戶端返回max number of clients reached錯誤資訊

maxclients 128

  1. 指定Redis最大記憶體限制,Redis在啟動時會把資料載入到記憶體中,達到最大記憶體後,Redis會先嚐試清除已到期或即將到期的Key,當此方法處理 後,仍然到達最大記憶體設定,將無法再進行寫入操作,但仍然可以進行讀取操作。Redis新的vm機制,會把Key存放記憶體,Value會存放在swap區

maxmemory <bytes>

  1. 指定是否在每次更新操作後進行日誌記錄,Redis在預設情況下是非同步的把資料寫入磁碟,如果不開啟,可能會在斷電時導致一段時間內的資料丟失。因為 redis本身同步資料檔案是按上面save條件來同步的,所以有的資料會在一段時間內只存在於記憶體中。預設為no

appendonly no

  1. 指定更新日誌檔名,預設為appendonly.aof

appendfilename appendonly.aof

  1. 指定更新日誌條件,共有3個可選值:

    no:表示等作業系統進行資料快取同步到磁碟(快)

    always:表示每次更新操作後手動呼叫fsync()將資料寫到磁碟(慢,安全)

    everysec:表示每秒同步一次(折衷,預設值)

appendfsync everysec

  1. 指定是否啟用虛擬記憶體機制,預設值為no,簡單的介紹一下,VM機制將資料分頁存放,由Redis將訪問量較少的頁即冷資料swap到磁碟上,訪問多的頁面由磁碟自動換出到記憶體中(在後面的文章我會仔細分析Redis的VM機制)

vm-enabled no

  1. 虛擬記憶體檔案路徑,預設值為/tmp/redis.swap,不可多個Redis例項共享

vm-swap-file /tmp/redis.swap

  1. 將所有大於vm-max-memory的資料存入虛擬記憶體,無論vm-max-memory設定多小,所有索引資料都是記憶體儲存的(Redis的索引資料 就是keys),也就是說,當vm-max-memory設定為0的時候,其實是所有value都存在於磁碟。預設值為0

vm-max-memory 0

  1. Redis swap檔案分成了很多的page,一個物件可以儲存在多個page上面,但一個page上不能被多個物件共享,vm-page-size是要根據儲存的 資料大小來設定的,作者建議如果儲存很多小物件,page大小最好設定為32或者64bytes;如果儲存很大大物件,則可以使用更大的page,如果不 確定,就使用預設值

vm-page-size 32

  1. 設定swap檔案中的page數量,由於頁表(一種表示頁面空閒或使用的bitmap)是在放在記憶體中的,,在磁碟上每8個pages將消耗1byte的記憶體。

vm-pages 134217728

  1. 設定訪問swap檔案的執行緒數,最好不要超過機器的核數,如果設定為0,那麼所有對swap檔案的操作都是序列的,可能會造成比較長時間的延遲。預設值為4

vm-max-threads 4

  1. 設定在向客戶端應答時,是否把較小的包合併為一個包傳送,預設為開啟

glueoutputbuf yes

  1. 指定在超過一定的數量或者最大的元素超過某一臨界值時,採用一種特殊的雜湊演算法

hash-max-zipmap-entries 64

hash-max-zipmap-value 512

  1. 指定是否啟用重置雜湊,預設為開啟(後面在介紹Redis的雜湊演算法時具體介紹)

activerehashing yes

  1. 指定包含其它的配置檔案,可以在同一主機上多個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 之間的關係:

image-20241106120308099

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

image-20241106120327986

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 引數讓結果只顯示每秒執行的請求數。

相關文章