前言
配置檔案redis.conf說明
include 選項
include /path/to/local.conf
Redis 支援通過 include 選項來載入其他配置檔案
子產品選項
loadmodule /path/to/my_module.so
loadmodule /path/to/other_module.so
Redis 可以通過 loadmodule 選項在啟動時加載子產品,若服務端無法加載子產品,服務端會停止。 可以通過多個 loadmodule 選項加載多個子產品。
網絡選項
bind 127.0.0.1
bind 選項用于設定監聽的 network interface,不設定這個選項相當于 bind 0.0.0.0,可以通過這個選項監聽多個 network interface, 如:
bind 192.168.1.100 10.0.0.1
當設定多個 bind 位址後,Redis 内部會維護多個 Socket,每個 Socket 用于一個 network interface。
protected-mode yes
此選項預設開啟,開啟此選項後, 當 Redis 服務端未使用 bind 選項顯式指定要監聽的 network interface,并且未設定密碼, Redis 服務端隻會接受來自 127.0.0.1 和 ::1 的用戶端以及 Unix 域的 Socket 進行連接配接。
port 6379
port 選項用于設定 Redis 監聽的 TCP 端口,預設為 6379,設定為 0 表示不監聽 TCP 端口
tcp-backlog 511
tcp-backlog 用于設定 TCP 連接配接的排隊隊列長度,最終就是影響到 listen 接口的 backlog 參數。
unixsocket /var/run/redis/redis.sock
unixsocketperm 700
unixsocket 和 unixsocketperm 用于設定 Unix 域套接字,預設不開啟。
timeout 0
當用戶端空閑 timeout 秒後,Redis 服務端主動關閉此連接配接, 0 表示不啟用此功能。
tcp-keepalive 300
将此值設定為非 0 值表示啟用協定層的心跳檢測功能,此功能是通過 setsockopt 的 SO_KEEPALIVE 選項開啟的。
通用選項
daemonize yes
設定 daemonize 選項為 yes 會使 Redis 以守護程序模式啟動,在此模式下,Redis 預設會将 pid 寫入 /var/run/redis.pid。 可以通過 pidfile 選項修改寫入的檔案,如:
pidfile /var/run/redis/redis-server.pid
supervised no
當你通過 upstart 或者 systemd 運作 Redis 時,Redis 可以和你的 supervision tree 進行互動,可選的選項為:
no 無互動
upstart 通過向 Redis 發送 SIGSTOP 信号來通知 upstart
systemd 通過向 $NOTIFY_SOCKET 寫入 READY=1 來通知 systemd
auto 通過是否設定了 UPSTART_JOB 或者 NOTIFY_SOCKET 環境變量來決定選項為 upstart 或者 systemd
loglevel notice
日志級别,可以設定為: debug、verbose、notice、warning 中的一個。
logfile /var/log/redis/redis-server.log
logfile 選項用于設定日志輸出的路徑,若沒有設定此路徑,則 Redis 會将日志輸出到标準輸出,若以守護程序模式啟動則輸出到 /dev/null。
# To enable logging to the system logger, just set 'syslog-enabled' to yes,
# and optionally update the other syslog parameters to suit your needs.
# syslog-enabled no
# Specify the syslog identity.
# syslog-ident redis
# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7.
# syslog-facility local0
以上三個選項用于設定是否将日志輸出到 syslog,syslog-ident 和 syslog-facility 對應了系統接口 openlog 的 ident 和 facility 選項。
databases 16
Redis 的資料庫個數,當你連接配接到 Redis 伺服器時,預設會選中 0 号資料庫,可以通過 SELECT num 指令,選擇要使用的資料庫(num 表示 0 到 此選項的值減 1 的資料庫)。
always-show-logo yes
預設情況下,Redis 隻會在互動模式才顯示 ASCII 版本的 logo,可以通過設定此選項為 yes,使 Redis 在任何情況下都顯示 logo,使得 Redis 的此行為和 4.0 之前的版本行為保持一緻。
快照選項
save 900 1
save 300 10
save 60 10000
save 選項用于設定 Redis 将資料庫持久化到硬碟的時間,可以有多個 save 選項。 save 後面的第一個數字表示多少秒進行一次檢查,第二個數字表示此時間内有多少個 key 被改變會将資料庫持久化到硬碟。 比如上面的三個選項表示,每 900 秒内,如果有多于 1 個 key 被改變(包括增加,修改,删除)則将其持久化到硬碟, 每 300 秒内,如果有多于 10 個 key 被改變則将其持久化到硬碟,每 60 秒内,如果有多于 10000 個 key 被改變則将其持久化到硬碟。
stop-writes-on-bgsave-error yes
當最近一次的持久化操作失敗後,Redis 會拒絕用戶端的寫入操作,通過這種行為用戶端會知道服務端的不正常現象。 若持久化操作可以正常工作後,服務端會自動允許用戶端的寫入操作。 如果你自己有 Redis 服務端的監控方案,或者你希望即使持久化失敗 Redis 也可以正常工作,則可以将此選項設定為 no。
rdbcompression yes
設定為 yes 表示使用 LZO 算法壓縮持久化到硬碟的 string 對象。
rdbchecksum yes
RDB 檔案是否開啟校驗和。
dbfilename dump.rdb
RDB 檔案的檔案名。
dir /var/lib/redis
Redis 的工作目錄,RDB 和 AOF (後面會說)檔案會儲存到此目錄。
複制選項
replicaof <masterip> <masterport>
通過 replicaof (即以前的 slaveof)選項可以将 Redis 執行個體設定為其他 Redis 服務端的副本。
關于 Redis 的複制,有以下幾點需要注意:
Redis 複制是異步的,但是你可以設定 master 節點,使得 master 節點至少要和指定數量的 replicas 節點連接配接才提供寫服務
當 Redis replicas 節點和 master 節點短暫斷開後,replicas 節點可以向 master 節點要求進行部分資料的重傳
複制是自動的,不需要使用者幹預,當發生網絡分區後,replicas 節點會自動嘗試和 master 節點重連以及進行資料同步
masterauth <master-password>
當 master 節點使用了 “requirepass” 選項後,replicas 節點需要配置此選項。
replica-serve-stale-data yes
此選項為以前的 slave-serve-stale-data,replicas 節點和 master 節點斷開連接配接後,replicas 節點根據 replica-serve-stale-data 選項的配置可能有以下行為:
- 選項設定為 yes(預設值),replicas 節點會繼續向用戶端提供服務,此時傳回給用戶端的資料很可能是過期的
- 選項設定為 no,除了 INFO, replicaOF, AUTH, PING, SHUTDOWN, REPLCONF, ROLE, CONFIG, SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB, COMMAND, POST, HOST, 和 LATENCY 指令外的其他指令,replicas 節點都會傳回 "SYNC with master in progress" 給用戶端
replica-read-only yes
設定 replicas 節點是否隻讀,從 Redis 2.6 開始此選項的預設值為 yes。 需要注意的是隻讀的 replicas 節點并沒有設計為會暴露給網絡上不受信任的用戶端使用的。 你需要對其進行保護以防執行個體被濫用。并且隻讀的 replicas 節點導出了所有如 CONFIG,DEBUG,等管理指令。 你可以使用 'rename-command' 将所有管理/危險 指令進行映射以提高安全性。
repl-diskless-sync no
DISKLESS REPLICATION 目前是實驗性功能
當一個不能續傳或者新的 replicas 需要進行“全量同步”時。一個 RDB 檔案需要由 master 傳送到 replicas。 根據 repl-diskless-sync 選項的不同,RDB 檔案有以下兩種傳輸方式:
- Disk-backed:Redis master 節點建立一個新的程序并且将 RDB 檔案寫入磁盤。然後檔案通過父程序傳輸給 replicas 節點
- Diskless:Redis master 節點一個新的程序并且直接将 RDB 檔案寫入到 replica 的 socket 中,不寫到磁盤
當進行 disk-backed 複制時,當 RDB 檔案生成完畢,多個 replicas 通過排隊來同步 RDB 檔案。 當進行 diskless 複制時,master 節點會等待一段時間再傳輸以期望會有多個 replicas 連接配接進來,這樣 master 節點就可以同時同步到多個 replicas 節點。
repl-diskless-sync-delay 5
當啟用 diskless 複制後,可以通過此選項設定 master 節點建立子程序前等待的時間,機關為秒。
repl-ping-replica-period 10
Replicas 發送 PING 到 master 的間隔,預設值為 10 秒。
repl-timeout 60
此選項用于設定以下情形的 timeout 判斷:
- 從 replica 節點的角度來看的 SYNC 過程中的 I/O 傳輸
- 從 replica 節點的角度來看的 master 的 timeout(如 data,pings)
- 從 master 節點角度來看的 replica 的 timeout(如 REPLCONF ACK pings)
需要注意的是,此選項必須大于 repl-ping-replica-period,否則在低業務量的情況下會經常發生 timeout。
repl-disable-tcp-nodelay no
master 和 replicas 節點的連接配接是否關掉 TCP_NODELAY 選項。 這個實際影響的是 TCP 層的選項,裡面會用 setsockopt 設定,預設為 no,表示 TCP 層會禁用 Nagle 算法,盡快将資料發出, 設定為 yes 表示 TCP 層啟用 Nagle 算法,資料累積到一定程度,或者經過一定時間 TCP 層才會将其發出。
repl-backlog-size 1mb
設定複制的 backlog 緩沖大小。當 replicas 節點斷開重連後,如果斷點發生時的資料還在 backlog 緩沖中, 則不需要全量同步,隻需要部分同步。 更大的 backlog 緩沖大小,意味着 replicas 斷開重連後,依然可以進行續傳的時間越長(支援斷開更長時間)。 backlog 緩沖隻有在至少一個 replicas 節點連過來的時候 master 節點才需要建立。
repl-backlog-ttl 3600
當 replicas 節點斷開連接配接後,master 節點會在一段時間後釋放 backlog 緩沖區。 這個選項設定的是當最後一個 replicas 斷開連結後,master 需要等待多少秒再釋放緩沖區。
需要注意的是 replicas 節點永遠都不會釋放這個緩沖區,因為它有可能再次連接配接到 master 節點, 然後嘗試進行 “增量同步”。
replica-priority 100
這是 replicas 節點通過 INFO 接口給出的資訊,預設值為 100。 當 master 節點無法正常工作後 Redis Sentinel 通過這個值來決定将哪個 replicas 節點提升為 master 節點。
這個數值越小表示越優先進行提升。如有三個 replicas 節點其 priority 值分别為 10,100,25, Sentinel 會選擇 priority 為 10 的節點進行提升。
這個值為 0 表示 replica 節點永遠不能被提升為 master 節點。
min-replicas-to-write 3
min-replicas-max-lag 10
以上選項用于設定至少有 N 個 replicas 節點延遲少于 M 秒時,master 節點才能進行寫操作, 如上面的例子表示至少有 3 個 replicas 節點延遲少于 M 秒時,master 節點才能進行寫操作。 将上面參數的任意一個設定為 0 表示不啟用此功能,min-replicas-to-write 的預設值為 0,min-replicas-max-lag 的預設值為 10。
replica-announce-ip 5.5.5.5
replica-announce-port 1234
Redis master 可以通過不同方式列出連接配接上來的 replicas 節點的位址和端口。 如 Redis Sentinel 等會使用 “INFO replication” 指令來擷取 replica 執行個體資訊。 master 的 “ROLE“ 指令也會提供此資訊。
這個資訊一般來說是通過 replica 節點通過以下方式擷取然後報告上來的:
- IP:通過自動識别連接配接到 Socket 的資訊自動擷取
- Port:一般來說這個值就是 replicas 節點用來接受用戶端的連接配接的監聽端口
但是,若啟用了端口轉發或者 NAT,可能需要其他位址和端口才能連接配接到 replicas 節點。 這種情況下,需要設定這兩個選項,這樣 replicas 就會用這兩個選項設定的值覆寫預設行為擷取的值,然後報告給 master 節點。 根據實際情況,你可以隻設定其中某個選項,而不用兩個選項都設定。
安全選項
requirepass foobared
設定此選項後,用戶端需要使用 AUTH <PASSWORD> 指令進行認證後才能進行其他操作。 當你的伺服器有可能被非信任的用戶端通路到的時候這個指令是很有用的。
警告:由于 Redis 非常快,外部使用者若進行暴力破解,每秒能嘗試超過 150k 個密碼。是以你需要使用強度非常高的密碼才能保證密碼不容易被暴力破解掉。
rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
在共享環境下,可以通過 rename-command 指令将一些危險的指令進行重命名。 如上所示将 CONFIG 指令重命名為難以猜測的指令。
可以通過将指令重命名為空字元串進而将其完全 ”kill“ 掉,如:
rename-command CONFIG ""
注意:rename-command 指令會被記錄到日志和 AOF 檔案中或者傳輸到 replicas 節點,而這可能會是一個安全問題。
用戶端選項
maxclients 10000
設定同時連接配接進來的最大用戶端數,預設值為 10000。需要注意的是同時連接配接進來的用戶端數量還受限于 Redis 程序所能建立的最大的檔案句柄的數量減去 32(Redis 會保留部分句柄用于内部使用)。當超過限制後 Redis 會向所有新進來的連接配接發送錯誤資訊 ”max number of clients reached“ 然後關閉連接配接。
記憶體管理
maxmemory <bytes>
設定 Redis 能使用的最大記憶體數,以位元組為機關。根據你選擇的過期政策(檢視下面的 maxmemory-policy 選項), 當 Redis 使用的記憶體達到限制時,Redis 會嘗試删除過期的鍵。
若 Redis 沒有能删除的鍵,Redis 會拒絕那些如 SET,LPUSH 等會使用更多記憶體的指令,并且會正常相應那些如 GET 等隻讀指令。
這個選項通常用于将 Redis 作為 LRU 或者 LFU cache 使用的情況。
當你的 Redis 執行個體設定了 maxmemory 并且有 replicas 連接配接上來的情況,你需要留出一部分記憶體給 replica 緩沖區。
maxmemory-policy noeviction
當記憶體使用值到達 maxmemory 時使用的删除政策,預設值為 noeviction。
- volatile-lru -> 對過期鍵使用 LRU(Least Recently Used) 近似算法
- allkeys-lru -> 對所有鍵使用 LRU 近似算法
- volatile-lfu -> 對過期鍵使用 LFU(Least Frequently Used)近似算法
- allkeys-lfu -> 對所有鍵使用 LFU 近似算法
- volatile-random -> 對過期鍵使用随機算法
- allkeys-random -> 對所有鍵使用随機算法
- volatile-ttl -> 删除最近過期的鍵(minimal TTL)
- noeviction -> 對寫請求傳回錯誤,不删除鍵
注意:在記憶體到達限值,并且沒有合适的鍵被删除的情況下,無論選擇的是什麼過期政策,Redis 都會傳回出錯。
maxmemory-samples 5
上面的 LRU,LFU 和 minimal TTL 算法都是近似算法,你可以通過改變這個選項來讓算法更快還是更精确。 預設值是 5,也就是說 Redis 随機挑出 5 個鍵,然後選出一個最符合條件的。
對 LRU 來說 5 是比較合适的。10 已經很接近于真正的 LRU,但會消耗更多的 CPU。3 會更快但沒有那麼精确。
replica-ignore-maxmemory yes
從 Redis 5 開始,預設情況下,replica 節點會忽略 maxmemory 設定(除非在發生 failover 後,此節點被提升為 master 節點)。 這意味着隻有 master 才會執行過期删除政策,并且 master 在删除鍵之後會對 replica 發送 DEL 指令。
這個行為保證了 master 和 replicas 的一緻性,并且這通常也是你需要的,但是若你的 replica 節點是可寫的, 或者你希望 replica 節點有不同的記憶體配置,并且你確定所有到 replica 寫操作都幂等的,那麼你可以修改這個預設的行為 (請確定你明白你在做什麼)。
注意::預設情況下 replica 節點不會執行過期政策,它有可能使用了超過 maxmemory 設定的值的記憶體。 是以你需要監控 replicas 節點所在的機器并且確定在 master 節點到達配置的 maxmemory 大小時, replicas 節點不會超過實體記憶體的大小。
惰性删除
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
Redis 有兩種方式删除鍵。一種是使用如 DEL 這樣的指令進行的同步删除。 同步删除意味着删除過程中服務端會停止處理新進來的指令。 若要删除的 key 關聯了一個小的 object 删除耗時會很短。 若要删除的 key 管理了一個很大的 object,比如此對象有上百萬個元素,服務端會阻塞相同長一段時間(甚至超過一秒)。
由于以上原因,Redis 同時提供了一種非阻塞的方式用于删除,比如 UNLINK(非阻塞的 DEL)以及用于 FLUSHALL 和 FLUSHDB 的 ASYNC 選項,這些指令能在背景回收記憶體。 這些指令能在常數時間内執行完畢。其他線程會在背景盡快回收記憶體。
DEL,UNLINK 以及用于 FLUSHALL 和 FLUSHDB 的 ASYNC 選項是使用者可以控制的。 根據應用的設計,使用者可以選擇使用阻塞或者非阻塞的方式。 但是作為某些指令的副作用 Redis 服務端有時會删除某些 object 或者 flush 整個資料庫。 特别是以下獨立于使用者操作的情形:
- 由于 maxmemory 和 maxmemory policy 配置導緻的記憶體回收動作
- 由于過期,當一個 key 過期後(可以檢視 EXPIRE 指令擷取相關資訊),必須回收其記憶體
- 由于某些指令的副作用,比如 STORE 指令,執行 STORE 指令可能需要删除已有的鍵。SET 指令需要删除已有的舊内容。
- 在複制過程中,當一個 replica 節點執行一個全量同步時,replica 需要删除整個資料庫的内容以加載傳輸過來的 RDB 檔案。
在上述所有情形中,删除 object 的預設行為都是以阻塞方式删除。當然你可以配置上述四個選項來改變這種預設行為。
APPEND ONLY 模式
appendonly no
預設情況下,Redis 會以異步形式将備份集 dump 到硬碟中。 對于很多應用來說,這種行為足夠了,但是對于 Redis 程序崩潰或者斷電的情況會導緻最近數分鐘的資料丢失(取決于 save 選項的設定)。
Append Only File 是 Redis 提供的另一種更好的持久化方式。 比如使用預設的資料同步政策(後面會講),Redis 在斷電等意外情況隻會丢失最多一秒的寫入資料, 在系統正常而 Redis 程序出錯(如崩潰)的情況下隻會丢掉最近一次寫操作。
AOF 和 RDB 同步政策可以同時啟用。當 AOF 啟用後,Redis 在啟動階段會加載 AOF 檔案, 這是因為相比 RDB,AOF 提供更好的持久性。 可以通過檢視 http://redis.io/topics/persistence 擷取更多資訊。
appendfilename "appendonly.aof"
append only file 的名稱,預設為 appendonly.aof。
appendfsync everysec
fsync() 調用用于告訴作業系統将資料寫入硬碟而不是放入輸出緩沖區中。 某些系統會馬上将資料 flush 到硬碟中,而某些系統隻是盡快嘗試寫入。 Redis 支援以下三種模式:
- no 不調用 fsync,讓作業系統決定什麼時候真正寫到硬碟
- always 每次寫入都對 append only file 進行 fsync 操作。最慢,也是最安全的選項。
- everysec 每秒進行一次 fsync 操作,折中的做法。
預設選項為 "everysec",對安全性和速度進行了折中。 更多資訊可以通過檢視 http://antirez.com/post/redis-persistence-demystified.html 擷取。
當 AOF fsync 政策設定為 always 或者 everysec 并且背景儲存程序(bgsave 或者 AOF 日志重寫)正在進行大量 I/O 操作, 某些 Linux 配置下,Redis 會阻塞太長時間在 fsync() 調用。目前,沒有方法可以避免這種狀況, 即使是在其他線程執行 fsync 操作也一樣會阻塞我們的同步寫 write(2) 操作。
no-appendfsync-on-rewrite no
為了緩和這種情況,可以在進行 BGSAVE 或者 BGREWRITEAOF 時禁止 fsync() 操作。 這意味着,當有子程序在儲存的時候 Redis 的持久性相當于 "appendfsync none"。
當你的 Redis 延遲過大時可以将 no-appendfsync-on-rewrite 設定為 "yes", 否則将其保持在 "no" 以保證持久性。
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
自動重寫 append only file 選項。 當 AOF 檔案增長到一定比例後,Redis 可以自動通過隐式調用 BGREWRITEAOF 指令來重寫 AOF 檔案。
Redis 會記錄上一次 rewrite 的 AOF 檔案大小(若從未進行 rewrite,Redis 會使用啟動時的 AOF 檔案大小)作為基準大小。
Redis 會比較目前大小和基準大小,若目前大小大于一定比例則觸發 rewrite。 為了防止增長比例到了但是總資料量還是非常小的情況就觸發 rewrite,你還需要指定一個 AOF rewritten 的最小大小。
通過将 auto-aof-rewrite-percentage 設定為 0 可以禁用此功能。
aof-load-truncated yes
當 Redis 啟動時可能會發現 AOF 檔案被截斷了(不完整),這可能是由于系統崩潰了, 特别是 ext4 沒有以 data=ordered 選項挂載的情況(在 Redis 崩潰而系統正常的情況下不會發生截斷)。
當這種情況發生時,Redis 可以選擇終止程序,或者加載 AOF 檔案上盡可能多的資料(目前的預設行為)。
當 aof-load-truncated 設定為 yes, Redis 服務端在啟動的時候發現加載的 AOF 檔案是被截斷的會發送一條日志來通知客戶。 若 aof-load-truncated 設定為 no,服務端會以錯誤形式終止程序并拒絕啟動。 這是需要使用者在重新開機服務前使用 "redis-check-aof" 工具來修複 AOF 檔案。
注意:當 Redis 服務端發現 AOF 檔案已經被損壞的情況下,服務端無論如何都會以錯誤終止程序。 這個選項隻會在 Redis 嘗試讀取更多資料但是發現已經讀到 AOF 檔案的末尾時才會生效。
aof-use-rdb-preamble yes
當重寫 AOF 檔案時,Redis 可以使用 RDB 檔案作為 AOF 檔案的前導,這樣可以更快地進行重寫和恢複。 當啟用這個功能時 AOF 檔案由兩部分組成:
[RDB file][AOF tail]
當加載 AOF 檔案時,Redis 通過以 “REDIS” 字元串開頭的 AOF 檔案識别出此檔案是由 RDB 和 AOF 組合而成的, Redis 會先加載 RDB 部分,然後再加載 AOF 部分。
LUA 腳本選項
lua-time-limit 5000
此選項用于控制 Lua 腳本的最長執行時間,機關為毫秒。
當 Lua 腳本的執行時間超出限制後,Redis 會在寫入相關日志,并且向用戶端傳回出錯。
當一個長時間運作的腳本超過超大限制後,隻有 SCRIPT KILL 和 SHUTDOWN NOSAVE 指令是有效的。 前者可以用于停止尚未進行寫操作的腳本。後者用于停掉服務, 當腳本已經開始進行寫操作并使用者于不想等腳本自然結束,這是唯一的方法。
将這個值設為 0 或者負數表示不限制最大運作時間。
REDIS 叢集
cluster-enabled yes
隻有那些以叢集的模式啟動的節點才能成為 Redis 叢集的一部分,普通的 Redis 執行個體不能成為 Redis 叢集的一部分。 為了讓 Redis 執行個體成為叢集的節點,需要将 cluster-enabled 設定為 yes。
cluster-config-file nodes-6379.conf
每個叢集節點都有一個叢集配置檔案,這個檔案不能手動修改,隻能由 Redis 節點建立和更新。 每個 Redis 叢集節點需要不同的叢集配置檔案,需要確定同一個系統運作的不同 Redis 執行個體使用了不同的名稱的叢集配置檔案。
cluster-node-timeout 15000
叢集節點的逾時時間,以毫秒為機關,當一個節點無法連接配接超過此選項配置的時間後, 就可以認為此節點處于失敗狀态。
其他的内部時間限制是此配置值的整數倍。
cluster-replica-validity-factor 10
當一個 master 處于失敗狀态,而它的 replica 節點資料太舊的情況下不會進行 failover。
沒有一個簡單的方法判斷 replica 節點的 "data age",是以需要以下方法來檢查:
- 如果有多個可用于 failover 的 replicas 節點,他們之間會交換消息以嘗試選出具有最好的 replication offset(處理了最多的資料)的節點。 Replicas 會根據 offset 擷取 rank,并且它開始進行 failover 的延時與 rank 成正比。
- 每個 replica 節點計算最後一次與 master 互動的時間。這個互動可以是 ping 或者是收到指令(如果 master 節點依然是 “connected” 狀态), 擷取是與 master 連接配接丢失以來經過的時間(如果複制連接配接斷開)。 如果上一個互動的時間太舊,則 replica 不會嘗試 failover。
第二點可以由使用者進行調整。當 replicas 節點最後一個與 master 節點互動的時間超過以下時間時,replicas 不會進行 failover。
(node-timeout * replica-validity-factor) + repl-ping-replica-period
比如 node-timeout 為 30 秒,而 replica-validity-factor 為 10,并且假設 repl-ping-replica-period 為 10 秒, 當 replica 最後與 master 互動的時間超過 310 秒時,replica 不會嘗試 failover。
replica-validity-factor 設定的過大會導緻擁有陳舊資料的 replicas 通過 failover 成為 master, 當這個值太小則會阻止叢集選出一個 replica。
為了最大的可用性,可以将 replica-validity-factor 設定為 0, 表示 replicas 總是嘗試 failover 成為 master 而不管最後一次與 master 互動的時間。
0 是保證所有叢集的所有分區總是能痊愈并且繼續提供服務的唯一選擇。
cluster-migration-barrier 1
叢集的 replicas 節點可以遷移到裸奔的 master 節點(就是沒有 replicas 節點的 master 節點)。 當裸奔的 master 節點發生故障後不能進行 failover,是以這個功能提高了整個叢集的抗故障能力。
replicas 節點隻有在遷移到裸奔的 master 節點後,舊的 master 依然有給定數量的 replicas 節點才能進行遷移。 這個給定數量就是 "migration barrier",由 cluster-migration-barrier 設定。 cluster-migration-barrier 為 1 表示 replicas 隻有在遷移後舊的 master 節點至少還有一個可工作的 replicas 節點才進行遷移。 這個值一般設定為你希望每個 master 需要多少個 replicas 節點。
這個選項的預設為 1。如果你想要禁止遷移隻需要将這個選項的值設定為一個很大的數即可。 設定為 0 隻有在調試的時候才有用,在生産環境使用這個值是很危險的。
cluster-require-full-coverage yes
預設情況下 Redis 叢集隻要發現有一個 hash slot 未被覆寫(沒有可用的節點為其提供服務)則會停止提供查詢服務。 是以當叢集發生部分故障(比如部分的 hash slot 未被覆寫),則會導緻整個叢集都無法工作。 當所有的 slots 再次被覆寫後,叢集會自動恢複到可用狀态。
如果你希望在叢集發生故障時可用的部分依然可以提供查詢服務,可以将 cluster-require-full-coverage 的值設定為 no。
cluster-replica-no-failover no
這個選項用于控制 master 發生故障時是否自動進行 failover。
當設定為 yes 後 master 發生故障時不會自動進行 failover,這時你可以進行手動的 failover 操作。
叢集的 DOCKER/NAT 支援
# cluster-announce-ip 10.1.1.5
# cluster-announce-port 6379
# cluster-announce-bus-port 6380
在某些部署環境下,Redis 叢集的節點位址不能被自動發現,這是因為這些節點是部署在 NAT 網絡或者端口是轉發的 (典型的情況就是使用了 Docker 或者其他容器)。
為了能讓 Redis 叢集工作在這種環境下,我們需要進行相關配置讓各個節點知道互相之間的外部位址, 這可以通過設定以下選項做到:
- cluster-announce-ip
- cluster-announce-port
- cluster-announce-bus-port
cluster-announce-ip 表示節點的外部位址,cluster-announce-port 表示節點的用戶端口, cluster-announce-bus-port 表示叢集消息總線端口。
若以上選項未配置,則将會啟用正常的 Redis 叢集自動檢測機制。 若 bus port 未設定,則會将其設定為 port + 10000。
慢查詢日志
slowlog-log-slower-than 10000
slowlog-max-len 128
慢查詢日志表示當一個查詢的運作時間超過設定的時間時,系統會将其記錄在慢查詢日志中。 這個運作時間隻包括執行指令需要的時間(隻有這個階段線程是處于阻塞狀态并且無法為其他請求提供服務), 不包括 I/O 操作,比如和用戶端通訊,發送響應請求等。
你可以設定慢查詢日志的兩個參數:一個是以微秒為機關的執行時間,超過這個時間的指令将會被記錄下來, 另一個選項是慢查詢日志的大小(就是一共會儲存多少條慢查詢日志)。 當一個新的指令需要被記錄到慢查詢日志并且目前慢查詢日志的條數已經到達限制時,會先将最舊的慢查詢日志移出隊列。
slowlog-log-slower-than 為負數時表示禁用慢查詢日志,0 表示記錄所有的指令。
slowlog-max-len 沒有上限,是以需要注意設定此值的大小,以免消耗過多的記憶體。
可以通過 SLOWLOG RESET 回收慢查詢日志所消耗的記憶體。
延遲監控
latency-monitor-threshold 0
Redis 延遲監視子系統收集的閥值,機關為毫秒,預設值為 0。 Redis 延遲監視子系統在運作時對不同的操作進行采樣,以便收集與 Redis 執行個體延遲相關的資料。
使用者可以通過 LATENCY 指令以圖表和報告的形式擷取延遲相關資訊。
系統隻會記錄時間大于等于 latency-monitor-threshold 的操作。 當 latency-monitor-threshold 設定為 0 表示關閉 Redis 延遲監視子系統。
預設情況下 Redis 延遲監視子系統是處于關閉狀态的,當你的系統沒有延遲問題,資料收集工作反而會造成性能沖擊。 可以通過以下指令在運作的 Redis 系統中啟用Redis 延遲監視子系統:
CONFIG SET latency-monitor-threshold <milliseconds>
事件通知
notify-keyspace-events ""
Redis 通過 Pub/Sub 機制向客戶通知 keyspace 中發生的事件。 這個特性的更多資訊可以檢視文檔: http://redis.io/topics/notifications
舉例來說,如果 keyspace 事件通知是啟用的,并且有一個客戶在資料庫 0 執行了如下指令:
DEL foo
這時 Redis 會通過 Pub/Sub 機制發送如下兩條消息:
PUBLISH __keyspace@0__:foo del
PUBLISH __keyevent@0__:del foo
可以通過配置 "notify-keyspace-events" 選項來讓 Redis 選擇發送哪些事件:
- K Keyspace 事件, 以 __keyspace@<db>__ 為字首釋出
- E Keyevent 事件, 以 __keyevent@<db>__ 為字首釋出
- g 通用指令 (不是針對特定類型的指令) 比如 DEL, EXPIRE, RENAME 等
- $ String 指令
- l List 指令
- s Set 指令
- h Hash 指令
- z Sorted set 指令
- x Expired 事件 (當一個 key 過期的時候生成)
- e Evicted 事件 (當一個 key 由于 maxmemory 被回收生成)
- A 表示 g$lshzxe 的别名,是以 "AKE" 表示所有事件
notify-keyspace-events 的值由上面的 0 到 N 個字元組成。空字元串表示禁止發送通知, 這是 notify-keyspace-events 的預設值。
舉個例子:
notify-keyspace-events Elg
表示啟用 list 指令和通用指令相關的事件通知。
notify-keyspace-events Ex
表示啟用過期事件通知。
需要注意的是如果要啟用事件通知至少要包含 K 或者 E,否則不會有事件釋出。
進階選項
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
當哈希表的項不超過 hash-max-ziplist-entries,并且每一項的長度不超過 hash-max-ziplist-value 使用 ziplist 儲存資料。
list-max-ziplist-size -2
Redis 的 List 内部是通過 quicklist 實作的(Redis 3.2 開始使用),quicklist 是一個雙向連結清單。 quicklist 的每個節點都是一個 ziplist。list-max-ziplist-size 就是用于配置 quicklist 中的每個節點的 ziplist 的大小。 當這個值配置為正數時表示 quicklist 每個節點的 ziplist 所包含的元素個數是一個确定的數量。 當 list-max-ziplist-size 為負數時表示限制每個 ziplist 的大小,具體有以下含義:
- -5:最大 64 kb <--- 正常環境不推薦
- -4:最大 32 kb <--- 不推薦
- -3:最大 16 kb <--- 可能不推薦
- -2:最大 8 kb <--- 不錯
- -1:最大 4kb <--- 不錯
預設值為 -2,也是官方最推薦的值,當然你可以根據自己的實際情況進行修改。
list-compress-depth 0
quicklist 中的 ziplist 節點會被壓縮。為了 push/pop 操作的高效性,quicklist 的頭和尾節點永遠都不會被壓縮。 list-compress-depth 選項用于控制 quicklist 中壓縮的節點的深度,下面的示例中加了中括号的節點表示未壓縮。
- 0 表示不對節點進行壓縮,這是預設的值
- 1 表示對頭和尾節點外的其他節點進行壓縮, [head]->node->node->...->node->[tail]
- 2 [head]->[next]->node->node->...->node->[prev]->[tail]
- 3 [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail]
- 依次類推
set-max-intset-entries 512
當 Redis 的集合類型儲存的資料均為數字,并且元素個數不超過 set-max-intset-entries 的時候。 Redis 将使用特殊的 intset 結構來儲存這個集合。
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
類似哈希表和清單,當排序集合的元素個數不超過 zset-max-ziplist-entries 并且每個元素的長度不超過 zset-max-ziplist-value 時,Redis 将使用 ziplist 儲存這個排序集合。
hll-sparse-max-bytes 3000
HyperLogLog 稀疏模式的位元組限制,包括了 16 位元組的頭,預設值為 3000。 當超出這個限制後 HyperLogLog 将有稀疏模式轉為稠密模式。
将這個值設定為超過 16000 是沒必要的,因為這時使用稠密模式更省空間。
stream-node-max-bytes 4096
stream-node-max-entries 100
用于設定 Streams 單個節點的最大大小和最多能儲存多個個元素。
activerehashing yes
預設值為 yes。
當啟用這個功能後,Redis 對哈希表的 rehash 操作會在每 100 毫秒 CPU 時間中的 1 毫秒進行。 Redis 的哈希表實作的 rehash 政策是一個惰性政策:就是說你對這個哈希表進行越多操作,你将有更多的 rehash 機會, 若你的伺服器處于空閑狀态則不會有機會完成 rehash 操作,這時哈希表會占用更多記憶體。
預設情況下會在每一秒中用 10 毫秒來對主哈希表進行 rehash。
如果在你的環境中需要有嚴格的延遲要求,則需要使用将 activerehashing 配置為 no,比如說需要在 2 毫秒内相應查詢操作。 否則你應該将這個選項設定诶 yes,這樣可以更及時地釋放空閑的記憶體。
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
用戶端輸出緩沖區限制可用于強制斷開從伺服器讀取資料的速度不夠快的用戶端 (一個常見的原因是 Pub/Sub 用戶端處理釋出者的消息不夠快)。
可以為每種用戶端設定不同的限制:
- normal -> 普通用戶端,包括 MONITOR 用戶端
- replica -> 複制用戶端
- pubsub -> 訂閱了至少一個頻道的用戶端
client-output-buffer-limit 選項的文法為:
client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
當一個用戶端到達 hard limit 後會馬上被斷開,或者在到達 soft limit 并持續 soft seconds 秒後會被斷開。
預設情況下,普通用戶端不會有限制,因為除非主動請求否則他們不會收到資訊, 隻有異步的用戶端才可能發生發送請求的速度比讀取響應的速度快的情況。
預設情況下 pubsub 和 replica 用戶端會有預設的限制,因為這些用戶端是以 Redis 服務端 push 的方式接收資料的。
soft limit 或者 hard limit 都可以設定為 0,這表示不啟用此限制。
client-query-buffer-limit 1gb
用戶端查詢緩沖區會累加新的指令。 預設情況下,他們會限制在一個固定的數量避免協定同步失效(比如用戶端的 bug)導緻查詢緩沖區出現未綁定的記憶體。
但是,如果有類似于巨大的 multi/exec 請求的時候可以修改這個值以滿足你的特殊需求。
proto-max-bulk-len 512mb
在 Redis 協定中,批量請求通常限制在 512 mb 内,可以通過修改 proto-max-bulk-len 選項改變這個限制。
hz 10
預設值是 10,範圍是 1 到 500,超過 100 一般都不是一個好主意。 Redis 會通過調用内部函數來完成很多背景任務,比如關閉逾時的用戶端的連接配接,清除過期的 key,等等。
Redis 通過 hz 設定的值來決定執行這些任務的頻繁程度。
hz 的預設值是 10,可以通過提高這個值來使得 CPU 在空閑的時候使用更多的 CPU 時間來處理背景任務。 但同時這會使得當有很多 key 在同一時間過期時,過期處理會更精确。
很多客戶隻有在一些需要很低延遲的環境中才會将這個值從 10 提升到 100。
dynamic-hz yes
通常來說根據連接配接上來的用戶端數量對 HZ 的值按比例進行調整是有用的。 這很有用,例如,為了避免每次背景任務處理太多的用戶端,進而避免高延遲峰值。
預設情況下 HZ 的值為 10,啟用 dynamic-hz 後,當有大量用戶端連接配接進來時 HZ 的值會臨時性地調高。
啟用 dynamic-hz 後,HZ 的配置值将作為基線,當有大量的用戶端連接配接進來時,Redis 會将 HZ 的實際值設定為 HZ 的配置值的整數倍。 通過這種方式,空閑的 Redis 執行個體隻會占用非常小的 CPU 時間,當執行個體變得繁忙時 Redis 能更快地進行響應(相對未啟用 dynamic-hz 的情況)。
aof-rewrite-incremental-fsync yes
當子程序進行 AOF 的重寫時,如果啟用了 aof-rewrite-incremental-fsync, 子程序會每生成 32 MB 資料就進行一次 fsync 操作。 通過這種方式将資料分批送出到硬碟可以避免高延遲峰值。
rdb-save-incremental-fsync yes
當 Redis 儲存 RDB 檔案時,如果啟用了 rdb-save-incremental-fsync 功能, Redis 會每生成 32 MB 資料就執行一次 fsync 操作。 通過這種方式将資料分批送出到硬碟可以避免高延遲峰值。
# lfu-log-factor 10
# lfu-decay-time 1
Redis LFU 回收政策(忘了的話可以回顧下 maxmemory 選項)是可以調整的。 在開始的時候使用預設值并且隻有在經過對如何提升性能和 key LFU 随時間如何改變進行調查查後才對其更改是一個好的主意。 這可以通過 OBJECT FREQ 指令進行檢查。
Redis 的 LFU 實作目前有兩個可調整的參數:計數器對數因子(couter logarithm factor) 和 計數器衰退時間(counter decay time)。 在修改這兩個參數之前了解這兩個參數是很重要的。
每個 key 的 LFU 計數器隻有 8 bits,也就是說最大值為 255,是以 Redis 通過對數行為來對計數進行機率性的增加。 當一個 key 被通路後,計數器通過如下方式進行增加(假設計數器的舊值為 old_value):
- 取出一個 0 到 1 之間的随機數 R
- 通過如下方式算出機率 P: 1 / (old_value * lfu_log_factor + 1)
- 隻有當 R < P 時,才增加計數器
lfu-log-factor 的預設值為 10。下表是不同計數器對數因子下計數器的改變頻率:
factor | 100 hits | 1000 hits | 100K hits | 1M hits | 10M hits |
104 | 255 | 255 | 255 | 255 | |
1 | 18 | 49 | 255 | 255 | 255 |
10 | 10 | 18 | 142 | 255 | 255 |
100 | 8 | 11 | 49 | 143 | 255 |
注意:上表是通過如下指令獲得的: redis-benchmark -n 1000000 incr foo redis-cli object freq foo;計數器的初始值為 5
計數器衰減時間是 key 計數器除以 2 (如果值小于 <= 10,則遞減)所必須經過的時間,機關為分鐘。 lfu-decay-time 的預設值為 1。 0 表示每次都對計數器進行衰減。
線上碎片整理(active defragmentation)
https://zhuanlan.zhihu.com/p/263667109?utm_source=wechat_session
警告:這個功能是實驗性的。當然此功能已經在包括生産環境在内的環境中通過壓力測試。 并且被多名工程師手工測過一段時間。
活動碎片整理允許 Redis 伺服器壓縮記憶體中由于申請和釋放資料塊導緻的碎片,進而回收記憶體。 碎片是每次申請記憶體(幸運的是 Jemalloc 出現碎片的幾率小很多)的時候會自然發生的。 通常來說,為了降低碎片化程度需要重新開機服務,或者至少需要清除所有的資料然後重新建立。 得益于 Oran Agra 在 Redis 4.0 實作的這個特性,程序可以在服務運作時以 “熱” 方式完成這些目的。
通常來說當碎片化達到一定程度(檢視下面的配置)Redis 會使用 Jemalloc 的特性建立連續的記憶體空間, 并在此記憶體空間對現有的值進行拷貝,拷貝完成後會釋放掉舊的資料。 這個過程會對所有的導緻碎片化的 key 以增量的形式進行。
需要重點了解的是:
- 這個特性預設是關閉的,并且隻有在編譯 Redis 時使用我們代碼中的 Jemalloc 版本才生效。(這是 Linux 下的預設行為)
- 如果沒有碎片問題,你永遠不需要啟用這項特性
- 如果你需要試驗這項特性,可以通過指令 CONFIG SET activefrag yes 來啟用
相關的配置參數可以很好的調整碎片整理過程。如果你不知道這些選項的作用最好使用預設值。
activedefrag yes
啟用碎片整理。
active-defrag-ignore-bytes 100mb
有至少多少碎片時才開始碎片整理。
active-defrag-threshold-lower 10
有至少多少比例的碎片時才開始碎片整理。
active-defrag-threshold-upper 100
有多少比例的碎片時才開始以最大努力進行碎片整理。
active-defrag-cycle-min 5
進行碎片整理時至少使用多少比例的 CPU 時間。
active-defrag-cycle-max 75
active-defrag-max-scan-fields 1000