Redis 突然變慢了如何排查并解決响逢?

Redis 通常是我們業(yè)務(wù)系統(tǒng)中一個(gè)重要的組件棍厂,比如:緩存末誓、賬號(hào)登錄信息、排行榜等书蚪。

一旦 Redis 請(qǐng)求延遲增加喇澡,可能就會(huì)導(dǎo)致業(yè)務(wù)系統(tǒng)“雪崩”。

我在單身紅娘婚戀類型互聯(lián)網(wǎng)公司工作殊校,在雙十一推出下單就送女朋友的活動(dòng)晴玖。

誰曾想,凌晨 12 點(diǎn)之后为流,用戶量暴增呕屎,出現(xiàn)了一個(gè)技術(shù)故障,用戶無法下單敬察,當(dāng)時(shí)老大火冒三丈秀睛!

經(jīng)過查找發(fā)現(xiàn)Redis。

獲取不到連接資源莲祸,并且集群中的單臺(tái) Redis 連接量很高蹂安。

大量的流量沒了 Redis 的緩存響應(yīng),直接打到了 MySQL虫给,最后數(shù)據(jù)庫也宕機(jī)了……

于是各種更改最大連接數(shù)藤抡、連接等待數(shù),雖然報(bào)錯(cuò)信息頻率有所緩解抹估,但還是持續(xù)報(bào)錯(cuò)缠黍。

后來經(jīng)過線下測(cè)試,發(fā)現(xiàn)存放Redis字符數(shù)據(jù)很大药蜻,平均 1s 返回?cái)?shù)據(jù)瓷式。

可以發(fā)現(xiàn),一旦 Redis 延遲過高语泽,會(huì)引發(fā)各種問題贸典。

Redis 性能出問題了么?

最大延遲是客戶端發(fā)出命令到客戶端收到命令的響應(yīng)的時(shí)間踱卵,正常情況下 Redis 處理的時(shí)間極短廊驼,在微秒級(jí)別。

當(dāng) Redis 出現(xiàn)性能波動(dòng)的時(shí)候惋砂,比如達(dá)到幾秒到十幾秒妒挎,這個(gè)很明顯我們可以認(rèn)定 Redis 性能變慢了。

有的硬件配置比較高西饵,當(dāng)延遲 0.6ms酝掩,我們可能就認(rèn)定變慢了。硬件比較差的可能 3 ms 我們才認(rèn)為出現(xiàn)問題眷柔。

那我們?cè)撊绾味x Redis 真的變慢了呢期虾?

所以原朝,我們需要對(duì)當(dāng)前環(huán)境的 Redis 基線性能做測(cè)量,也就是在一個(gè)系統(tǒng)在低壓力镶苞、無干擾情況下的基本性能喳坠。

當(dāng)你發(fā)現(xiàn) Redis 運(yùn)行時(shí)時(shí)的延遲是基線性能的 2 倍以上,就可以判定 Redis 性能變慢了宾尚。

延遲基線測(cè)量

redis-cli 命令提供了–intrinsic-latency 選項(xiàng)丙笋,用來監(jiān)測(cè)和統(tǒng)計(jì)測(cè)試期間內(nèi)的最大延遲(以毫秒為單位),這個(gè)延遲可以作為 Redis 的基線性能煌贴。

redis-cli --latency -h `host` -p `port`

比如執(zhí)行如下指令:

redis-cli --intrinsic-latency 100
Max latency so far: 4 microseconds.
Max latency so far: 18 microseconds.
Max latency so far: 41 microseconds.
Max latency so far: 57 microseconds.
Max latency so far: 78 microseconds.
Max latency so far: 170 microseconds.
Max latency so far: 342 microseconds.
Max latency so far: 3079 microseconds.

45026981 total runs (avg latency: 2.2209 microseconds / 2220.89 nanoseconds per run).
Worst run took 1386x longer than the average latency.

注意:參數(shù)100是測(cè)試將執(zhí)行的秒數(shù)御板。我們運(yùn)行測(cè)試的時(shí)間越長,我們就越有可能發(fā)現(xiàn)延遲峰值牛郑。

通常運(yùn)行 100 秒通常是合適的怠肋,足以發(fā)現(xiàn)延遲問題了,當(dāng)然我們可以選擇不同時(shí)間運(yùn)行幾次淹朋,避免誤差笙各。

運(yùn)行的最大延遲是 3079 微秒,所以基線性能是 3079 (3 毫秒)微秒础芍。

需要注意的是杈抢,我們要在 Redis 的服務(wù)端運(yùn)行,而不是客戶端仑性。這樣惶楼,可以避免網(wǎng)絡(luò)對(duì)基線性能的影響

可以通過 -h host -p port 來連接服務(wù)端诊杆,如果想監(jiān)測(cè)網(wǎng)絡(luò)對(duì) Redis 的性能影響歼捐,可以使用 Iperf 測(cè)量客戶端到服務(wù)端的網(wǎng)絡(luò)延遲。

如果網(wǎng)絡(luò)延遲幾百毫秒晨汹,說明網(wǎng)絡(luò)可能有其他大流量的程序在運(yùn)行導(dǎo)致網(wǎng)絡(luò)擁塞豹储,需要找運(yùn)維協(xié)調(diào)網(wǎng)絡(luò)的流量分配。

慢指令監(jiān)控

如何判斷是否是慢指令呢淘这?

看操作復(fù)雜度是否是O(N)剥扣。官方文檔對(duì)每個(gè)命令的復(fù)雜度都有介紹,盡可能使用O(1) 和 O(log N)命令铝穷。

涉及到集合操作的復(fù)雜度一般為O(N)朦乏,比如集合全量查詢HGETALL、SMEMBERS氧骤,以及集合的聚合操作:SORT、LREM吃引、 SUNION等筹陵。

有監(jiān)控?cái)?shù)據(jù)可以觀測(cè)呢刽锤?代碼不是我寫的,不知道有沒有人用了慢指令朦佩。

有兩種方式可以排查到:

  • 使用 Redis 慢日志功能查出慢命令并思;
  • latency-monitor(延遲監(jiān)控)工具。

此外语稠,可以使用自己(top宋彼、htop、prstat 等)快速檢查 Redis 主進(jìn)程的 CPU 消耗仙畦。如果 CPU 使用率很高而流量不高输涕,通常表明使用了慢速命令。

慢日志功能

Redis 中的 slowlog 命令可以讓我們快速定位到那些超出指定執(zhí)行時(shí)間的慢命令慨畸,默認(rèn)情況下命令若是執(zhí)行時(shí)間超過 10ms 就會(huì)被記錄到日志莱坎。

slowlog 只會(huì)記錄其命令執(zhí)行的時(shí)間,不包含 io 往返操作寸士,也不記錄單由網(wǎng)絡(luò)延遲引起的響應(yīng)慢檐什。

我們可以根據(jù)基線性能來自定義慢命令的標(biāo)準(zhǔn)(配置成基線性能最大延遲的 2 倍),調(diào)整觸發(fā)記錄慢命令的閾值弱卡。

可以在 redis-cli 中輸入以下命令配置記錄 6 毫秒以上的指令:

redis-cli CONFIG SET slowlog-log-slower-than 6000

也可以在 Redis.config 配置文件中設(shè)置乃正,以微秒為單位。

想要查看所有執(zhí)行時(shí)間比較慢的命令婶博,可以通過使用 Redis-cli 工具瓮具,輸入 slowlog get 命令查看,返回結(jié)果的第三個(gè)字段以微秒位單位顯示命令的執(zhí)行時(shí)間凡蜻。

假如只需要查看最后 2 個(gè)慢命令搭综,輸入 slowlog get 2 即可。

示例:獲取最近2個(gè)慢查詢命令
127.0.0.1:6381> SLOWLOG get 2
1) 1) (integer) 6
   2) (integer) 1458734263
   3) (integer) 74372
   4) 1) "hgetall"
      2) "max.dsp.blacklist"
2) 1) (integer) 5
   2) (integer) 1458734258
   3) (integer) 5411075
   4) 1) "keys"
      2) "max.dsp.blacklist"

以第一個(gè) HGET 命令為例分析划栓,每個(gè) slowlog 實(shí)體共 4 個(gè)字段:

  • 字段 1:1 個(gè)整數(shù)兑巾,表示這個(gè) slowlog 出現(xiàn)的序號(hào),server 啟動(dòng)后遞增忠荞,當(dāng)前為 6蒋歌。
  • 字段 2:表示查詢執(zhí)行時(shí)的 Unix 時(shí)間戳。
  • 字段 3:表示查詢執(zhí)行微秒數(shù),當(dāng)前是 74372 微秒,約 74ms委煤。
  • 字段 4: 表示查詢的命令和參數(shù),如果參數(shù)很多或很大,只會(huì)顯示部分參數(shù)個(gè)數(shù)堂油。當(dāng)前命令是hgetall max.dsp.blacklist

Latency Monitoring

Redis 在 2.8.13 版本引入了 Latency Monitoring 功能碧绞,用于以秒為粒度監(jiān)控各種事件的發(fā)生頻率府框。

啟用延遲監(jiān)視器的第一步是設(shè)置延遲閾值(單位毫秒)。只有超過該閾值的時(shí)間才會(huì)被記錄讥邻,比如我們根據(jù)基線性能(3ms)的 3 倍設(shè)置閾值為 9 ms迫靖。

可以用 redis-cli 設(shè)置也可以在 Redis.config 中設(shè)置院峡;

CONFIG SET latency-monitor-threshold 9

工具記錄的相關(guān)事件的詳情可查看官方文檔:https://redis.io/topics/latency-monitor

如獲取最近的 latency

127.0.0.1:6379> debug sleep 2
OK
(2.00s)
127.0.0.1:6379> latency latest
1) 1) "command"
   2) (integer) 1645330616
   3) (integer) 2003
   4) (integer) 2003
  1. 事件的名稱;
  2. 事件發(fā)生的最新延遲的 Unix 時(shí)間戳系宜;
  3. 毫秒為單位的時(shí)間延遲照激;
  4. 該事件的最大延遲。

如何解決 Redis 變慢盹牧?

Redis 的數(shù)據(jù)讀寫由單線程執(zhí)行俩垃,如果主線程執(zhí)行的操作時(shí)間太長,就會(huì)導(dǎo)致主線程阻塞汰寓。

一起分析下都有哪些操作會(huì)阻塞主線程口柳,我們又該如何解決?

網(wǎng)絡(luò)通信導(dǎo)致的延遲

客戶端使用 TCP/IP 連接或 Unix 域連接連接到 Redis踩寇。1 Gbit/s 網(wǎng)絡(luò)的典型延遲約為 200 us啄清。

redis 客戶端執(zhí)行一條命令分 4 個(gè)過程:

發(fā)送命令-〉 命令排隊(duì) -〉 命令執(zhí)行-〉 返回結(jié)果

這個(gè)過程稱為 Round trip time(簡稱 RTT, 往返時(shí)間),mget mset 有效節(jié)約了 RTT俺孙,但大部分命令(如 hgetall辣卒,并沒有 mhgetall)不支持批量操作,需要消耗 N 次 RTT 睛榄,這個(gè)時(shí)候需要 pipeline 來解決這個(gè)問題荣茫。

Redis pipeline 將多個(gè)命令連接在一起來減少網(wǎng)絡(luò)響應(yīng)往返次數(shù)。

慢指令導(dǎo)致的延遲

根據(jù)上文的慢指令監(jiān)控查詢文檔场靴,查詢到慢查詢指令啡莉。可以通過以下兩種方式解決:

  • 比如在 Cluster 集群中旨剥,將聚合運(yùn)算等 O(N) 操作運(yùn)行在 slave 上咧欣,或者在客戶端完成。
  • 使用高效的命令代替轨帜。使用增量迭代的方式魄咕,避免一次查詢大量數(shù)據(jù),具體請(qǐng)查看SCAN蚌父、SSCAN哮兰、HSCAN和ZSCAN命令。

除此之外苟弛,生產(chǎn)中禁用KEYS 命令喝滞,它只適用于調(diào)試。因?yàn)樗鼤?huì)遍歷所有的鍵值對(duì)膏秫,所以操作延時(shí)高右遭。

Fork 生成 RDB 導(dǎo)致的延遲

生成 RDB 快照,Redis 必須 fork 后臺(tái)進(jìn)程。fork 操作(在主線程中運(yùn)行)本身會(huì)導(dǎo)致延遲狸演。

Redis 使用操作系統(tǒng)的多進(jìn)程寫時(shí)復(fù)制技術(shù) COW(Copy On Write) 來實(shí)現(xiàn)快照持久化言蛇,減少內(nèi)存占用。

但 fork 會(huì)涉及到復(fù)制大量鏈接對(duì)象宵距,一個(gè) 24 GB 的大型 Redis 實(shí)例需要 24 GB / 4 kB * 8 = 48 MB 的頁表。

執(zhí)行 bgsave 時(shí)吨拗,這將涉及分配和復(fù)制 48 MB 內(nèi)存满哪。

此外,從庫加載 RDB 期間無法提供讀寫服務(wù)劝篷,所以主庫的數(shù)據(jù)量大小控制在 2~4G 左右哨鸭,讓從庫快速的加載完成

內(nèi)存大頁(transparent huge pages)

常規(guī)的內(nèi)存頁是按照 4 KB 來分配娇妓,Linux 內(nèi)核從 2.6.38 開始支持內(nèi)存大頁機(jī)制像鸡,該機(jī)制支持 2MB 大小的內(nèi)存頁分配。

Redis 使用了 fork 生成RDB 做持久化提供了數(shù)據(jù)可靠性保證哈恰。

當(dāng)生成 RDB 快照的過程中只估,Redis 采用寫時(shí)復(fù)制技術(shù)使得主線程依然可以接收客戶端的寫請(qǐng)求。

也就是當(dāng)數(shù)據(jù)被修改的時(shí)候着绷,Redis 會(huì)復(fù)制一份這個(gè)數(shù)據(jù)蛔钙,再進(jìn)行修改。

采用了內(nèi)存大頁荠医,生成 RDB 期間吁脱,即使客戶端修改的數(shù)據(jù)只有 50B 的數(shù)據(jù),Redis 需要復(fù)制 2MB 的大頁彬向。當(dāng)寫的指令比較多的時(shí)候就會(huì)導(dǎo)致大量的拷貝兼贡,導(dǎo)致性能變慢。

使用以下指令禁用 Linux 內(nèi)存大頁即可:

echo never > /sys/kernel/mm/transparent_hugepage/enabled

swap:操作系統(tǒng)分頁

當(dāng)物理內(nèi)存(內(nèi)存條)不夠用的時(shí)候娃胆,將部分內(nèi)存上的數(shù)據(jù)交換到 swap 空間上遍希,以便讓系統(tǒng)不會(huì)因內(nèi)存不夠用而導(dǎo)致 oom 或者更致命的情況出現(xiàn)。

當(dāng)某進(jìn)程向 OS 請(qǐng)求內(nèi)存發(fā)現(xiàn)不足時(shí)缕棵,OS 會(huì)把內(nèi)存中暫時(shí)不用的數(shù)據(jù)交換出去孵班,放在 SWAP 分區(qū)中,這個(gè)過程稱為 SWAP OUT招驴。

當(dāng)某進(jìn)程又需要這些數(shù)據(jù)且 OS 發(fā)現(xiàn)還有空閑物理內(nèi)存時(shí)篙程,又會(huì)把 SWAP 分區(qū)中的數(shù)據(jù)交換回物理內(nèi)存中,這個(gè)過程稱為 SWAP IN别厘。

內(nèi)存 swap 是操作系統(tǒng)里將內(nèi)存數(shù)據(jù)在內(nèi)存和磁盤間來回?fù)Q入和換出的機(jī)制虱饿,涉及到磁盤的讀寫。

觸發(fā) swap 的情況有哪些呢?

對(duì)于 Redis 而言氮发,有兩種常見的情況:

  • Redis 使用了比可用內(nèi)存更多的內(nèi)存渴肉;
  • 與 Redis 在同一機(jī)器運(yùn)行的其他進(jìn)程在執(zhí)行大量的文件讀寫 I/O 操作(包括生成大文件的 RDB 文件和 AOF 后臺(tái)線程),文件讀寫占用內(nèi)存爽冕,導(dǎo)致 Redis 獲得的內(nèi)存減少仇祭,觸發(fā)了 swap。

我要如何排查是否因?yàn)?swap 導(dǎo)致的性能變慢呢颈畸?

Linux 提供了很好的工具來排查這個(gè)問題乌奇,所以當(dāng)懷疑由于交換導(dǎo)致的延遲時(shí),只需按照以下步驟排查眯娱。

獲取 Redis 實(shí)例 pid

$ redis-cli info | grep process_idprocess_id:13160

進(jìn)入此進(jìn)程的 /proc 文件系統(tǒng)目錄:

cd /proc/13160

在這里有一個(gè) smaps 的文件礁苗,該文件描述了 Redis 進(jìn)程的內(nèi)存布局,運(yùn)行以下指令徙缴,用 grep 查找所有文件中的 Swap 字段试伙。

$ cat smaps | egrep '^(Swap|Size)'
Size:                316 kB
Swap:                  0 kB
Size:                  4 kB
Swap:                  0 kB
Size:                  8 kB
Swap:                  0 kB
Size:                 40 kB
Swap:                  0 kB
Size:                132 kB
Swap:                  0 kB
Size:             720896 kB
Swap:                 12 kB

每行 Size 表示 Redis 實(shí)例所用的一塊內(nèi)存大小,和 Size 下方的 Swap 對(duì)應(yīng)這塊 Size 大小的內(nèi)存區(qū)域有多少數(shù)據(jù)已經(jīng)被換出到磁盤上了于样。

如果 Size == Swap 則說明數(shù)據(jù)被完全換出了疏叨。

可以看到有一個(gè) 720896 kB 的內(nèi)存大小有 12 kb 被換出到了磁盤上(僅交換了 12 kB),這就沒什么問題百宇。

Redis 本身會(huì)使用很多大小不一的內(nèi)存塊考廉,所以,你可以看到有很多 Size 行携御,有的很小昌粤,就是 4KB,而有的很大啄刹,例如 720896KB涮坐。不同內(nèi)存塊被換出到磁盤上的大小也不一樣。

敲重點(diǎn)了

如果 Swap 一切都是 0 kb誓军,或者零星的 4k 袱讹,那么一切正常。

當(dāng)出現(xiàn)百 MB昵时,甚至 GB 級(jí)別的 swap 大小時(shí)捷雕,就表明,此時(shí)壹甥,Redis 實(shí)例的內(nèi)存壓力很大救巷,很有可能會(huì)變慢。

解決方案

  1. 增加機(jī)器內(nèi)存句柠;
  2. 將 Redis 放在單獨(dú)的機(jī)器上運(yùn)行浦译,避免在同一機(jī)器上運(yùn)行需要大量內(nèi)存的進(jìn)程棒假,從而滿足 Redis 的內(nèi)存需求;
  3. 增加 Cluster 集群的數(shù)量分擔(dān)數(shù)據(jù)量精盅,減少每個(gè)實(shí)例所需的內(nèi)存帽哑。

AOF 和磁盤 I/O 導(dǎo)致的延遲

為了保證數(shù)據(jù)可靠性,Redis 使用 AOF 和 RDB 快照實(shí)現(xiàn)快速恢復(fù)和持久化叹俏。

可以使用 appendfsync 配置將 AOF 配置為以三種不同的方式在磁盤上執(zhí)行 write 或者 fsync (可以在運(yùn)行時(shí)使用 CONFIG SET命令修改此設(shè)置妻枕,比如:redis-cli CONFIG SET appendfsync no)。

  • no:Redis 不執(zhí)行 fsync她肯,唯一的延遲來自于 write 調(diào)用佳头,write 只需要把日志記錄寫到內(nèi)核緩沖區(qū)就可以返回。
  • everysec:Redis 每秒執(zhí)行一次 fsync晴氨。使用后臺(tái)子線程異步完成 fsync 操作。最多丟失 1s 的數(shù)據(jù)碉输。
  • always:每次寫入操作都會(huì)執(zhí)行 fsync籽前,然后用 OK 代碼回復(fù)客戶端(實(shí)際上 Redis 會(huì)嘗試將同時(shí)執(zhí)行的許多命令聚集到單個(gè) fsync 中),沒有數(shù)據(jù)丟失敷钾。在這種模式下枝哄,性能通常非常低,強(qiáng)烈建議使用快速磁盤和可以在短時(shí)間內(nèi)執(zhí)行 fsync 的文件系統(tǒng)實(shí)現(xiàn)阻荒。

我們通常將 Redis 用于緩存挠锥,數(shù)據(jù)丟失完全惡意從數(shù)據(jù)獲取,并不需要很高的數(shù)據(jù)可靠性侨赡,建議設(shè)置成 no 或者 everysec蓖租。

除此之外,避免 AOF 文件過大羊壹, Redis 會(huì)進(jìn)行 AOF 重寫蓖宦,生成縮小的 AOF 文件。

可以把配置項(xiàng) no-appendfsync-on-rewrite設(shè)置為 yes油猫,表示在 AOF 重寫時(shí)稠茂,不進(jìn)行 fsync 操作。

也就是說情妖,Redis 實(shí)例把寫命令寫到內(nèi)存后睬关,不調(diào)用后臺(tái)線程進(jìn)行 fsync 操作,就直接返回了毡证。

expires 淘汰過期數(shù)據(jù)

Redis 有兩種方式淘汰過期數(shù)據(jù):

  • 惰性刪除:當(dāng)接收請(qǐng)求的時(shí)候發(fā)現(xiàn) key 已經(jīng)過期电爹,才執(zhí)行刪除;
  • 定時(shí)刪除:每 100 毫秒刪除一些過期的 key情竹。

定時(shí)刪除的算法如下:

  1. 隨機(jī)采樣 ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP個(gè)數(shù)的 key藐不,刪除所有過期的 key匀哄;

  2. 如果發(fā)現(xiàn)還有超過 25% 的 key 已過期,則執(zhí)行步驟一雏蛮。

ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP默認(rèn)設(shè)置為 20涎嚼,每秒執(zhí)行 10 次,刪除 200 個(gè) key 問題不大挑秉。

如果觸發(fā)了第二條法梯,就會(huì)導(dǎo)致 Redis 一致在刪除過期數(shù)據(jù)去釋放內(nèi)存。而刪除是阻塞的犀概。

觸發(fā)條件是什么呀立哑?

也就是大量的 key 設(shè)置了相同的時(shí)間參數(shù)。同一秒內(nèi)姻灶,大量 key 過期铛绰,需要重復(fù)刪除多次才能降低到 25% 以下。

簡而言之:大量同時(shí)到期的 key 可能會(huì)導(dǎo)致性能波動(dòng)产喉。

解決方案

如果一批 key 的確是同時(shí)過期捂掰,可以在 EXPIREATEXPIRE 的過期時(shí)間參數(shù)上,加上一個(gè)一定大小范圍內(nèi)的隨機(jī)數(shù)曾沈,這樣这嚣,既保證了 key 在一個(gè)鄰近時(shí)間范圍內(nèi)被刪除,又避免了同時(shí)過期造成的壓力塞俱。

bigkey

通常我們會(huì)將含有較大數(shù)據(jù)或含有大量成員姐帚、列表數(shù)的 Key 稱之為大 Key,下面我們將用幾個(gè)實(shí)際的例子對(duì)大 Key 的特征進(jìn)行描述:

  • 一個(gè) STRING 類型的 Key障涯,它的值為 5MB(數(shù)據(jù)過大)

  • 一個(gè) LIST 類型的 Key罐旗,它的列表數(shù)量為 10000 個(gè)(列表數(shù)量過多)

  • 一個(gè) ZSET 類型的 Key,它的成員數(shù)量為 10000 個(gè)(成員數(shù)量過多)

  • 一個(gè) HASH 格式的 Key像樊,它的成員數(shù)量雖然只有 1000 個(gè)但這些成員的 value 總大小為 10MB(成員體積過大)

bigkey 帶來問題如下:

  1. Redis 內(nèi)存不斷變大引發(fā) OOM尤莺,或者達(dá)到 maxmemory 設(shè) 置值引發(fā)寫阻塞或重要 Key 被逐出;
  2. Redis Cluster 中的某個(gè) node 內(nèi)存遠(yuǎn)超其余 node生棍,但因 Redis Cluster 的數(shù)據(jù)遷移最小粒度為 Key 而無法將 node 上的內(nèi)存均衡化颤霎;
  3. bigkey 的讀請(qǐng)求占用過大帶寬,自身變慢的同時(shí)影響到該服務(wù)器上的其它服務(wù)涂滴;
  4. 刪除一個(gè) bigkey 造成主庫較長時(shí)間的阻塞并引發(fā)同步中斷或主從切換友酱;

查找 bigkey

使用 redis-rdb-tools 工具以定制化方式找出大 Key。

解決方案

對(duì)大 key 拆分

如將一個(gè)含有數(shù)萬成員的 HASH Key 拆分為多個(gè) HASH Key柔纵,并確保每個(gè) Key 的成員數(shù)量在合理范圍缔杉,在 Redis Cluster 結(jié)構(gòu)中,大 Key 的拆分對(duì) node 間的內(nèi)存平衡能夠起到顯著作用搁料。

異步清理大 key

Redis 自 4.0 起提供了 UNLINK 命令或详,該命令能夠以非阻塞的方式緩慢逐步的清理傳入的 Key系羞,通過 UNLINK,你可以安全的刪除大 Key 甚至特大 Key霸琴。

總結(jié)

如下檢查清單椒振,幫助你在遇到 Redis 性能變慢的時(shí)候能高效解決問題。

  1. 獲取當(dāng)前 Redis 的基線性能梧乘;
  2. 開啟慢指令監(jiān)控澎迎,定位慢指令導(dǎo)致的問題;
  3. 找到慢指令选调,使用 scan 的方式夹供;
  4. 將實(shí)例的數(shù)據(jù)大小控制在 2-4GB,避免主從復(fù)制加載過大 RDB 文件而阻塞仁堪;
  5. 禁用內(nèi)存大頁哮洽,采用了內(nèi)存大頁,生成 RDB 期間弦聂,即使客戶端修改的數(shù)據(jù)只有 50B 的數(shù)據(jù)袁铐,Redis 需要復(fù)制 2MB 的大頁。當(dāng)寫的指令比較多的時(shí)候就會(huì)導(dǎo)致大量的拷貝横浑,導(dǎo)致性能變慢。
  6. Redis 使用的內(nèi)存是否過大導(dǎo)致 swap屉更;
  7. AOF 配置是否合理徙融,可以將配置項(xiàng) no-appendfsync-on-rewrite 設(shè)置為 yes,避免 AOF 重寫和 fsync 競(jìng)爭磁盤 IO 資源瑰谜,導(dǎo)致 Redis 延遲增加欺冀。
  8. bigkey 會(huì)帶來一系列問題,我們需要進(jìn)行拆分防止出現(xiàn) bigkey萨脑,并通過 UNLINK 異步刪除隐轩。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市渤早,隨后出現(xiàn)的幾起案子职车,更是在濱河造成了極大的恐慌,老刑警劉巖鹊杖,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悴灵,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡骂蓖,警方通過查閱死者的電腦和手機(jī)积瞒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來登下,“玉大人茫孔,你說我怎么就攤上這事叮喳。” “怎么了缰贝?”我有些...
    開封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵馍悟,是天一觀的道長。 經(jīng)常有香客問我揩瞪,道長赋朦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任李破,我火速辦了婚禮,結(jié)果婚禮上嗤攻,老公的妹妹穿的比我還像新娘。我一直安慰自己妇菱,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開白布闯团。 她就那樣靜靜地躺著辛臊,像睡著了一般房交。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上候味,一...
    開封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天刃唤,我揣著相機(jī)與錄音,去河邊找鬼白群。 笑死尚胞,一個(gè)胖子當(dāng)著我的面吹牛帜慢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播侍咱,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼密幔,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了胯甩?” 一聲冷哼從身側(cè)響起堪嫂,我...
    開封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤皆串,失蹤者是張志新(化名)和其女友劉穎眉枕,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體速挑,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年翅萤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了腊满。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡胚泌,死狀恐怖肃弟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤壁公,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站比肄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏囊陡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一妥色、第九天 我趴在偏房一處隱蔽的房頂上張望遏片。 院中可真熱鬧撮竿,春花似錦笔呀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽搭幻。三九已至敛助,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間纳击,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來泰國打工焕数, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人识脆。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓善已,卻偏偏與公主長得像,于是被迫代替她去往敵國和親悉稠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子艘包,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 本文作為學(xué)習(xí)筆記想虎,文章內(nèi)容來自“極客時(shí)間”專欄《Redis核心技術(shù)與實(shí)戰(zhàn)》卦尊,如有侵權(quán)舌厨,請(qǐng)告知,必即時(shí)刪除淌友。 Red...
    JBryan閱讀 1,935評(píng)論 0 0
  • Redis作為內(nèi)存數(shù)據(jù)庫拨拓,擁有非常高的性能,單個(gè)實(shí)例的QPS能夠達(dá)到10W左右婿着。 但我們?cè)谑褂肦edis時(shí)醋界,經(jīng)常時(shí)...
    趙客縵胡纓v吳鉤霜雪明閱讀 790評(píng)論 0 8
  • by shihang.mai Redis 作為優(yōu)秀的內(nèi)存數(shù)據(jù)庫,其擁有非常高的性能形纺,單個(gè)實(shí)例的 OPS 能夠達(dá)到 ...
    麥大大吃不胖閱讀 679評(píng)論 0 0
  • Redis作為內(nèi)存數(shù)據(jù)庫逐样,擁有非常高的性能,單個(gè)實(shí)例的QPS能夠達(dá)到10W左右脂新。但我們?cè)谑褂肦edis時(shí),經(jīng)常時(shí)不...
    wxyjj閱讀 228評(píng)論 0 1
  • 在一些網(wǎng)絡(luò)服務(wù)的系統(tǒng)中躬窜,Redis 的性能,可能是比 MySQL 等硬盤數(shù)據(jù)庫的性能更重要的課題男韧。比如微博,把熱點(diǎn)...
    瘋狂的代碼士閱讀 764評(píng)論 0 0