欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談Redis變慢的原因及排查方法

 更新時(shí)間:2022年06月17日 09:13:26   作者:普通收錄  
本文主要介紹了淺談Redis變慢的原因及排查方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

原因1:實(shí)例內(nèi)存達(dá)到上限

排查思路

如果你的 Redis 實(shí)例設(shè)置了內(nèi)存上限 maxmemory,那么也有可能導(dǎo)致 Redis 變慢。

當(dāng)我們把 Redis 當(dāng)做純緩存使用時(shí),通常會(huì)給這個(gè)實(shí)例設(shè)置一個(gè)內(nèi)存上限 maxmemory,然后設(shè)置一個(gè)數(shù)據(jù)淘汰策略。而當(dāng)實(shí)例的內(nèi)存達(dá)到了 maxmemory 后,你可能會(huì)發(fā)現(xiàn),在此之后每次寫(xiě)入新數(shù)據(jù),操作延遲變大了。

導(dǎo)致變慢的原因

當(dāng) Redis 內(nèi)存達(dá)到 maxmemory 后,每次寫(xiě)入新的數(shù)據(jù)之前,Redis 必須先從實(shí)例中踢出一部分?jǐn)?shù)據(jù),讓整個(gè)實(shí)例的內(nèi)存維持在 maxmemory 之下,然后才能把新數(shù)據(jù)寫(xiě)進(jìn)來(lái)。

這個(gè)踢出舊數(shù)據(jù)的邏輯也是需要消耗時(shí)間的,而具體耗時(shí)的長(zhǎng)短,要取決于你配置的淘汰策略:

  • allkeys-lru:不管 key 是否設(shè)置了過(guò)期,淘汰最近最少訪問(wèn)的 key
  • volatile-lru:只淘汰最近最少訪問(wèn)、并設(shè)置了過(guò)期時(shí)間的 key
  • allkeys-random:不管 key 是否設(shè)置了過(guò)期,隨機(jī)淘汰 key
  • volatile-random:只隨機(jī)淘汰設(shè)置了過(guò)期時(shí)間的 key
  • allkeys-ttl:不管 key 是否設(shè)置了過(guò)期,淘汰即將過(guò)期的 key
  • noeviction:不淘汰任何 key,實(shí)例內(nèi)存達(dá)到 maxmeory 后,再寫(xiě)入新數(shù)據(jù)直接返回錯(cuò)誤
  • allkeys-lfu:不管 key 是否設(shè)置了過(guò)期,淘汰訪問(wèn)頻率最低的 key(4.0+版本支持)
  • volatile-lfu:只淘汰訪問(wèn)頻率最低、并設(shè)置了過(guò)期時(shí)間 key(4.0+版本支持)

        具體使用哪種策略,我們需要根據(jù)具體的業(yè)務(wù)場(chǎng)景來(lái)配置。一般最常使用的是 allkeys-lru / volatile-lru 淘汰策略,它們的處理邏輯是,每次從實(shí)例中隨機(jī)取出一批 key(這個(gè)數(shù)量可配置),然后淘汰一個(gè)最少訪問(wèn)的 key,之后把剩下的 key 暫存到一個(gè)池子中,繼續(xù)隨機(jī)取一批 key,并與之前池子中的 key 比較,再淘汰一個(gè)最少訪問(wèn)的 key。以此往復(fù),直到實(shí)例內(nèi)存降到 maxmemory 之下。

        需要注意的是,Redis 的淘汰數(shù)據(jù)的邏輯與刪除過(guò)期 key 的一樣,也是在命令真正執(zhí)行之前執(zhí)行的,也就是說(shuō)它也會(huì)增加我們操作 Redis 的延遲,而且,寫(xiě) OPS 越高,延遲也會(huì)越明顯。

另外,如果此時(shí)你的 Redis 實(shí)例中還存儲(chǔ)了 bigkey,那么在淘汰刪除 bigkey 釋放內(nèi)存時(shí),也會(huì)耗時(shí)比較久。

看到了么?bigkey 的危害到處都是,這也是前面我提醒你盡量不存儲(chǔ) bigkey 的原因。

解決方案

  • 避免存儲(chǔ) bigkey,降低釋放內(nèi)存的耗時(shí)
  • 淘汰策略改為隨機(jī)淘汰,隨機(jī)淘汰比 LRU 要快很多(視業(yè)務(wù)情況調(diào)整)
  • 拆分實(shí)例,把淘汰 key 的壓力分?jǐn)偟蕉鄠€(gè)實(shí)例上
  • 如果使用的是 Redis 4.0 以上版本,開(kāi)啟 layz-free 機(jī)制,把淘汰 key 釋放內(nèi)存的操作放到后臺(tái)線(xiàn)程中執(zhí)行(配置 lazyfree-lazy-eviction = yes)

原因2:開(kāi)啟內(nèi)存大頁(yè)

排查思路

  • 我們都知道,應(yīng)用程序向操作系統(tǒng)申請(qǐng)內(nèi)存時(shí),是按內(nèi)存頁(yè)進(jìn)行申請(qǐng)的,而常規(guī)的內(nèi)存頁(yè)大小是 4KB。
  • Linux 內(nèi)核從 2.6.38 開(kāi)始,支持了內(nèi)存大頁(yè)機(jī)制,該機(jī)制允許應(yīng)用程序以 2MB 大小為單位,向操作系統(tǒng)申請(qǐng)內(nèi)存。
  • 應(yīng)用程序每次向操作系統(tǒng)申請(qǐng)的內(nèi)存單位變大了,但這也意味著申請(qǐng)內(nèi)存的耗時(shí)變長(zhǎng)。

導(dǎo)致變慢的原因

  • 當(dāng) Redis 在執(zhí)行后臺(tái) RDB 和 AOF rewrite 時(shí),采用 fork 子進(jìn)程的方式來(lái)處理。但主進(jìn)程 fork 子進(jìn)程后,此時(shí)的主進(jìn)程依舊是可以接收寫(xiě)請(qǐng)求的,而進(jìn)來(lái)的寫(xiě)請(qǐng)求,會(huì)采用 Copy On Write(寫(xiě)時(shí)復(fù)制)的方式操作內(nèi)存數(shù)據(jù)。
  • 也就是說(shuō),主進(jìn)程一旦有數(shù)據(jù)需要修改,Redis 并不會(huì)直接修改現(xiàn)有內(nèi)存中的數(shù)據(jù),而是先將這塊內(nèi)存數(shù)據(jù)拷貝出來(lái),再修改這塊新內(nèi)存的數(shù)據(jù),這就是所謂的「寫(xiě)時(shí)復(fù)制」。
  • 寫(xiě)時(shí)復(fù)制你也可以理解成,誰(shuí)需要發(fā)生寫(xiě)操作,誰(shuí)就需要先拷貝,再修改。
  • 這樣做的好處是,父進(jìn)程有任何寫(xiě)操作,并不會(huì)影響子進(jìn)程的數(shù)據(jù)持久化(子進(jìn)程只持久化 fork 這一瞬間整個(gè)實(shí)例中的所有數(shù)據(jù)即可,不關(guān)心新的數(shù)據(jù)變更,因?yàn)樽舆M(jìn)程只需要一份內(nèi)存快照,然后持久化到磁盤(pán)上)。
  • 但是請(qǐng)注意,主進(jìn)程在拷貝內(nèi)存數(shù)據(jù)時(shí),這個(gè)階段就涉及到新內(nèi)存的申請(qǐng),如果此時(shí)操作系統(tǒng)開(kāi)啟了內(nèi)存大頁(yè),那么在此期間,客戶(hù)端即便只修改 10B 的數(shù)據(jù),Redis 在申請(qǐng)內(nèi)存時(shí)也會(huì)以 2MB 為單位向操作系統(tǒng)申請(qǐng),申請(qǐng)內(nèi)存的耗時(shí)變長(zhǎng),進(jìn)而導(dǎo)致每個(gè)寫(xiě)請(qǐng)求的延遲增加,影響到 Redis 性能。
  • 同樣地,如果這個(gè)寫(xiě)請(qǐng)求操作的是一個(gè) bigkey,那主進(jìn)程在拷貝這個(gè) bigkey 內(nèi)存塊時(shí),一次申請(qǐng)的內(nèi)存會(huì)更大,時(shí)間也會(huì)更久??梢?jiàn),bigkey 在這里又一次影響到了性能。

解決方案

關(guān)閉內(nèi)存大頁(yè)機(jī)制。

首先,你需要查看 Redis 機(jī)器是否開(kāi)啟了內(nèi)存大頁(yè):

$ cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never

如果輸出選項(xiàng)是 always,就表示目前開(kāi)啟了內(nèi)存大頁(yè)機(jī)制,我們需要關(guān)掉它:

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

其實(shí),操作系統(tǒng)提供的內(nèi)存大頁(yè)機(jī)制,其優(yōu)勢(shì)是,可以在一定程序上降低應(yīng)用程序申請(qǐng)內(nèi)存的次數(shù)。

但是對(duì)于 Redis 這種對(duì)性能和延遲極其敏感的數(shù)據(jù)庫(kù)來(lái)說(shuō),我們希望 Redis 在每次申請(qǐng)內(nèi)存時(shí),耗時(shí)盡量短,所以我不建議你在 Redis 機(jī)器上開(kāi)啟這個(gè)機(jī)制。

原因3:使用Swap

排查思路

如果你發(fā)現(xiàn) Redis 突然變得非常慢,每次的操作耗時(shí)都達(dá)到了幾百毫秒甚至秒級(jí),那此時(shí)你就需要檢查 Redis 是否使用到了 Swap,在這種情況下 Redis 基本上已經(jīng)無(wú)法提供高性能的服務(wù)了。

導(dǎo)致變慢的原因

什么是 Swap?為什么使用 Swap 會(huì)導(dǎo)致 Redis 的性能下降?

如果你對(duì)操作系統(tǒng)有些了解,就會(huì)知道操作系統(tǒng)為了緩解內(nèi)存不足對(duì)應(yīng)用程序的影響,允許把一部分內(nèi)存中的數(shù)據(jù)換到磁盤(pán)上,以達(dá)到應(yīng)用程序?qū)?nèi)存使用的緩沖,這些內(nèi)存數(shù)據(jù)被換到磁盤(pán)上的區(qū)域,就是 Swap。

問(wèn)題就在于,當(dāng)內(nèi)存中的數(shù)據(jù)被換到磁盤(pán)上后,Redis 再訪問(wèn)這些數(shù)據(jù)時(shí),就需要從磁盤(pán)上讀取,訪問(wèn)磁盤(pán)的速度要比訪問(wèn)內(nèi)存慢幾百倍!尤其是針對(duì) Redis 這種對(duì)性能要求極高、性能極其敏感的數(shù)據(jù)庫(kù)來(lái)說(shuō),這個(gè)操作延時(shí)是無(wú)法接受的。

此時(shí),你需要檢查 Redis 機(jī)器的內(nèi)存使用情況,確認(rèn)是否存在使用了 Swap。你可以通過(guò)以下方式來(lái)查看 Redis 進(jìn)程是否使用到了 Swap:

# 先找到 Redis 的進(jìn)程 ID
$ ps -aux | grep redis-server
 
# 查看 Redis Swap 使用情況
$ cat /proc/$pid/smaps | egrep '^(Swap|Size)'

輸出結(jié)果如下

Size:               1256 kB
Swap:                  0 kB
Size:                  4 kB
Swap:                  0 kB
Size:                132 kB
Swap:                  0 kB
Size:              63488 kB
Swap:                  0 kB
Size:                132 kB
Swap:                  0 kB
Size:              65404 kB
Swap:                  0 kB
Size:            1921024 kB
Swap:                  0 kB
...

這個(gè)結(jié)果會(huì)列出 Redis 進(jìn)程的內(nèi)存使用情況。

每一行 Size 表示 Redis 所用的一塊內(nèi)存大小,Size 下面的 Swap 就表示這塊 Size 大小的內(nèi)存,有多少數(shù)據(jù)已經(jīng)被換到磁盤(pán)上了,如果這兩個(gè)值相等,說(shuō)明這塊內(nèi)存的數(shù)據(jù)都已經(jīng)完全被換到磁盤(pán)上了。

如果只是少量數(shù)據(jù)被換到磁盤(pán)上,例如每一塊 Swap 占對(duì)應(yīng) Size 的比例很小,那影響并不是很大。如果是幾百兆甚至上 GB 的內(nèi)存被換到了磁盤(pán)上,那么你就需要警惕了,這種情況 Redis 的性能肯定會(huì)急劇下降。

解決方案

  • 增加機(jī)器的內(nèi)存,讓 Redis 有足夠的內(nèi)存可以使用
  • 整理內(nèi)存空間,釋放出足夠的內(nèi)存供 Redis 使用,然后釋放 Redis 的 Swap,讓 Redis 重新使用內(nèi)存

釋放 Redis 的 Swap 過(guò)程通常要重啟實(shí)例,為了避免重啟實(shí)例對(duì)業(yè)務(wù)的影響,一般會(huì)先進(jìn)行主從切換,然后釋放舊主節(jié)點(diǎn)的 Swap,重啟舊主節(jié)點(diǎn)實(shí)例,待從庫(kù)數(shù)據(jù)同步完成后,再進(jìn)行主從切換即可。

可見(jiàn),當(dāng) Redis 使用到 Swap 后,此時(shí)的 Redis 性能基本已達(dá)不到高性能的要求(你可以理解為武功被廢),所以你也需要提前預(yù)防這種情況。

預(yù)防的辦法就是,你需要對(duì) Redis 機(jī)器的內(nèi)存和 Swap 使用情況進(jìn)行監(jiān)控,在內(nèi)存不足或使用到 Swap 時(shí)報(bào)警出來(lái),及時(shí)處理。

原因4:網(wǎng)絡(luò)帶寬過(guò)載 

排查思路

如果以上產(chǎn)生性能問(wèn)題的場(chǎng)景,你都規(guī)避掉了,而且 Redis 也穩(wěn)定運(yùn)行了很長(zhǎng)時(shí)間,但在某個(gè)時(shí)間點(diǎn)之后開(kāi)始,操作 Redis 突然開(kāi)始變慢了,而且一直持續(xù)下去,這種情況又是什么原因?qū)е拢?/p>

此時(shí)你需要排查一下 Redis 機(jī)器的網(wǎng)絡(luò)帶寬是否過(guò)載,是否存在某個(gè)實(shí)例把整個(gè)機(jī)器的網(wǎng)路帶寬占滿(mǎn)的情況。

導(dǎo)致變慢的原因

網(wǎng)絡(luò)帶寬過(guò)載的情況下,服務(wù)器在 TCP 層和網(wǎng)絡(luò)層就會(huì)出現(xiàn)數(shù)據(jù)包發(fā)送延遲、丟包等情況。

Redis 的高性能,除了操作內(nèi)存之外,就在于網(wǎng)絡(luò) IO 了,如果網(wǎng)絡(luò) IO 存在瓶頸,那么也會(huì)嚴(yán)重影響 Redis 的性能。

解決方案

  • 及時(shí)確認(rèn)占滿(mǎn)網(wǎng)絡(luò)帶寬 Redis 實(shí)例,如果屬于正常的業(yè)務(wù)訪問(wèn),那就需要及時(shí)擴(kuò)容或遷移實(shí)例了,避免因?yàn)檫@個(gè)實(shí)例流量過(guò)大,影響這個(gè)機(jī)器的其他實(shí)例。
  • 運(yùn)維層面,你需要對(duì) Redis 機(jī)器的各項(xiàng)指標(biāo)增加監(jiān)控,包括網(wǎng)絡(luò)流量,在網(wǎng)絡(luò)流量達(dá)到一定閾值時(shí)提前報(bào)警,及時(shí)確認(rèn)和擴(kuò)容。

原因5:其他原因

1) 頻繁短連接

你的業(yè)務(wù)應(yīng)用,應(yīng)該使用長(zhǎng)連接操作 Redis,避免頻繁的短連接。

頻繁的短連接會(huì)導(dǎo)致 Redis 大量時(shí)間耗費(fèi)在連接的建立和釋放上,TCP 的三次握手和四次揮手同樣也會(huì)增加訪問(wèn)延遲。

2) 運(yùn)維監(jiān)控

前面我也提到了,要想提前預(yù)知 Redis 變慢的情況發(fā)生,必不可少的就是做好完善的監(jiān)控。

監(jiān)控其實(shí)就是對(duì)采集 Redis 的各項(xiàng)運(yùn)行時(shí)指標(biāo),通常的做法是監(jiān)控程序定時(shí)采集 Redis 的 INFO 信息,然后根據(jù) INFO 信息中的狀態(tài)數(shù)據(jù)做數(shù)據(jù)展示和報(bào)警。

這里我需要提醒你的是,在寫(xiě)一些監(jiān)控腳本,或使用開(kāi)源的監(jiān)控組件時(shí),也不能掉以輕心。

在寫(xiě)監(jiān)控腳本訪問(wèn) Redis 時(shí),盡量采用長(zhǎng)連接的方式采集狀態(tài)信息,避免頻繁短連接。同時(shí),你還要注意控制訪問(wèn) Redis 的頻率,避免影響到業(yè)務(wù)請(qǐng)求。

在使用一些開(kāi)源的監(jiān)控組件時(shí),最好了解一下這些組件的實(shí)現(xiàn)原理,以及正確配置這些組件,防止出現(xiàn)監(jiān)控組件發(fā)生 Bug,導(dǎo)致短時(shí)大量操作 Redis,影響 Redis 性能的情況發(fā)生。

我們當(dāng)時(shí)就發(fā)生過(guò),DBA 在使用一些開(kāi)源組件時(shí),因?yàn)榕渲煤褪褂脝?wèn)題,導(dǎo)致監(jiān)控程序頻繁地與 Redis 建立和斷開(kāi)連接,導(dǎo)致 Redis 響應(yīng)變慢。

3)其它程序爭(zhēng)搶資源

最后需要提醒你的是,你的 Redis 機(jī)器最好專(zhuān)項(xiàng)專(zhuān)用,只用來(lái)部署 Redis 實(shí)例,不要部署其他應(yīng)用程序,盡量給 Redis 提供一個(gè)相對(duì)「安靜」的環(huán)境,避免其它程序占用 CPU、內(nèi)存、磁盤(pán)資源,導(dǎo)致分配給 Redis 的資源不足而受到影響。

到此這篇關(guān)于淺談Redis變慢的原因及排查方法的文章就介紹到這了,更多相關(guān)Redis變慢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Linux下redis5.0.5的安裝過(guò)程與配置方法

    Linux下redis5.0.5的安裝過(guò)程與配置方法

    這篇文章主要介紹了Linux下redis5.0.5的安裝過(guò)程與配置方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Centos7 Redis主從搭建配置的實(shí)現(xiàn)

    Centos7 Redis主從搭建配置的實(shí)現(xiàn)

    這篇文章主要介紹了Centos7 Redis主從搭建配置的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • 淺談redis的maxmemory設(shè)置以及淘汰策略

    淺談redis的maxmemory設(shè)置以及淘汰策略

    下面小編就為大家?guī)?lái)一篇淺談redis的maxmemory設(shè)置以及淘汰策略。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-03-03
  • sentinel支持的redis高可用集群配置詳解

    sentinel支持的redis高可用集群配置詳解

    這篇文章主要為大家介紹了sentinel支持的redis高可用集群配置詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • 利用redis實(shí)現(xiàn)聊天記錄轉(zhuǎn)存功能的全過(guò)程

    利用redis實(shí)現(xiàn)聊天記錄轉(zhuǎn)存功能的全過(guò)程

    社交類(lèi)軟件聊天功能必不可少,聊天記錄存儲(chǔ)的方式也比較多,比如文本,數(shù)據(jù)庫(kù),云等等,但是最好的選擇還是redis進(jìn)行存儲(chǔ),這篇文章主要給大家介紹了關(guān)于如何利用redis實(shí)現(xiàn)聊天記錄轉(zhuǎn)存功能的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • Linux Redis 的安裝步驟詳解

    Linux Redis 的安裝步驟詳解

    這篇文章主要介紹了 Linux Redis 的安裝步驟詳解的相關(guān)資料,希望大家通過(guò)本文能掌握如何安裝Redis,需要的朋友可以參考下
    2017-08-08
  • Redis 命令的詳解及簡(jiǎn)單實(shí)例

    Redis 命令的詳解及簡(jiǎn)單實(shí)例

    這篇文章主要介紹了Redis 命令的詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,這里提供基礎(chǔ)語(yǔ)法及使用實(shí)例,需要的朋友可以參考下
    2017-08-08
  • Redis異常測(cè)試盤(pán)點(diǎn)分析

    Redis異常測(cè)試盤(pán)點(diǎn)分析

    這篇文章主要為大家介紹了Redis異常測(cè)試盤(pán)點(diǎn)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Redis?哨兵模式的實(shí)現(xiàn)詳解

    Redis?哨兵模式的實(shí)現(xiàn)詳解

    本文主要介紹了Redis?哨兵模式的實(shí)現(xiàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Redis和Lua實(shí)現(xiàn)分布式限流器的方法詳解

    Redis和Lua實(shí)現(xiàn)分布式限流器的方法詳解

    這篇文章主要給大家介紹了關(guān)于Redis和Lua實(shí)現(xiàn)分布式限流器的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Redis和Lua具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06

最新評(píng)論