0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

redis.conf 7.0配置和原理全解

OSC開源社區(qū) ? 來源:碼哥字節(jié) ? 2023-06-08 15:57 ? 次閱讀

1.1 常規(guī)通用配置

這些是我的常規(guī)配置,每個 Redis 啟動必備參數(shù),你一定要掌握,涉及到網(wǎng)絡(luò)、模塊插件、運行模式、日志等。

MODULES

這個配置可以加載模塊插件增強我的功能,常見的模塊有 RedisSearch、RedisBloom 等。關(guān)于模塊加載可以參考【5.6 布隆過濾器原理與實戰(zhàn)】章節(jié)集成布隆過濾器便是通過以下配置實現(xiàn)加載布隆過濾器插件。

loadmodule/opt/app/RedisBloom-2.2.14/redisbloom.so

NETWORK

這部分都是與網(wǎng)絡(luò)相關(guān)的配置,很重要滴,配置不當(dāng)將會有安全和性能問題。

bind

bind用于綁定本機的網(wǎng)絡(luò)接口(網(wǎng)卡),注意是本機。

每臺機器可能有多個網(wǎng)卡,每個網(wǎng)卡都有一個 IP 地址。配置了 bind,則表示我只允許來自本機指定網(wǎng)卡的 Redis 請求。

MySQL:“bind 是用于限制訪問你的機器 IP 么?”

非也,注意,這個配置指的并不是只有 bind 指定的 IP 地址的計算機才能訪問我。如果想限制指定的主機連接我,只能通過防火墻來控制,bind 參數(shù)不也能起到這個作用。

舉個例子:如果我所在的服務(wù)器有兩個網(wǎng)卡,每個網(wǎng)卡有一個 IP 地址, IP1,IP2。

配置 bind IP1,則表示只能通過這個網(wǎng)卡地址來的網(wǎng)絡(luò)請求訪問我,也可以使用空格分割綁定多個網(wǎng)卡 IP。

我的默認(rèn)配置是bind 127.0.0.1 -::1 表示綁定本地回環(huán)地址 IPv4 和 Ipv6。- 表示當(dāng) ip 不存在也能啟動成功。

protected-mode

MySQL:網(wǎng)絡(luò)世界很危險滴,你如何保證安全?

默認(rèn)開啟保護模式,如果沒有設(shè)置密碼或者沒有 bind 配置,我只允許在本機連接我,其它機器無法連接。

如果想讓其它機器連接我,有以下三種方式。

配置為 protected-mode no(不建議,地球很危險滴,防人之心不可無)。

protected-mode yes,配置 bind 綁定本機的 IP。

protected-mode yes,除了設(shè)置 bind 以外,還可以通過 requirepass magebyte設(shè)置密碼為 magebyte, 讓其他機器的客戶端能使用密碼訪問我。

bind、protected-mode、requirepass 之間的關(guān)系

bind:指定的是我所在服務(wù)器網(wǎng)卡的 IP,不是指定某個可以訪問我的機器。

protected-mode:保護模式,默認(rèn)開啟,如果沒有設(shè)置密碼或者 bind IP,我只接受本機訪問(沒密碼+保護模式啟動=本地訪問)。

requirepass,Redis 客戶端連接我通行的密碼。

如果參數(shù)設(shè)置為bind 127.0.0.1 -::1,不管 protected-mode是否開啟,只能本機用 127.0.0.1 連接,其他外機無法連接。

在生產(chǎn)環(huán)境中,為了安全,不要關(guān)閉 protected-mode,并設(shè)置 requirepass 參數(shù)配置密碼和 bind 綁定機器的網(wǎng)卡 IP。

port 6379

用于指定我監(jiān)聽的客戶端 socket 端口號,默認(rèn) 6379。設(shè)置為 0 則不會監(jiān)聽 TCP 連接,我想沒人設(shè)置為 0 吧。

tcp-backlog 511

用于在 Linux 系統(tǒng)中控制 TCP 三次握手已完成連接隊列(完成三次握手后)的長度,如果已完成連接隊列已經(jīng)滿則無法放入,客戶端會報read timeout或者connection reset by peer的錯。

MySQL:“在高并發(fā)系統(tǒng)中這玩意需要調(diào)大些吧?”

是的,我的默認(rèn)配置是 511,這個配置的值不能大于 Linux 系統(tǒng)定義的 /proc/sys/net/core/somaxconn 值,Linux 默認(rèn)的是 128。

所以我在啟動的時候你會看到這樣的警告:WARNING: The TCP backlog setting of 511 cannot be enforced because kern.ipc.somaxconn is set to the lower value of 128.

當(dāng)系統(tǒng)并發(fā)量大并且客戶端速度緩慢的時候,在高并發(fā)系統(tǒng)中,需要設(shè)置一個較高的值來避免客戶端連接速度慢的問題。

需要分別調(diào)整 Linux 和 Redis 的配置。

建議修改為 2048 或者更大,Linux 則在 /etc/sysctl.conf中添加net.core.somaxconn = 2048配置,并且在終端執(zhí)行 sysctl -p即可。

碼哥使用 macOS 系統(tǒng),使用 sudo sysctl -w kern.ipc.somaxconn=2048即可。

timeout

timeout 60 單位是秒,如果在 timout 時間內(nèi)客戶端跟我沒有數(shù)據(jù)交互(客戶端不再向我發(fā)送任何數(shù)據(jù)),我將關(guān)閉該客戶端連接。

注意事項

0 表示永不斷開。

timeout 對應(yīng)源碼 server.maxidletime

tcp-keepalive

tcp-keepalive 300 單位是秒,官方建議值是 300。這是一個很有用的配置,實現(xiàn) TCP 連接復(fù)用。

用途

用于客戶端與服務(wù)端的長連接,如果設(shè)置為非 0,則使用 SO_KEEPALIVE 周期性發(fā)送 ACK 給客戶端,俗話就是用來定時向客戶端發(fā)送 tcp_ack 包來探測客戶端是否存活,并保持該連接。不用每次請求都建立 TCP 連接,畢竟創(chuàng)建連接是比較慢的。

常規(guī)配置

這些都是我的常規(guī)配置,比較通用,你必須了解。你可以把這些配置寫到一個特有文件中,其他節(jié)點可以使用 include /path/to/other.conf 配置來加載并復(fù)用該配置文件的配置。

daemonize

配置daemonize yes表示使用守護進程的模式運行,默認(rèn)情況下我是以非守護線程的模式運行(daemonize no),開啟守護進程模式,會生成一個 .pid文件存儲進程號。

你也可以配置 pidfile /var/run/redis_6379.pid 參數(shù)來指定文件的生成目錄,當(dāng)關(guān)閉服務(wù)的時候我會自動刪除該文件。

loglevel

指定我在運行時的日志記錄級別。默認(rèn)是 loglevel notice。有以下幾個選項可以配置。

debug:會記錄很多信息,主要用于開發(fā)和測試。

verbose:許多用處不大的信息,但是比 debug 少,如果發(fā)現(xiàn)生產(chǎn)出現(xiàn)一些問題無從下手,可使用該級別來輔助定位。

notice:生產(chǎn)一般配置這個級別。

warning:只會記錄非常重要/關(guān)鍵的的日志。

logfile

指定日志文件目錄,默認(rèn)是 logfile "",表示只在標(biāo)準(zhǔn)控制臺輸出。

需要注意的是,如果使用標(biāo)準(zhǔn)控制臺輸出,并且使用守護進程的模式運行,日志會發(fā)送到 /dev/null。

databases

設(shè)置數(shù)據(jù)庫數(shù)量,我的默認(rèn)配置是 databases 16 。默認(rèn)的數(shù)據(jù)庫是 DB 0,使用集群模式的時候, database 只有一個,就是 DB 0。

1.2 RDB 快照持久化

MySQL:“要怎么開啟 RDB 內(nèi)存快照文件實現(xiàn)持久化呢?”

RDB 快照持久化相關(guān)的配置,必須掌握,合理配置能我實現(xiàn)宕機快速恢復(fù)實現(xiàn)高可用。

save

使用 save 開啟持久化,比如 save 60 100 表示 60 秒內(nèi),至少執(zhí)行了 100 個寫操作,則執(zhí)行 RDB 內(nèi)存快照保存。

不關(guān)心是否丟失數(shù)據(jù),你也可以通過配置 save "" 來禁用 RDB 快照保存,讓我性能起飛,沖出三界外。

默認(rèn)情況的我會按照如下規(guī)則來保存 RDB 內(nèi)存快照。

在 3600 秒 (一個小時) 內(nèi),至少執(zhí)行了一次更改。

在 300 秒(5 分鐘)內(nèi),至少執(zhí)行了 100 個更改。

在 60 秒后,至少執(zhí)行了 10000 個更改。

也可以通過 save 3600 1 300 100 60 10000 配置來顯示設(shè)置。

stop-writes-on-bgsave-error

MySQL:“bgsave 失敗的話,停止接收寫請求要怎么配置?”

默認(rèn)配置為 stop-writes-on-bgsave-error yes,它的作用是如果 RDB 內(nèi)存快照持久化開啟并且最后一次 bgsave 失敗的話就停止接收寫請求。

我通過這種強硬的方式來告知程序員數(shù)據(jù)持久化不正常了,否則可能沒人知道 RDB 快照持久化出問題了。

當(dāng) bgsave 后臺進程能正常工作,我會自動允許寫請求。如果你對此已經(jīng)有相關(guān)的監(jiān)控,即使磁盤出問題(磁盤空間不足、沒有權(quán)限等)的情況下依舊處理寫請求,那么設(shè)置成 no 即可。

rdbcompression

MySQL:“RDB 內(nèi)存快照文件比較大,可以壓縮么?”

我的默認(rèn)配置是 rdbcompression yes,意味著對 RDB 內(nèi)存快照文件中的 String 對象使用 LZF 算法做壓縮。這個非常有用,能大大減少文件大小,受益匪淺呀,建議你開啟。

如果你不想損失因為壓縮 RDB 內(nèi)存快照文件的 CPU 資源,那就設(shè)置成 no,帶來的后果就是文件比較大,傳輸占用更大的帶寬(要三思啊,老伙計)。

rdbchecksum

默認(rèn)配置是 rdbchecksum yes,從 5.0 版本開始,RDB 文件末尾會寫入一個 CRC64 檢驗碼,能起到一定的糾錯作用,但是要丟失大約 10% 的性能損失,你可以設(shè)置成功 no 關(guān)閉這個功能來獲得更快的性能。

關(guān)閉了這個功能, RDB 內(nèi)存快照文件的校驗就是 0 ,代碼會自動跳過檢查。

推薦你關(guān)閉,讓我快到令人發(fā)指。

你還可以通過 dbfilename 參數(shù)來指定 RDB 內(nèi)存快照文件名,默認(rèn)是 dbfilename dump.rdb。

rdb-del-sync-files

默認(rèn)配置是 rdb-del-sync-files no,主從進行全量同步時,通過傳輸 RDB 內(nèi)存快照文件實現(xiàn),沒有開啟 RDB 持久化的實例在同步完成后會刪除該文件,通常情況下保持默認(rèn)即可。

dir

我的工作目錄,注意這是目錄而不是文件, 默認(rèn)配置是dir ./。比如存放 RDB 內(nèi)存快照文件、AOF 文件。

.3 主從復(fù)制

這部分配置很重要,涉及到主從復(fù)制的方方面面,是高可用的基石,重點對待啊伙計們。

replicaof

主從復(fù)制,使用replicaof 配置將當(dāng)前實例成為其他 Redis 服務(wù)的從節(jié)點

masterip,就是 master 的 IP。

masterport,master 的端口。

有以下幾點需要注意。

我使用異步實現(xiàn)主從復(fù)制,當(dāng) Master 節(jié)點的 slave 節(jié)點數(shù)量小于指定的數(shù)量時,你可以設(shè)置 Master 節(jié)點停止處理寫請求。

主從復(fù)制如果斷開的時間較短,slave 節(jié)點可以執(zhí)行部分重新同步,需要合理設(shè)置 backlog size,保證這個緩存區(qū)能完整保存斷連期間 Master 接受寫請求的數(shù)據(jù),防止出現(xiàn)全量復(fù)制,具體配置后面會細說。

主從復(fù)制是自動的,不需要用戶干預(yù)。

masterauth

如果當(dāng)前節(jié)點是 slave,且 master 節(jié)點配置了 requirepass 參數(shù)設(shè)置了密碼,那么 slave 節(jié)點必須使用該參數(shù)配置為 master 的密碼,否則 master 節(jié)點將拒絕該 slave 節(jié)點的請求。

配置方式為 masterauth

masteruser

在 6.0 以上版本,如果使用了我的 ACL 安全功能,只配置 masterauth 還不夠。因為默認(rèn)用戶不能運行 PSYNC 命令或者主從復(fù)制所需要的其他命令。

這時候,最好配置一個專門用于主從復(fù)制的特殊用戶,配置方式為 masteruser

replica-serve-stale-data

MySQL:“當(dāng) slave 節(jié)點與 master 失去連接,導(dǎo)致主從同步失敗的時候,還能處理客戶端請求么?”

slave 節(jié)點可以有以下兩種行為來決定是否處理客戶端請求。

配置為 yes,slave 節(jié)點可以繼續(xù)處理客戶端請求,但是數(shù)據(jù)可能是舊的,因為新的沒同步過來。也可能是空的,如果是第一次同步的話。

配置為 no,slave 節(jié)點將返回錯誤 MASTERDOWN Link with MASTER is down and replica-serve-stale-data is set to no給客戶端。但是以下的指令還是可以執(zhí)行:INFO, REPLICAOF, AUTH, SHUTDOWN, REPLCONF, ROLE, CONFIG, SUBSCRIBE,UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB, COMMAND, POST,HOST and LATENCY。

我的默認(rèn)配置是 replica-serve-stale-data yes。

replica-read-only

這個配置用于控制 slave 實例能否接收寫指令,在 2.6 版本后默認(rèn)配置為 yes,表示 slave 節(jié)點只處理讀請求,如果為 no 則可讀可寫。

我建議保持默認(rèn)配置,讓 slave 節(jié)點只作為副本實現(xiàn)高可用。想要提高寫性能,使用集群模式橫向拓展更好。

repl-diskless-sync

主從復(fù)制過程中,新加入的 slave 節(jié)點和 slave 節(jié)點重連后無法進行增量同步,需要進行一次全量同步,master 節(jié)點會生成 RDB 內(nèi)存快照文件傳輸給 slave 節(jié)點。

所以這個配置是用于控制傳輸方式的,傳輸方式有兩種。

Disk-backed(磁盤備份):master 節(jié)點創(chuàng)建新進程將 RDB 內(nèi)存快照文件寫到磁盤,主進程逐步將這個文件傳輸?shù)讲煌?slave 節(jié)點。

Diskless(無盤備份):master 節(jié)點創(chuàng)建一個新進程直接把 RDB 內(nèi)存快照內(nèi)容寫到 Socket,不會將 RDB 內(nèi)存快照文件持久化到磁盤。

使用磁盤備份的方式,master 保存在磁盤的 RDB 內(nèi)存快照文件可以讓多個 slave 復(fù)用。

使用無盤備份的話,當(dāng) RDB 內(nèi)存快照文件傳輸開始,如果當(dāng)前有多個slave 節(jié)點與 master 建立連接,我會使用并行傳輸?shù)姆绞綄?RDB 內(nèi)容傳輸給多個節(jié)點。

默認(rèn)的配置是 repl-diskless-sync yes,表示使用無盤備份。在磁盤速度很慢,而網(wǎng)絡(luò)超快的情況下,無盤備份會更給力。如果網(wǎng)絡(luò)很慢,有可能會出現(xiàn)數(shù)據(jù)丟失,推薦你改成 no。

repl-diskless-sync-delay

使用無盤復(fù)制的話,如果此刻有新的 slave 發(fā)起全量同步,需要等待之前的傳輸完畢才能開啟傳輸。

所以可以使用配置 repl-diskless-sync-delay 5 參數(shù)指定一個延遲時間,這個單位是秒,讓 master 節(jié)點等待一會,讓更多 slave 節(jié)點連接再執(zhí)行傳輸。

因為一旦開始傳輸,master 節(jié)點無法響應(yīng)新的 slave 節(jié)點的全量復(fù)制請求,只能在隊列中等待下一次 RDB 內(nèi)存快照傳輸。

想要關(guān)閉這個功能,設(shè)置為 0 即可。

repl-diskless-load

mastar 節(jié)點有兩種方式傳輸 RDB,slave 節(jié)點也有兩種方式加載 master 傳輸過來的 RDB 數(shù)據(jù)。

傳統(tǒng)方式:接受到數(shù)據(jù)后,先持久化到磁盤,再從磁盤加載 RDB 文件恢復(fù)數(shù)據(jù)到內(nèi)存中,這是傳統(tǒng)方式。

diskless-load:從 Socket 中一邊接受數(shù)據(jù),一邊解析,實現(xiàn)無盤化。

一共有三個取值可配置。

disabled:不使用 diskless-load 方式,即采用磁盤化的傳統(tǒng)方式。

on-empty-db:安全模式下使用 diskless-load(也就 slave 節(jié)點數(shù)據(jù)庫為空的時候使用 diskless-load)。

swapdb:使用 diskless-load 方式加載,slave 節(jié)點會緩存一份當(dāng)前數(shù)據(jù)庫的數(shù)據(jù),再清空數(shù)據(jù)庫,接著進行 Socket 讀取實現(xiàn)加載。緩存一份數(shù)據(jù)的目的是防止讀取 Socket 失敗。

需要注意的是,diskless-load 目前在實驗階段,因為 RDB 內(nèi)存快照數(shù)據(jù)并沒有持久化到磁盤,因此有可能造成數(shù)據(jù)丟失;

另外,該模式會占用更多內(nèi)存,可能會導(dǎo)致 OOM。

repl-ping-replica-period

默認(rèn)配置repl-ping-replica-period 10 表示 slave 每 10 秒 PING 一次 master。

repl-timeout

很重要的一個參數(shù),slave 與 master 之間的復(fù)制超時時間,默認(rèn)配置是repl-timeout 60,表示在 60 秒內(nèi) ping 不通,則判定超時。

超時包含以下三種情況。

slave 角度,全量同步期間,在 repl-timeout 時間內(nèi)沒有收到 master 傳輸?shù)?RDB 內(nèi)存快照文件。

slave 角度,在 repl-timeout 時間內(nèi)沒有收到 master 發(fā)送的數(shù)據(jù)包或者 ping。

master 角度,在 repl-timeout 時間內(nèi)沒有收到 REPCONF ACK (復(fù)制偏移量 offset)確認(rèn)信息。

當(dāng)檢測到超時,將會關(guān)閉 master 與 slave 之間的連接,slave 會發(fā)起重新建立主從連接的請求,對于內(nèi)存數(shù)據(jù)比較大的系統(tǒng),可以增大 repl-timeout 的值。

你需要注意的是,這個配置一定要大于 repl-ping-replica-period的值,否則每次心跳監(jiān)測都超時。

repl-disable-tcp-nodelay

當(dāng) slave 與 master 全量同步(slave 發(fā)送 psync/sync 指令給 master)完成后,后續(xù)的增量同步是否設(shè)置成 TCP_NODELAY。

如果設(shè)置成 yes,master 將合并小的 TCP 包從而節(jié)省帶寬,但是會增加同步延遲(40 ms),造成 master 與 slave 數(shù)據(jù)不一致;設(shè)置成 no,則 master 會立即發(fā)送數(shù)據(jù)給 slave,沒有延遲。

默認(rèn)配置 repl-disable-tcp-nodelay no。

repl-backlog-size

設(shè)置主從復(fù)制積壓緩沖區(qū)(backlog) 容量大小,這是一個環(huán)形數(shù)組,正常主從同步不涉及到 repl-backlog。當(dāng)主從斷開重連,repl-backlog 的作用就出來了。

緩沖區(qū)用于存放斷連期間 master 接受的寫請求數(shù)據(jù),當(dāng)主從斷開重連,通常不需要執(zhí)行全量同步,只需要將斷連期間的部分?jǐn)?shù)據(jù)傳遞到 slave 即可。

主從復(fù)制積壓緩沖區(qū)越大,slave 可以承受的斷連時間越長。

默認(rèn)配置是 repl-backlog-size 1mb,建議根據(jù)每秒流量大小和斷開重連時間長,設(shè)置大一點,比如 128 mb。

repl-backlog-ttl

用于配置當(dāng) master 與 slave 斷連多少秒之后,master 清空主從復(fù)制積壓緩沖區(qū)(repl-backlog)。配置成 0 ,表示永遠不清空。默認(rèn)配置repl-backlog-ttl 3600。

replica-priority

slave 優(yōu)先級,這個配置是給哨兵使用的,當(dāng) master 節(jié)點掛掉,哨兵會選擇一個 priority 最小的 slave 節(jié)點作為新的 master,這個值越小沒接越優(yōu)先選中。

如果是 0,那意味著這個 slave 將不能選中成為 master,默認(rèn)配置是 replica-priority 100。

min-slaves-to-write 和 min-slaves-max-lag

這兩個配置要一起設(shè)置才有意義,如果有一個配置成 0,表示關(guān)閉該特性。

先看默認(rèn)配置含義。

min-replicas-to-write3
min-replicas-max-lag10

如果 master 發(fā)現(xiàn)超過 3 個 slave 節(jié)點連接 master 延遲大于 10 秒,那么 master 就停止接收客戶端寫請求。這么做的目的是為了盡可能保證主從數(shù)據(jù)一致性。

master 會記錄每個 slave 最近一次發(fā)來 ping 的時間,掌握每個 slave 的運行情況。

tracking-table-max-keys

我在 Redis 6.0 版本,實現(xiàn)了服務(wù)端輔助實現(xiàn)客戶端緩存的特性,需要追蹤客戶端有哪些 key。當(dāng)某個 key 被修改,我需要把這個失效信息發(fā)送到對應(yīng)的客戶端將本地緩存失效,這個配置就是用于指定追蹤表保存的最大 key 數(shù)量,一旦超過這個數(shù)量,即使這個 key 沒有被修改,為了回收內(nèi)存我也會強制這個 key 所在的客戶端緩存值失效。

設(shè)置 0 表示不限制,需要注意的是,如果使用廣播模式實現(xiàn)鍵追蹤,則不需要額外內(nèi)存,忽略這個配置。

使用廣播模式的不足就是與這個 key 無關(guān)的客戶端也會收到失效消息。

1.4 安全

正是由于我快的一塌糊涂,攻擊者一秒鐘可以嘗試 100 萬個密碼,所以你應(yīng)該使用非常健壯的密碼。

ACL

ACL 日志的最大長度,默認(rèn)配置 acllog-max-len 128 表示最大 128 mb。

另外,使用 aclfile /etc/redis/users.acl 配置 ACL 文件所在位置。

requirepass

當(dāng)前 Redis 服務(wù)器的訪問密碼,默認(rèn)是不需要密碼訪問,網(wǎng)絡(luò)危險,必須設(shè)置,如 requirepass magebyte660設(shè)置密碼為 “magebyte666”。

maxclients

設(shè)置客戶端同時連接的最大數(shù)量,默認(rèn)設(shè)置是 maxclients 10000。達到最大值,我將關(guān)閉客戶端新的連接,并發(fā)送一個 max number of clients reached 錯誤給客戶端。

1.5 內(nèi)存管理

作為用內(nèi)存保存數(shù)據(jù)的我,這部分的配置也相當(dāng)重要。

maxmemory

設(shè)置使用內(nèi)存最大字節(jié),當(dāng)內(nèi)存達到限制,我將嘗試根據(jù)配置的內(nèi)存淘汰策略(參見 maxmemory-policy)刪除一些 key。建議你不要設(shè)置太大的內(nèi)存,防止執(zhí)行 RDB 內(nèi)存快照文件或者 AOF 重寫的時候因數(shù)據(jù)太大而阻塞過長時間。

推薦最大設(shè)置為 maxmemory 6GB。

如果淘汰策略是 noeviction,當(dāng)收到寫請求,我將回復(fù)錯誤給客戶端,讀請求依然可以執(zhí)行。

如果你把我當(dāng)做一個 LRU 或 LFU 緩存系統(tǒng)的時候,那請用心關(guān)注以下配置。

maxmemory-policy

設(shè)置內(nèi)存淘汰策略,定義當(dāng)內(nèi)存滿時如何淘汰 key,默認(rèn)配置是 noeviction。

volatile-lru -> 在設(shè)置過期時間的 key 中使用近似 LRU 驅(qū)逐。

allkeys-lru -> 在所有 key 中使用近似 LRU 驅(qū)逐。

volatile-lfu -> 在過期 key 中使用近似 LFU 驅(qū)逐。

allkeys-lfu -> 在所有 key 中使用近似 LFU。

volatile-random -> 在設(shè)置了過期時間的 key 中隨機刪除一個。

allkeys-random -> 在所有的 key 中隨機刪除一個。

volatile-ttl -> 誰快過期就刪誰。

noeviction -> 不刪除任何 key,內(nèi)存滿了直接返回報錯。

maxmemory-samples

LRU, LFU and minimal TTL algorithms 不是精確的算法,是一個近似的算法(主要為了節(jié)省內(nèi)存)。

所以需要你自己權(quán)衡速度和精確度。默認(rèn)會抽取 5 個 key,選擇一個最近最少使用的 key 淘汰,你可以改變這個數(shù)量。

默認(rèn)的 5 可以提供不錯的結(jié)果。配置 10 會非常接近真實的 LRU 但是會耗費更多的 CPU,配置 3 會更快,但是就不那么精確了。

replica-ignore-maxmemory

從 Redis 5.0 開始,默認(rèn)情況下 slave 節(jié)點會忽略 maxmemory 配置,除非在故障轉(zhuǎn)移后或手動將其提升為 master。這意味著只有 master 才會執(zhí)行內(nèi)存淘汰策略,當(dāng) master 刪除 key 后會發(fā)送 DEL指令給 slave。

默認(rèn)配置replica-ignore-maxmemory yes。

active-expire-effort

我有兩種方式刪除過期數(shù)據(jù)。

后臺周期性選取部分?jǐn)?shù)據(jù)刪除。

惰性刪除,當(dāng)訪問請求到某個 key 的時候,發(fā)現(xiàn)該 key 已經(jīng)過期則刪除。

這個配置用于指定過期 key 滯留在內(nèi)存中的比例,默認(rèn)值是 1,表示最多只能有 10 % 的過期 key 駐留在內(nèi)存中,值設(shè)置的越小,那么一次淘汰周期內(nèi)需需要消耗的 CPU 將會更多,因為需要刪除更多的過期數(shù)據(jù)。

1.6 惰性釋放

MySQL:“ 可以使用非阻塞的方式刪除 bigkey 么?”

我提供了兩種刪除 key 的基本命令用于刪除數(shù)據(jù)。

DEL 指令:這是一個阻塞的刪除,執(zhí)行該指令會停止處理寫請求,使用同步的方式去回收 DEL 刪除的對象的內(nèi)存。如果這個 key 對應(yīng)的 value 是一個非常小的對象, DEL 執(zhí)行的時間非常短,時間復(fù)雜度為 O(1) 或者 O(log n)。如果 key 對應(yīng)的 value 非常大,比如集合對象的數(shù)據(jù)包含百萬個元素,服務(wù)器將阻塞很長時間(幾秒鐘)才能完成操作。

UNLINK(非阻塞刪除)、(異步刪除) FLUSHALL ASYNC/FLUSHDB ASYNC:后臺回收內(nèi)存,這些指令在常量級別時間內(nèi)執(zhí)行,會使用一個新的線程在后臺漸進的刪除并釋放內(nèi)存(Lazy Free 機制)。

lazyfree-lazy-eviction

由于 maxmemory 和 maxmemory-policy 策略配置,我會刪除一些數(shù)據(jù),防止內(nèi)存爆掉。使用lazyfree-lazy-eviction yes表示使用 lazy free 機制,該場景開啟 lazy free 可能會導(dǎo)致淘汰數(shù)據(jù)的內(nèi)存釋放不及時,出現(xiàn)內(nèi)存超限。

lazyfree-lazy-expire

對于設(shè)置了 TTL 的鍵,過期后刪除。如果想啟用 lazy free 機制刪除,則配置 lazyfree-lazy-eviction yes。

lazyfree-lazy-server-del

針對有些指令在處理已存在的鍵時,會帶有一個隱式的 DEL 鍵的操作。

如 rename 命令,當(dāng)目標(biāo)鍵已存在,我會先刪除目標(biāo)鍵,如果這些目標(biāo)鍵是一個 big key,那可能會出現(xiàn)阻塞刪除的性能問題。此參數(shù)設(shè)置就是解決這類問題,建議配置 lazyfree-lazy-server-del yes 開啟。

replica-lazy-flush

該配置針對 slave 進行全量數(shù)據(jù)同步,在加載 master 的 RDB 內(nèi)存快照文件之前,會先運行 flashall清理數(shù)據(jù)的時候是否采用異步 flush 機制。

推薦你使用 replica-lazy-flush yes配置,可減少全量同步耗時,從而減少 master 因輸出緩沖區(qū)暴漲引起的內(nèi)存增長。

lazyfree-lazy-user-del

意思是是否將 DEL 指令的默認(rèn)行為替換成 lazy free 機制刪除,效果就跟 UNLINK 一樣,只要配置成 lazyfree-lazy-user-del yes。

lazyfree-lazy-user-flush

FLUSHDB, FLUSHALL, SCRIPT FLUSH, FUNCTION FLUSH可以使用額外參數(shù) ASYNC|SYNC 決定使用同步還是異步操作,當(dāng)沒有指定這個可選項,可以通過 lazyfree-lazy-user-flush yes 表示使用異步刪除。

IO 多線程

大家知道我是單線程模型處理讀寫請求,但是有一些操作可以使用其他線程處理,比如 UNLINK,I/O 讀寫操作。

在 6.0 版本,我提供了 I/O 多線程處理 Socket 讀寫,利用 I/O 多線程可以提高客戶端 Socket 讀寫性能。

默認(rèn)配置是關(guān)閉的,我只建議當(dāng)你的機器至少是 4 核 CPU 或者更多的情況啟用,并且配置的線程數(shù)少于機器總 CPU 核數(shù),配置超過 8 個線程對提升沒什么幫助。

當(dāng)你的機器是四核 CPU,那可以嘗試配置使用 2~3 個 I/O 線程,如果是 8 核 CPU,一般只需要配置 6 個線程。

如下配置表示開啟 I/O 線程組,線程組的 I/O 線程數(shù)量為 3。

io-threads-do-readsyes
io-threads3

1.7 AOF 持久化

除了 RDB 內(nèi)存快照文件作為持久化手段以外,還能使用 AOF(Append only file) 實現(xiàn)持久化,AOF 是一種可選的持久化策略提供更好數(shù)據(jù)安全性。

默認(rèn)配置下,我最多只會丟失一秒的數(shù)據(jù),你甚至可以配置更高級別,最多只丟失一次 write 操作,但這樣會對損耗性能。

appendonly

appendonly yes 表示開啟 AOF 持久化,可以同時開啟 AOF 和 RDB 內(nèi)存快照持久化,如果開啟了 AOF ,我會先加載 AOF 用于恢復(fù)內(nèi)存數(shù)據(jù)。

appendfilename

指定 AOF 文件名稱,默認(rèn)名字是 appendonly.aof。為了方便,你可以配置 appenddirname 指定 AOF 文件存儲目錄。

appendfsync

調(diào)用操作系統(tǒng)的 fsync()函數(shù)告訴操作系統(tǒng)把輸出緩沖區(qū)的數(shù)據(jù)持久化到磁盤, AOF 文件刷寫的頻率有三種。

no:不去主動調(diào)用 fsync(),讓操作系統(tǒng)自己決定何時寫磁盤。

always:每次 write 操作之后都調(diào)用 fsync(),非常慢,但是數(shù)據(jù)安全性最高。

everysec:每秒調(diào)用一次 fsync(),一個折中的策略,最多丟失一秒的數(shù)據(jù)。

默認(rèn)配置是 appendfsync everysec,推薦大家這么設(shè)置,兼顧了速度和數(shù)據(jù)安全。

no-appendfsync-on-rewrite

當(dāng) appendfsync 的配置設(shè)置成 always或者 everysec ,現(xiàn)在有一個后臺 save 進程(可能是生成 RDB 內(nèi)存快照的 bgsave 進程,也有可能是 AOF rewrite 進程)正在進行大量的磁盤 I/O 操作,會造成調(diào)用 fsync()執(zhí)行太長,后續(xù)其他想要調(diào)用 fsync() 的進程就會阻塞。

為了緩解這個問題,可以使用以下配置 no-appendfsync-on-rewrite yes 表示當(dāng)已經(jīng)有 bgsave和bgrewriteaof 后臺進程在調(diào)用 fsync() 時,不再開啟新進程執(zhí)行 AOF 文件寫入。

這樣的話,就會出現(xiàn)當(dāng)前有子進程在做 bgsave 或者其他的磁盤操作時,我就無法繼續(xù)寫 AOF 文件,這意味著可能會丟失更多數(shù)據(jù)。

如果有延遲問題,請將此選項改為 yes。否則將其保留為 no。從持久化的角度來看,no是最安全的選擇。

AOF 重寫

為了防止 AOF 文件過大,antirez 大佬給我搞了個 AOF 重寫機制。

auto-aof-rewrite-percentage 100 表示當(dāng)前 AOF 文件大小超過上一次重寫的 AOF 文件大小的百分之多少(如果沒有執(zhí)行過 AOF 重寫,那就參照原始 AOF 文件大?。?,則執(zhí)行 AOF 文件重寫操作。

除了這個配置,你還要配置 auto-aof-rewrite-min-size 64mb 用于指定觸發(fā) AOF 重寫操作的文件大小。

如果該 AOF 文件大小小于該值,即使文件增長比例達到 100%,我也不會觸發(fā) AOF 重寫操作,這是為了防止 AOF 文件其實很小,但是滿足增長百分比時的多余 AOF 重寫操作。

如果配置為auto-aof-rewrite-percentage 0 ,表示禁用 AOF 重寫功能,建議大家開啟 AOF 重寫,防止文件過大。

aof-load-truncated

MySQL:如果 AOF 文件是損壞的,你還加載數(shù)據(jù)還原到內(nèi)存中么?

加載 AOF 文件把數(shù)據(jù)還原到內(nèi)存中,文件可能是損壞的,比如文件末尾是錯誤的。這種情況一般是由于宕機導(dǎo)致,尤其是使用 ext4 文件系統(tǒng)掛載時沒配置 data=ordered 選項。

在這種情況下,我可以直接報錯,或者盡可能的讀取可讀的 AOF 內(nèi)容。

如果配置成 aof-load-truncated yes,我依然會加載并讀取這個損壞的 AOF 文件,并記錄一個錯誤日志通知程序員。

配置成 aof-load-truncated no,我就會報錯并拒絕啟動服務(wù),你需要使用 redis-check-aof 工具修復(fù) AOF 文件,再啟動 Redis。如果修復(fù)后還是錯誤,我依然報錯并拒絕啟動。

aof-use-rdb-preamble

這就是大名鼎鼎的 RDB-AOF 混合持久化功能,配置成 aof-use-rdb-preamble yes(必須先開啟 AOF),AOF 重寫生成的文件將同時包含 RDB 格式的內(nèi)容和 AOF 格式內(nèi)容。

混合持久化是在 AOF 重寫完成的,開啟混合持久化后,fork 出的子進程先將內(nèi)存數(shù)據(jù)以 RDB 的方式寫入 AOF 文件,接著把 RDB 格式數(shù)據(jù)寫入 AOF 文件期間收到的增量命令從重寫緩沖區(qū)以 AOF 格式寫到文件中。

寫入完成后通知主進程更新統(tǒng)計信息,并把含有 RDB 格式和 AOF 格式的 AOF 文件替換舊的 AOF 文件。

這樣的好處是可以結(jié)合 RDB 和 AOF 的優(yōu)點,實現(xiàn)快速加載同時避免丟失過多數(shù)據(jù),缺點是 AOF 文件的 RDB 部分內(nèi)容不是 AOF 格式,可讀性差(都是程序解析讀取,哪個傻瓜程序員去讀這個呀),強烈推薦你使用這個來保證持久化。

aof-timestamp-enabled

我在 7.0 版本新增的特性,大體就是講 AOF 現(xiàn)在支持時間戳了,你可以做到基于時間點來恢復(fù)數(shù)據(jù)。

默認(rèn)是是 aof-timestamp-enabled no 表示關(guān)閉該特性,你可以按照實際需求選擇開啟。

1.7 Cluster 集群

Redis Cluster 集群相關(guān)配置,使用集群方式的你必須重視和知曉。別嘴上原理說的頭頭是道,而集群有哪些配置?如何配置讓集群快到飛起,實現(xiàn)真正的高可用卻一頭霧水,通過下面這些配置詳解也讓你對集群原理更加深刻。

cluster-enabled

普通的 Redis 實例是不能成為集群的一員,想要將該節(jié)點加入 Redis Cluster,需要設(shè)置 cluster-enabled yes。

cluster-config-file

cluster-config-file nodes-6379.conf 指定集群中的每個節(jié)點文件。

集群中的每個節(jié)點都有一個配置文件,這個文件并不是讓程序員編輯的,是我自己創(chuàng)建和更新的,每個節(jié)點都要使用不同的配置文件,一定要確保同一個集群中的不同節(jié)點使用的是不同的文件。

cluster-node-timeout

設(shè)置集群節(jié)點不可用的最大超時時間,節(jié)點失效檢測。集群中當(dāng)一個節(jié)點向另一個節(jié)點發(fā)送 PING 命令,但是目標(biāo)節(jié)點未在給定的時限內(nèi)返回 PING 命令的回復(fù)時,那么發(fā)送命令的節(jié)點會將目標(biāo)節(jié)點標(biāo)記為 PFAIL(possible failuer,可能已失效);

如果 master 節(jié)點超過這個時間還是無響應(yīng),則用它的從節(jié)點將啟動故障遷移,升級成主節(jié)點。

默認(rèn)配置是 cluster-node-timeout 15000,單位是毫秒數(shù)。

cluster-port

該端口是集群總線監(jiān)聽 TCP 連接的端口,默認(rèn)配置為 cluster-port 0,我就會把端口綁定為客戶端命令端口 + 10000(客戶端端口默認(rèn) 6379,所以綁定為 16379 作為集群總線端口)。每個 Redis Cluster 節(jié)點都需要開放兩個端口:

一個用于服務(wù)于客戶端的 TCP 端口,比如 6379.

另一個稱為集群總線端口,節(jié)點使用集群總線進行故障監(jiān)測、配置更新、故障轉(zhuǎn)移等。客戶端不要與集群總線端口通信,另外請確保在防火墻打開這兩個端口,否則 Redis 集群之間將無法通信

cluster-replica-validity-factor

該配置用于決定當(dāng) Redis Cluster 集群中,一個 master 宕機后,如何選擇一個 slave 節(jié)點完成故障轉(zhuǎn)移自動恢復(fù)(failover)。如果設(shè)置為 0 ,則不管 slave 與 master 之間斷開多久,都有資格成為 master。

下面提供了兩種方式來評估 slave 的數(shù)據(jù)是否太舊。

如果有多個 slave 可以 failover,他們之間會通過交換信息選出擁有擁有最大復(fù)制 offset 的 slave 節(jié)點。

每個 slave 節(jié)點計算上次與 master 節(jié)點交互的時間,這個交互包含最后一次 ping 操作、master 節(jié)點傳輸過來的寫指令、上次與 master 斷開的時間等。如果上次交互的時間過去很久,那么這個節(jié)點就不會發(fā)起 failover。

針對第二點,交互時間可以通過配置定義,如果 slave 與 master 上次交互的時間大于 (node-timeout * cluster-replica-validity-factor) + repl-ping-replica-period,該 slave 就不會發(fā)生 failover。

例如,``node-timeout = 30秒,cluster-replica-validity-factor=10,repl-ping-slave-period=10`秒, 表示 slave 節(jié)點與 master 節(jié)點上次交互時間已經(jīng)過去了 310 秒,那么 slave 節(jié)點就不會做 failover。

調(diào)大 cluster-replica-validity-factor 則允許存儲過舊數(shù)據(jù)的 slave 節(jié)點提升為 master,調(diào)小的話可能會導(dǎo)致沒有 slave 節(jié)點可以升為 master 節(jié)點。

考慮高可用,建議大家設(shè)置為 cluster-replica-validity-factor 0。

cluster-migration-barrier

沒有 slave 節(jié)點的 master 節(jié)點稱為孤兒 master 節(jié)點,這個配置就是用于防止出現(xiàn)孤兒 master。

當(dāng)某個 master 的 slave 節(jié)點宕機后,集群會從其他 master 中選出一個富余的 slave 節(jié)點遷移過來,確保每個 master 節(jié)點至少有一個 slave 節(jié)點,防止當(dāng)孤立 master 節(jié)點宕機時,沒有 slave 節(jié)點可以升為 master 導(dǎo)致集群不可用。

默認(rèn)配置為 cluster-migration-barrier 1,是一個遷移臨界值。

含義是:被遷移的 master 節(jié)點至少還有 1 個 slave 節(jié)點才能做遷移操作。比如 master A 節(jié)點有 2 個以上 slave 節(jié)點 ,當(dāng)集群出現(xiàn)孤兒 master B 節(jié)點時,A 節(jié)點富余的 slave 節(jié)點可以遷移到 master B 節(jié)點上。

生產(chǎn)環(huán)境建議維持默認(rèn)值,最大可能保證高可用,設(shè)置為非常大的值或者配置 cluster-allow-replica-migration no 禁用自動遷移功能。

cluster-allow-replica-migration 默認(rèn)配置為 yes,表示允許自動遷移。

cluster-require-full-coverage

默認(rèn)配置是 yes,表示為當(dāng) redis cluster 發(fā)現(xiàn)還有哈希槽沒有被分配時禁止查詢操作。

這就會導(dǎo)致集群部分宕機,整個集群就不可用了,當(dāng)所有哈希槽都有分配,集群會自動變?yōu)榭捎脿顟B(tài)。

如果你希望 cluster 的子集依然可用,配置成 cluster-require-full-coverage no。

cluster-replica-no-failover

當(dāng)配置成 yes,在 master 宕機時,slave 不會做故障轉(zhuǎn)移升為 master。

這個配置在多數(shù)據(jù)中心的情況下會很有用,你可能希望某個數(shù)據(jù)中心永遠不要升級為 master 節(jié)點,否則 master 節(jié)點就漂移到其他數(shù)據(jù)中心了,正常情況設(shè)置成 no。

cluster-allow-reads-when-down

默認(rèn)是 no,表示當(dāng)集群因主節(jié)點數(shù)量達不到最小值或者哈希槽沒有完全分配而被標(biāo)記為失效時,節(jié)點將停止所有客戶端請求。

設(shè)置成 yes,則允許集群失效的情況下依然可從節(jié)點中讀取數(shù)據(jù),保證了高可用。

cluster-allow-pubsubshard-when-down

配置成 yes,表示當(dāng)集群因主節(jié)點數(shù)量達不到最小值或者哈希槽沒有完全分配而被標(biāo)記為失效時,pub/sub 依然可以正常運行。

cluster-link-sendbuf-limit

設(shè)置每個集群總線連接的發(fā)送字節(jié)緩沖區(qū)的內(nèi)存使用限制,超過限制緩沖區(qū)將被清空(主要為了防止發(fā)送緩沖區(qū)發(fā)送給慢速連接時無限延長時間的問題)。

默認(rèn)禁用,建議最小設(shè)置 1gb,這樣默認(rèn)情況下集群連接緩沖區(qū)可以容納至少一條 pubsub 消息(client-query-buffer-limit 默認(rèn)是 1gb);

1.8 性能監(jiān)控

慢查詢?nèi)罩?/p>

慢查詢(Slow Log)日志是我用于記錄慢查詢執(zhí)行時間的日志系統(tǒng),只要查詢超過配置的時間,都會記錄。slowlog 只保存在內(nèi)存中,因此效率很高,大家不用擔(dān)心會影響到 Redis 的性能。

執(zhí)行時間不包括 I/O 操作的時間,比如與客戶端建立連接、發(fā)送回復(fù)等,只記錄執(zhí)行命令執(zhí)行階段所需要的時間。

你可以使用兩個參數(shù)配置慢查詢?nèi)罩鞠到y(tǒng)。

slowlog-log-slower-than:指定對執(zhí)行時間大于多少微秒(microsecond,1 秒 = 1,000,000 微秒)的查詢進行記錄,默認(rèn)是 10000 微妙,推薦你先執(zhí)行基線測試得到一個基準(zhǔn)時間,通常這個值可以設(shè)置為基線性能最大延遲的 3 倍。

slowlog-max-len:設(shè)定最多保存多少條慢查詢的日志,slowlog 本身是一個 FIFO 隊列,當(dāng)超過設(shè)定的最大值后,我會把最舊的一條日志刪除。默認(rèn)配置 128,如果設(shè)置太大會占用多大內(nèi)存。

延遲監(jiān)控

延遲監(jiān)控(LATENCY MONITOR)系統(tǒng)會在運行時抽樣部分命令來幫助你分析 Redis 卡頓的原因。

通過 LATENCY命令,可以打印一些視圖和報告,系統(tǒng)只會記錄大于等于指定值的命令。

默認(rèn)配置 latency-monitor-threshold 0,設(shè)置 0 表示關(guān)閉這個功能。沒有延遲問題,沒必要開啟開啟監(jiān)控,因為會對性能造成很大影響。

在運行過程中你懷疑有延遲性能問題,想要監(jiān)控的話可以使用 CONFIG SET latency-monitor-threshold 開啟,單位是毫秒。

1.9 高級設(shè)置

這部分配置主要圍繞以下幾個方面。

指定不同數(shù)據(jù)類型根據(jù)不同條數(shù)下使用不同的數(shù)據(jù)結(jié)構(gòu)存儲,合理配置能做到更快和更省內(nèi)存。

客戶端緩沖區(qū)相關(guān)配置。

漸進式 rehash 資源控制。

LFU 調(diào)優(yōu)。

RDB 內(nèi)存快照文件、AOF 文件同步策略。

Hashes(散列表)

在 Redis 7.0 版本散列表數(shù)據(jù)類型有兩種數(shù)據(jù)結(jié)構(gòu)保存數(shù)據(jù),分別為散列表和 listpack。當(dāng)數(shù)據(jù)量很小時,可以使用更高效的數(shù)據(jù)結(jié)構(gòu)存儲,從而達到在不影響性能的情況下節(jié)省內(nèi)存。

hash-max-listpack-entries 512:指定使用 listpack 存儲的最大條目數(shù)。

hash-max-listpack-value 64:listpack 中,條目 value 值最大字節(jié)數(shù),建議設(shè)置成 1024。

在 7.0 版本以前,使用的是 ziplist 數(shù)據(jù)結(jié)構(gòu),配置如下。

hash-max-ziplist-entries512
hash-max-ziplist-value64

Lists(列表)

Lists 也可以使用一種特殊方式進行編碼來節(jié)省大量內(nèi)存空間。在 Redis 7.0 之后,Lits 底層的數(shù)據(jù)結(jié)構(gòu)使用 linkedlist 或者 listpack 。

Redis 3.2 版本,List 內(nèi)部是通過 linkedlist 和 quicklist 實現(xiàn),quicklist 是一個雙向鏈表, quicklist 的每個節(jié)點都是一個 ziplist,從而實現(xiàn)節(jié)省內(nèi)存。

元素少時用 quicklist,元素多時用 linkedlist。listpack 的目的就是用于替代 ziplist 和 quicklist。listpack 也叫緊湊列表,它的特點就是用一塊連續(xù)的內(nèi)存空間來緊湊地保存數(shù)據(jù),同時為了節(jié)省內(nèi)存空間

list-max-ziplist-size

7.0 版本之前l(fā)ist-max-ziplist-size 用于配置 quicklist 中的每個節(jié)點的 ziplist 的大小。當(dāng)這個值配置為正數(shù)時表示 quicklist 每個節(jié)點的 ziplist 最多可存儲元素數(shù)量,超過該值就會使用 linkedlist 存儲。

當(dāng) list-max-ziplist-size 為負(fù)數(shù)時表示限制每個 quicklistNode 的 ziplist 的內(nèi)存大小,超過這個大小就會使用 linkedlist 存儲數(shù)據(jù),每個值有以下含義:

-5:每個 quicklist 節(jié)點上的 ziplist 大小最大 64 kb <--- 正常環(huán)境不推薦

-4:每個 quicklist 節(jié)點上的 ziplist 大小最大 32 kb <--- 不推薦

-3:每個 quicklist 節(jié)點上的 ziplist 大小最大 16 kb <--- 可能不推薦

-2:每個 quicklist 節(jié)點上的 ziplist 大小最大 8 kb <--- 不錯

-1:每個 quicklist 節(jié)點上的 ziplist 大小最大 4kb <--- 不錯

默認(rèn)值為 -2,也是官方最推薦的值,當(dāng)然你可以根據(jù)自己的實際情況進行修改。

list-max-listpack-size

7.0 之后,配置修改為list-max-listpack-size -2則表示限制每個 listpack 大小,不再贅述。

list-compress-depth

壓縮深度配置,用來配置壓縮 Lists 的,當(dāng) Lists 底層使用 linkedlist 也是可以壓縮的,默認(rèn)是 list-compress-depth 0表示不壓縮。一般情況下,Lists 的兩端訪問的頻率高一些,所以你可以考慮把中間的數(shù)據(jù)進行壓縮。

不同參數(shù)值的含義如下。

0,關(guān)閉壓縮,默認(rèn)值。

1,兩端各有一個節(jié)點不壓縮。

2,兩端各有兩個節(jié)點不壓縮。

N,依次類推,兩端各有 N 個節(jié)點不壓縮。

需要注意的是,head 和 tail 節(jié)點永遠都不會被壓縮。

Sets(無序集合)

Sets 底層的數(shù)據(jù)結(jié)構(gòu)可以是 intset(整形數(shù)組)和 Hashtable(散列表),intset 你可以理解成數(shù)組,Hashtable 就是普通的散列表(key 存的是 Sets 的值,value 為 null)。有沒有覺得 Sets 使用散列表存儲是意想不到的事情?

set-max-intset-entries

當(dāng)集合的元素都是 64 位以內(nèi)的十進制整數(shù)時且長度不超過 set-max-intset-entries 配置的值(默認(rèn) 512),Sets 的底層會使用 intset 存儲節(jié)省內(nèi)存。添加的元素大于 set-max-intset-entries配置的值,底層實現(xiàn)由 intset 轉(zhuǎn)成散列表存儲。

SortedSets(有序集合)

在 Redis 7.0 版本之前,有序集合底層的數(shù)據(jù)結(jié)構(gòu)有 ziplist 和 skipist,之后使用 listpack 代替了 ziplist。

7.0 版本之前,當(dāng)集合元素個數(shù)小于 zset-max-ziplist-entries配置,同時且每個元素的值大小都小于zset-max-ziplist-value配置(默認(rèn) 64 字節(jié),推薦調(diào)大到 128)時,我將使用 ziplist 數(shù)據(jù)結(jié)構(gòu)存儲數(shù)據(jù),有效減少內(nèi)存使用。與此類似,7.0 版本之后我將使用 listpack 存儲。

##7.0之前的配置
zset-max-ziplist-entries128
zset-max-ziplist-value64
##7.0之后的配置
zset-max-listpack-entries128
zset-max-listpack-value64

HyperLogLog

HyperLogLog 是一種高級數(shù)據(jù)結(jié)構(gòu),統(tǒng)計基數(shù)的利器。HyperLogLog 的存儲結(jié)構(gòu)分為密集存儲結(jié)構(gòu)和稀疏存儲結(jié)構(gòu)兩種,默認(rèn)為稀疏存儲結(jié)構(gòu),而我們常說的占用 12K 內(nèi)存的則是密集存儲結(jié)構(gòu),稀疏結(jié)構(gòu)占用的內(nèi)存會更小。

hll-sparse-max-bytes

默認(rèn)配置是 hll-sparse-max-bytes 3000,單位是 Byte,這個配置用于決定存儲數(shù)據(jù)使用稀疏數(shù)據(jù)結(jié)構(gòu)(sparse)還是稠密數(shù)據(jù)結(jié)構(gòu)(dense)。

如果 HyperLogLog 存儲內(nèi)容大小大于 hll-sparse-max-bytes 配置的值將會轉(zhuǎn)換成稠密的數(shù)據(jù)結(jié)構(gòu)(dense)。

推薦的值是 0~3000,這樣PFADD命令的并不會慢多少,還能節(jié)省空間。如果內(nèi)存空間相對 cpu 資源更缺乏,可以將這個值提升到 10000。

Streams(流)

Stream 是 Redis 5.0 版本新增的數(shù)據(jù)類型。Redis Streams 是一些由基數(shù)樹(Radix Tree)連接在一起的節(jié)點經(jīng)過 delta 壓縮后構(gòu)成的,這些節(jié)點與 Stream 中的消息條目(Stream Entry)并非一一對應(yīng),而是每個節(jié)點中都存儲著若干 Stream 條目,因此這些節(jié)點也被稱為宏節(jié)點或大節(jié)點。

stream-node-max-bytes 4096

單位為 Byte,默認(rèn)值 4096,用于設(shè)定每個宏節(jié)點占用的內(nèi)存上限為 4096,0 表示無限制。

stream-node-max-entries 100

用于設(shè)定每個宏節(jié)點存儲元素個數(shù)。默認(rèn)值 100,0 表示無限制。當(dāng)一個宏節(jié)點存儲的 Stream 條目到達上限,新添加的條目會存儲到新的宏節(jié)點中。

rehash

我采用的是漸進式 rehash,這是一個惰性策略,不會一次性把所有數(shù)據(jù)遷移完,而是分散到每次請求中,這樣做的目的是防止數(shù)據(jù)太多要遷移阻塞主線程。

在漸進式 rehash 的同時,推薦你使用 activerehashing yes開啟定時輔助執(zhí)行 rehash,默認(rèn)情況下每一秒執(zhí)行 10 次 rehash 加快遷移速度,盡可能釋放內(nèi)存。

關(guān)閉該功能的話,如果這些 key 不再活躍不被被訪問到,rehash 操作可能不再有機會完成,會導(dǎo)致散列表占用更多內(nèi)存。

客戶端輸出緩沖區(qū)限制

這三個配置是用來強制斷開客戶端連接的,當(dāng)客戶端沒有及時把緩沖區(qū)的數(shù)據(jù)讀取完畢,我會認(rèn)為這個客戶端可能完蛋了(一個常見的原因是 Pub/Sub 客戶端處理發(fā)布者的消息不夠快),于是斷開連接。

一共分為三種不同類型的客戶端,分別設(shè)置不同的限制。

normal(普通),普通客戶端,包括 MONITOR 客戶端。

replica(副本客戶端),slave 節(jié)點的客戶端。

pubsub(發(fā)布訂閱客戶端),至少訂閱了一個 pubsub 頻道或者模式的客戶端。

client-output-buffer-limit的語法如下。

client-output-buffer-limit

表示不同類型的客戶端,當(dāng)客戶端的緩沖區(qū)內(nèi)容大小達到后我就立馬斷開與這個客戶端的連接,或者達到并持續(xù)了秒后斷開。

默認(rèn)情況下,普通客戶端不會限制,只有后異步的客戶端才可能發(fā)送發(fā)送請求的速度比讀取響應(yīng)速度快的問題。比如 pubsub 和 replica 客戶端會有默認(rèn)的限制。

soft limit 或者 hard limit 設(shè)置為 0,表示不啟用此限制。默認(rèn)配置如下。

client-output-buffer-limitnormal000
client-output-buffer-limitreplica256mb64mb60
client-output-buffer-limitpubsub32mb8mb60

client-query-buffer-limit

每個客戶端都有一個 query buffer(查詢緩沖區(qū)或輸入緩沖區(qū)),用于保存客戶端發(fā)送命令,Redis Server 從 query buffer 獲取命令并執(zhí)行。

如果程序的 Key 設(shè)計不合理,客戶端使用大量的 query buffer,導(dǎo)致 Redis 很容易達到 maxmeory 限制。最好限制在一個固定的大小來避免占用過大內(nèi)存的問題。

如果你需要發(fā)送巨大的 multi/exec 請求的時候,那可以適當(dāng)修改這個值以滿足你的特殊需求。

默認(rèn)配置為 client-query-buffer-limit 1gb。

maxmemory-clients

這是 7.0 版本特性,每個與服務(wù)端建立連接的客戶端都會占用內(nèi)存(查詢緩沖區(qū)、輸出緩沖區(qū)和其他緩沖區(qū)),大量的客戶端可能會占用過大內(nèi)存導(dǎo)致 OOM,為了避免這個情況,我提供了一種叫做(Client Eviction)客戶端驅(qū)逐機制用于限制內(nèi)存占用。

配置方式有兩種。

具體內(nèi)存值, maxmemory-clients 1g來限制所有客戶端占用內(nèi)存總和。

百分比,maxmemory-clients 5% 表示客戶端總和內(nèi)存占用最多為 Redis 最大內(nèi)存配置的 5%。

默認(rèn)配置是 maxmemory-clients 0 表示無限制。

MySQL:“達到最大內(nèi)存限制,你會把所有客戶端連接都釋放么?”

不是的,一旦達到限制,我會優(yōu)先嘗試斷開使用內(nèi)存最多的客戶端。

proto-max-bulk-len

批量請求(單個字符串的元素)內(nèi)存大小限制,默認(rèn)是 proto-max-bulk-len 512mb,你可以修改限制,但必須大于等于 1mb。

hz

我會在后臺調(diào)用一些函數(shù)來執(zhí)行很多后臺任務(wù),比如關(guān)閉超時連接,清理不再被請求的過期的 key,rehash、執(zhí)行 RDB 內(nèi)存快照和 AOF 持久化等。

并不是所有的后臺任務(wù)都需要使用相同的頻率來執(zhí)行,你可以使用 hz 參數(shù)來決定執(zhí)行這些任務(wù)的頻率。

默認(rèn)配置是 hz 10,表示每秒執(zhí)行 10 次,更大的值會消耗更多的 CPU 來處理后臺任務(wù),帶來的效果就是更快的清理過期 key,清理的超時連接更精確。

這個值的范圍是 1~500,不過并不推薦設(shè)置大于 100 的值。大家使用默認(rèn)值就好,或者最多調(diào)高到 100。

dynamic-hz

默認(rèn)配置是 dynamic-hz yes,啟用 dynamic-hz 后,將啟用自適應(yīng) HZ 值的能力。hz 的配置值將會作為基線,Redis 服務(wù)中的實際 hz 值會在基線值的基礎(chǔ)上根據(jù)已連接到 Redis 的客戶端數(shù)量自動調(diào)整,連接的客戶端越多,實際 hz 值越高,Redis 執(zhí)行定期任務(wù)的頻率就越高。

aof-rewrite-incremental-fsync

當(dāng)子進程進行 AOF 重寫時,如果配置成 aof-rewrite-incremental-fsync yes,每生成 4 MB 數(shù)據(jù)就執(zhí)行一次 fsync操作,分批提交到硬盤來避免高延遲峰值,推薦開啟。

rdb-save-incremental-fsync

當(dāng)我在保存 RDB 內(nèi)存快照文件時,如果配置成 db-save-incremental-fsync yes,每生成 4MB 文件就執(zhí)行一次 fsync操作,分批提交到硬盤來避免高延遲峰值,推薦開啟。

LFU 調(diào)優(yōu)

這個配置生效的前提是內(nèi)存淘汰策略設(shè)置的是 volatile-lfu或allkeys-lfu。

lfu-log-factor 用于調(diào)整 Logistic Counter 的增長速度,lfu-log-factor 值越大,Logistic Counter 增長越慢。默認(rèn)配置 10。

以下是表格是官方不同 factor 配置下,計數(shù)器的改變頻率。注意:表格是通過如下命令獲得的:redis-benchmark -n 1000000 incr foo redis-cli object freq foo。

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

lfu-decay-time 用于調(diào)整 Logistic Counter 的衰減速度,它是一個以分鐘為單位的數(shù)值,默認(rèn)值為 1;lfu-decay-time 值越大,衰減越慢。

1.9 在線內(nèi)存碎片整理

MySQL:“什么是在線內(nèi)存碎片整理?”

Active (online) defragmentation 在線內(nèi)存碎片整理指的是自動壓縮內(nèi)存分配器分配和 Redis 頻繁做更新操作、大量過期數(shù)據(jù)刪除,釋放的空間(不夠連續(xù))無法得到復(fù)用的內(nèi)存空間。

通常來說當(dāng)碎片化達到一定程度(查看下面的配置)Redis 會使用 Jemalloc 的特性創(chuàng)建連續(xù)的內(nèi)存空間, 并在此內(nèi)存空間對現(xiàn)有的值進行拷貝,拷貝完成后會釋放掉舊的數(shù)據(jù)。這個過程會對所有的導(dǎo)致碎片化的 key 以增量的形式進行。

需要注意的是

這個功能默認(rèn)是關(guān)閉的,并且只有在編譯 Redis 時使用我們代碼中的 Jemalloc 版本才生效。(這是 Linux 下的默認(rèn)行為)。

在實際使用中,建議是在 Redis 服務(wù)出現(xiàn)較多的內(nèi)存碎片時啟用(內(nèi)存碎片率大于 1.5),正常情況下盡量保持禁用狀態(tài)。

如果你需要試驗這項特性,可以通過命令 CONFIG SET activefrag yes來啟用。

清理的條件

activefrag yes:內(nèi)存碎片整理總開關(guān),默認(rèn)為禁用狀態(tài) no。

active-defrag-ignore-bytes 200mb:內(nèi)存碎片占用的內(nèi)存達到 200MB。

active-defrag-threshold-lower 20:內(nèi)存碎片的空間占比超過系統(tǒng)分配給 Redis 空間的 20% 。

在同時滿足上面三項配置時,內(nèi)存碎片自動整理功能才會啟用。

CPU 資源占用

MySQL:如何避免自動內(nèi)存碎片整理對性能造成影響?

清理的條件有了,還需要分配清理碎片占用的 CPU 資源,保證既能正常清理碎片,又能避免對 Redis 處理請求的性能影響。

active-defrag-cycle-min 5:自動清理過程中,占用 CPU 時間的比例不低于 5%,從而保證能正常展開清理任務(wù)。

active-defrag-cycle-max 20:自動清理過程占用的 CPU 時間比例不能高于 20%,超過的話就立刻停止清理,避免對 Redis 的阻塞,造成高延遲。

整理力度

active-defrag-max-scan-fields 1000:碎片整理掃描到set/hash/zset/list 時,僅當(dāng) set/hash/zset/list的長度小于此閥值時,才會將此鍵值對加入碎片整理,大于這個值的鍵值對會放在一個列表中延遲處理。

active-defrag-threshold-upper 100:內(nèi)存碎片空間占操作系統(tǒng)分配給 Redis 的總空間比例達此閾值(默認(rèn) 100%),我會盡最大努力整理碎片。建議你調(diào)整為 80。

jemalloc-bg-thread

默認(rèn)配置為 jemalloc-bg-thread yes,表示啟用清除臟頁后臺線程。

綁定 CPU

你可以將 Redis 的不同線程和進程綁定到特定的 CPU,減少上下文切換,提高 CPU L1、L2 Cache 命中率,實現(xiàn)最大化的性能。

你可以通過修改配置文件或者taskset命令綁定。

可分為三個模塊。

主線程和 I/O 線程:負(fù)責(zé)命令讀取、解析、結(jié)果返回。命令執(zhí)行由主線程完成。

bio 線程:負(fù)責(zé)執(zhí)行耗時的異步任務(wù),如 close fd、AOF fsync 等。

后臺進程:fork 子進程(RDB bgsave、AOF rewrite bgrewriteaof)來執(zhí)行耗時的命令。

Redis 支持分別配置上述模塊的 CPU 親合度,默認(rèn)情況是關(guān)閉的。

server_cpulist 0-7:2,I/O 線程(包含主線程)相關(guān)操作綁定到 CPU 0、2、4、6。

bio_cpulist 1,3,bio 線程相關(guān)的操作綁定到 CPU 1、3。

aof_rewrite_cpulist,aof rewrite 后臺進程綁定到 CPU 8、9、10、11。

bgsave_cpulist 1,10-11,bgsave 后臺進程綁定到 CPU 1、10、11。

注意事項

Linux 下,使用 「numactl --hardware」 查看硬件布局,確保支持并開啟 NUMA。

線程要盡可能分布在 不同的 CPU,相同的 node,設(shè)置 CPU 親和度才有效,否則會造成頻繁上下文切換。

你要熟悉 CPU 架構(gòu),做好充分的測試。否則可能適得其反,導(dǎo)致 Redis 性能下降。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 過濾器
    +關(guān)注

    關(guān)注

    1

    文章

    419

    瀏覽量

    19382
  • MYSQL數(shù)據(jù)庫
    +關(guān)注

    關(guān)注

    0

    文章

    95

    瀏覽量

    9347
  • TCP通信
    +關(guān)注

    關(guān)注

    0

    文章

    146

    瀏覽量

    4184
  • CRC效驗
    +關(guān)注

    關(guān)注

    0

    文章

    30

    瀏覽量

    1089
  • Redis
    +關(guān)注

    關(guān)注

    0

    文章

    368

    瀏覽量

    10780

原文標(biāo)題:redis.conf 7.0 配置和原理全解

文章出處:【微信號:OSC開源社區(qū),微信公眾號:OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Redis Stream應(yīng)用案例

    摘要: Redis Stream Redis最新的大版本5.0已經(jīng)RC1了,其中最重要的Feature莫過于Redis Stream了,關(guān)于Redis Stream的基本使用介紹和設(shè)計
    發(fā)表于 06-26 17:15

    redis集群環(huán)境安裝及配置

    redis集群主從配置
    發(fā)表于 03-08 09:59

    基于linux的安裝和配置redis

    linux(centos)下安裝、配置redis
    發(fā)表于 04-11 15:28

    阿里云ECS的redis配置步驟

    阿里云ECS配置redis
    發(fā)表于 10-28 08:28

    Mac上redis怎么安裝配置?

    Mac上redis基本安裝配置及問題
    發(fā)表于 05-01 06:18

    【廣東龍芯2K500先鋒板試用體驗】+試用3 實時內(nèi)存數(shù)據(jù)庫

    resis-7.0.7目錄下的 redis.conf 文件復(fù)制到剛才創(chuàng)建的目錄中。打開 redis.conf 配置文件,注意修改如下幾項:#修改監(jiān)聽ipbind0.0.0.0 -::*#修改dir ./為 dir
    發(fā)表于 01-13 13:43

    【愛芯派 Pro 開發(fā)板試用體驗】Redis源碼編譯和基準(zhǔn)測試

    /transparent_hugepage/enabled 設(shè)置完成后,重啟,再次檢測: 全部OK了。 3.3 啟動redis-server 使用redis目錄下的配置文件,啟動redis
    發(fā)表于 12-10 22:18

    Lilo.conf (LILO 配置文件)手冊

    LILO.CONF(5) 名稱 lilo.conf-lilo的配置文件。 描述 本文件,缺省位置為etc/lilo.conf,由引導(dǎo)裝入程序的安裝程序 LILO 讀取。 其表現(xiàn)可能如下
    發(fā)表于 11-07 10:21 ?0次下載

    redis緩存滿了怎么辦?

    只有在 Redis 的運行內(nèi)存達到了某個閥值,才會觸發(fā)內(nèi)存淘汰機制,這個閥值就是我們設(shè)置的最大運行內(nèi)存,此值在 Redis配置文件中可以找到,配置項為 maxmemory。
    發(fā)表于 08-21 10:42 ?206次閱讀
    <b class='flag-5'>redis</b>緩存滿了怎么辦?

    如何用Springboot整合Redis

    文件 mkdir -p /mydata/ redis/conftouch /mydata/ redis /conf/ redis.conf 1.3 啟動
    的頭像 發(fā)表于 10-08 14:56 ?487次閱讀
    如何用Springboot整合<b class='flag-5'>Redis</b>

    Redis持久化RDB方式介紹

    Redis會自動將內(nèi)存中的數(shù)據(jù)進行快照并持久化到硬盤。 觸發(fā)快照的時機 符合自定義配置的快照規(guī)則 redis.conf 執(zhí)行 save 或者 bgsave 命令 執(zhí)行 flushall 命令 第一次執(zhí)行
    的頭像 發(fā)表于 10-09 14:56 ?429次閱讀
    <b class='flag-5'>Redis</b>持久化RDB方式介紹

    Windows Docker部署Redis的流程

    由于 Docker 部署 Redis 后,Redis 容器中默認(rèn)是沒有 redis.conf 配置文件的,需要自己手動掛在進去。
    的頭像 發(fā)表于 11-27 10:02 ?725次閱讀
    Windows Docker部署<b class='flag-5'>Redis</b>的流程

    Java redis鎖怎么實現(xiàn)

    在Java中實現(xiàn)Redis鎖涉及到以下幾個方面:Redis的安裝配置、Redis連接池的使用、Redis數(shù)據(jù)結(jié)構(gòu)的選擇、實現(xiàn)分布式鎖的幾種方
    的頭像 發(fā)表于 12-04 10:47 ?910次閱讀

    redis連接數(shù)配置多少合適

    Redis 是一款高性能的內(nèi)存數(shù)據(jù)庫,廣泛應(yīng)用于緩存、消息隊列、會話存儲等場景。在配置 Redis 連接數(shù)時,需要根據(jù)實際情況綜合考慮一系列因素,如服務(wù)器硬件規(guī)格、業(yè)務(wù)負(fù)載、并發(fā)訪問量、數(shù)據(jù)模型等
    的頭像 發(fā)表于 12-04 11:31 ?1161次閱讀

    云容器redis持久化配置

    丟失。 Redis提供了不同的持久化機制,可以根據(jù)需要進行配置。本文將詳細介紹云容器中Redis的持久化配置及其相關(guān)配置項。 一、
    的頭像 發(fā)表于 12-05 10:07 ?418次閱讀