前言
本文來自http://cs-cjl.com/中的redis配置系列,基於Redis 5.0的配置說明,非常詳細。
配置文件redis.conf說明
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 的默認行為都是以阻塞方式刪除。當然你可以配置上述四個選項來改變這種默認行為。
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-time-limit 5000
此選項用於控制 Lua 腳本的最長執行時間,單位為毫秒。
當 Lua 腳本的執行時間超出限制后,Redis 會在寫入相關日志,並且向客戶端返回出錯。
當一個長時間運行的腳本超過超大限制后,只有 SCRIPT KILL 和 SHUTDOWN NOSAVE 命令是有效的。 前者可以用於停止尚未進行寫操作的腳本。后者用於停掉服務, 當腳本已經開始進行寫操作並用戶於不想等腳本自然結束,這是唯一的方法。
將這個值設為 0 或者負數表示不限制最大運行時間。
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 操作。
# 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 |
---|---|---|---|---|---|
0 | 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 表示每次都對計數器進行衰減。
活動碎片整理允許 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
最大努力進行碎片整理時使用多少 CPU 時間。
active-defrag-max-scan-fields 1000
進行主字典掃描時處理的 set/hash/zset/list 字段的最大數量(就是說在進行主字典掃描時 set/hash/zset/list 的長度小於這個值才會處理,大於這個值的會放在一個列表中延遲處理)。