Redis 性能分析及優(yōu)化

性能分析及優(yōu)化

內(nèi)存診斷

內(nèi)存使用率是Redis服務(wù)最關(guān)鍵的一部分前鹅。

如果Redis實(shí)例的內(nèi)存使用率超過(guò)最大可用內(nèi)存霍衫,即“used_memory”>最大可用內(nèi)存,那么操作系統(tǒng)會(huì)將內(nèi)存與Swap空間交換,把內(nèi)存中舊的或不再使用的內(nèi)容寫入硬盤上的Swap分區(qū)忧陪,以便留出新的物理內(nèi)存給新頁(yè)或活動(dòng)頁(yè)(page)使用虐先。

通過(guò)查看“used_memory”指標(biāo)可知道Redis的內(nèi)存情況秉扑,當(dāng)“used_memory”>最大可用內(nèi)存時(shí)吸占,Redis實(shí)例正在進(jìn)行內(nèi)存交換或者已經(jīng)內(nèi)存交換完畢。如果Redis進(jìn)程上發(fā)生內(nèi)存交換瓶您,那么Redis及使用Redis數(shù)據(jù)的應(yīng)用性能都會(huì)受到嚴(yán)重影響麻捻。

理想情況下,“used_memory_rss”的值應(yīng)該比“used_memory”略微高一點(diǎn)呀袱。

“used_memory_rss”>“used_memory”贸毕,且兩者的值相差較大時(shí),表示存在(內(nèi)部或外部的)內(nèi)存碎片夜赵。內(nèi)存碎片的比率可以通過(guò)“mem_fragmentation_ratio”的值確定明棍。

“used_memory”>“used_memory_rss”,表示Redis的部分內(nèi)存被操作系統(tǒng)換出到Swap空間了寇僧,在這種情況下摊腋,操作可能會(huì)產(chǎn)生明顯延遲。

當(dāng)Redis釋放內(nèi)存時(shí)婉宰,分配器有可能會(huì)將內(nèi)存返還給操作系統(tǒng)歌豺,也可能不會(huì)推穷。

如果Redis釋放了內(nèi)存心包,卻沒(méi)有將內(nèi)存返還給操作系統(tǒng),那么“used_memory”的值可能和操作系統(tǒng)顯示的Redis內(nèi)存占用并不一致馒铃,通過(guò)查看“used_memory_peak”可以驗(yàn)證這種情況是否發(fā)生蟹腾。

①跟蹤內(nèi)存使用率

當(dāng)Redis內(nèi)存使用率超過(guò)可用內(nèi)存的95%時(shí),部分?jǐn)?shù)據(jù)開始在內(nèi)存與Swap空間來(lái)回交換区宇,如果沒(méi)有開啟RDB快照或AOF持久化策略娃殖,緩存數(shù)據(jù)在Redis崩潰時(shí)會(huì)有丟失風(fēng)險(xiǎn)。

當(dāng)開啟并觸發(fā)快照功能時(shí)议谷,Redis會(huì)fork一個(gè)子進(jìn)程炉爆,復(fù)制當(dāng)前內(nèi)存中的數(shù)據(jù)到硬盤,若當(dāng)前使用內(nèi)存超過(guò)可用內(nèi)存的45%時(shí)觸發(fā)快照功能,那么此時(shí)進(jìn)行的內(nèi)存交換可能會(huì)丟失數(shù)據(jù)芬首。如果此時(shí)Redis實(shí)例上有大量頻繁的更新操作赴捞,問(wèn)題會(huì)更加嚴(yán)重。

我們可以減少Redis的內(nèi)存占用率來(lái)解決該問(wèn)題郁稍,或者使用下面的技巧來(lái)避免內(nèi)存交換:

盡可能的使用Hash數(shù)據(jù)結(jié)構(gòu)

Redis在儲(chǔ)存小于100個(gè)字段的Hash結(jié)構(gòu)時(shí)赦政,存儲(chǔ)效率非常高,因此在不需要集合“set”操作或“l(fā)ist”的“push/pop”操作時(shí)耀怜,我們應(yīng)盡可能地使用Hash結(jié)構(gòu)恢着。

設(shè)置“key”的過(guò)期時(shí)間

通過(guò)在存儲(chǔ)對(duì)象時(shí)設(shè)置“key”的過(guò)期時(shí)間可以減少內(nèi)存使用率。倘若“key”在明確的時(shí)間周期內(nèi)使用或者舊“key”不大可能被使用時(shí)财破,就可以用Redis過(guò)期時(shí)間命令(expire,expireat, pexpire, pexpireat)去設(shè)置過(guò)期時(shí)間掰派,這樣Redis會(huì)在“key”過(guò)期時(shí)自動(dòng)將其刪除。

回收“key”狈究。

在Redis配置文件中(一般為“redis.conf”文件)碗淌,設(shè)置“maxmemory”的值可以限制Redis最大使用內(nèi)存,修改后重啟實(shí)例生效抖锥。

當(dāng)內(nèi)存使用達(dá)到設(shè)置的最大閥值時(shí)亿眠,需要選擇一種“key”的回收策略,可在“redis.conf”配置文件中修改“maxmemory-policy”屬性磅废。若是Redis數(shù)據(jù)集中的“key”都設(shè)置了過(guò)期時(shí)間纳像,那么“volatile-ttl”策略是比較好的選擇,但如果“key”在達(dá)到最大內(nèi)存限制時(shí)沒(méi)能迅速過(guò)期拯勉,或根本沒(méi)有設(shè)置過(guò)期時(shí)間竟趾,那么設(shè)置為“allkeys-lru”更加合適,它允許Redis從整個(gè)數(shù)據(jù)集中挑選近期最少使用的“key”進(jìn)行刪除(LRU淘汰算法)宫峦。

Redis還提供了一些其他淘汰策略岔帽,如下:

“volatile-lru”:使用LRU算法從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集合中淘汰數(shù)據(jù)

“volatile-ttl”:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集合中淘汰即將過(guò)期的數(shù)據(jù)

“volatile-random”:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集合中隨機(jī)淘汰數(shù)據(jù)

“allkeys-lru”:使用LRU算法從所有數(shù)據(jù)集合中淘汰數(shù)據(jù)

“allkeys-random”:從數(shù)據(jù)集合中任意淘汰數(shù)據(jù)

“no-enviction”:禁止淘汰數(shù)據(jù)

設(shè)置“maxmemory”的值為系統(tǒng)可用內(nèi)存的45%或95%(取決于持久化策略),設(shè)置“maxmemory-policy”為“volatile-ttl”或“allkeys-lru”(取決于過(guò)期設(shè)置)导绷,可以比較準(zhǔn)確的限制Redis最大內(nèi)存使用率犀勒,在絕大多數(shù)場(chǎng)景下使用這2種方式可確保Redis不會(huì)進(jìn)行內(nèi)存交換。

延遲診斷

Redis之所以這么流行的主要原因之一就是低延遲特性帶來(lái)的高性能妥曲,所以說(shuō)解決延遲問(wèn)題是提高Redis性能最直接的辦法贾费。

以1G帶寬來(lái)說(shuō),若是延遲時(shí)間遠(yuǎn)高于200μs檐盟,那明顯是出現(xiàn)了性能問(wèn)題褂萧。Redis是單核執(zhí)行所有客戶端的請(qǐng)求的, 即使在服務(wù)器上會(huì)有一些慢的IO操作葵萎,這些請(qǐng)求也都是按序排隊(duì)等待執(zhí)行的导犹。

①通過(guò)slowlog查出引發(fā)延遲的慢命令

Redis中的“slowlog”命令可以讓我們快速定位到超出指定執(zhí)行時(shí)間的慢命令唱凯,默認(rèn)情況下命令若是執(zhí)行時(shí)間超過(guò)10ms就會(huì)被記錄到日志』蚜。“slowlog”只會(huì)記錄其命令執(zhí)行的時(shí)間波丰,不包含IO往返操作及由網(wǎng)絡(luò)延遲引起的慢響應(yīng) 。

通常1GB帶寬的網(wǎng)絡(luò)延遲預(yù)期在200μs左右舶得,倘若一個(gè)命令僅執(zhí)行時(shí)間就超過(guò)10ms(近網(wǎng)絡(luò)延遲的50倍)掰烟,此時(shí)可以使用“redis-cli”工具,輸入“slowlog get”命令進(jìn)行查看沐批,此時(shí)返回結(jié)果的第三個(gè)字段將以微秒為單位顯示命令的執(zhí)行時(shí)間纫骑,假如只需要查看最后10個(gè)慢命令,輸入“slowlog get 10”即可九孩。

②客戶端連接監(jiān)控

Redis是單線程模型先馆,只能單核處理客戶端的請(qǐng)求。由于客戶端連接數(shù)的增長(zhǎng)躺彬,處理請(qǐng)求的線程資源將降低分配給單個(gè)客戶端連接的處理時(shí)間煤墙,這時(shí)每個(gè)客戶端等待Redis共享服務(wù)的響應(yīng)時(shí)間將延長(zhǎng)。

因此宪拥,監(jiān)控客戶端連接數(shù)是非常有必要的仿野,通過(guò)監(jiān)控,可以確定客戶端創(chuàng)建連接數(shù)的數(shù)量是否超出預(yù)期她君,以及客戶端是否沒(méi)有有效釋放連接脚作。

查看命令如下:

“./redis-cli -p 6379 info |grep connected_clients”

Redis默認(rèn)允許客戶端連接的最大數(shù)量是10000,連接數(shù)超過(guò)5000以上缔刹,可能會(huì)影響Redis的性能球涛。

可嘗試通過(guò)如下辦法降低客戶端連接數(shù):

服務(wù)器內(nèi)存足夠:可增加Redis的實(shí)例個(gè)數(shù),均攤客戶端連接校镐。

服務(wù)器內(nèi)存足夠:可增加maxmemory配置亿扁,提高處理速度。

應(yīng)用通過(guò)連接池調(diào)用Redis:可適當(dāng)降低Redis連接的空閑數(shù)量鸟廓。

若以上方法未能降低Redis的連接數(shù)从祝,可限制客戶端連接數(shù)來(lái)提高性能。

③限制客戶端連接數(shù)

設(shè)置最大連接數(shù)可限制非預(yù)期的連接數(shù)增長(zhǎng)肝箱,并保持Redis的性能最優(yōu)哄褒。

Redis2.6版本及以上允許使用者通過(guò)配置文件(redis.conf)配置“maxclients”屬性稀蟋,來(lái)修改客戶端連接的最大值煌张。根據(jù)連接數(shù)負(fù)載的情況,這個(gè)數(shù)字應(yīng)該設(shè)置為預(yù)期連接數(shù)峰值的110到150之間退客,若連接數(shù)超出這個(gè)數(shù)值骏融,Redis會(huì)拒絕并立刻關(guān)閉新來(lái)的連接链嘀。

如新連接嘗試失敗,將返回一個(gè)錯(cuò)誤消息档玻,客戶端可執(zhí)行對(duì)應(yīng)的處理措施怀泊。

內(nèi)存碎片診斷

“info”信息中的“mem_fragmentation_ratio”給出了內(nèi)存碎片率的數(shù)據(jù)指標(biāo),該指標(biāo)由操作系統(tǒng)分配的內(nèi)存除Redis分配的內(nèi)存得出:

“mem_fragmentation_ratio = used_memory_rss / used_memory”

“used_memory”和“used_memory_rss”都包含的內(nèi)存分配有:

用戶定義的數(shù)據(jù):內(nèi)存被用來(lái)存儲(chǔ)“key-value”值

內(nèi)部開銷:存儲(chǔ)內(nèi)部Redis信息來(lái)表示不同的數(shù)據(jù)類型

“used_memory_rss”的“rss”是“Resident Set Size”的縮寫误趴,表示該進(jìn)程所占物理內(nèi)存的大小是操作系統(tǒng)分配給Redis實(shí)例的內(nèi)存大小霹琼。

除用戶定義的數(shù)據(jù)和內(nèi)部開銷外,“used_memory_rss”指標(biāo)還包含了內(nèi)存碎片的開銷凉当,內(nèi)存碎片是由操作系統(tǒng)低效的分配除回收物理內(nèi)存得到的枣申。

如內(nèi)存碎片率超過(guò)1.5,可能是操作系統(tǒng)或Redis實(shí)例中內(nèi)存管理變差的表現(xiàn)看杭。

下面列舉3種解決內(nèi)存管理變差并提高Redis性能的方法:

①重啟Redis服務(wù)器

如內(nèi)存碎片率超過(guò)1.5忠藤,重啟Redis服務(wù)器可讓額外產(chǎn)生的內(nèi)存碎片失效并作為新內(nèi)存使用,使操作系統(tǒng)恢復(fù)高效的內(nèi)存管理楼雹。

額外碎片的產(chǎn)生是由于Redis釋放了內(nèi)存塊模孩,但編譯時(shí)制定的內(nèi)存分配器(“l(fā)ibc”、“jemalloc”或“tcmalloc”)并沒(méi)有返回內(nèi)存給操作系統(tǒng)贮缅。

通過(guò)比較“used_memory_peak”榨咐、“used_memory_rss”和“used_memory_metrics”的數(shù)據(jù)指標(biāo)可檢查額外內(nèi)存碎片的占用。如果過(guò)去Redis內(nèi)存使用的峰值“used_memory_peak”和“used_memory_rss”的值大致相等谴供,且二者明顯超過(guò)“used_memory”的值祭芦,則額外的內(nèi)存碎片正在產(chǎn)生。 在“redis-cli”工具上輸入“info memory”可以查看上面三個(gè)指標(biāo)的信息憔鬼。

重啟服務(wù)器前龟劲,需在“redis-cli”工具上輸入“shutdown save”命令,強(qiáng)制讓Redis數(shù)據(jù)庫(kù)執(zhí)行保存操作并關(guān)閉Redis服務(wù)轴或,這樣能保證關(guān)閉Redis時(shí)不丟失任何數(shù)據(jù)昌跌。在重啟后,Redis會(huì)從硬盤上加載持久化的文件照雁,確保數(shù)據(jù)集持續(xù)可用蚕愤。

②限制內(nèi)存交換

如果內(nèi)存碎片率低于1,Redis實(shí)例可能會(huì)把部分?jǐn)?shù)據(jù)交換到硬盤上饺蚊,將嚴(yán)重影響Redis的性能萍诱。我們可以增加可用物理內(nèi)存或減少Redis實(shí)例內(nèi)存占用。具體可查看“used_memory”章節(jié)的優(yōu)化建議污呼。

③修改內(nèi)存分配器

Redis支持“glibc’s malloc”裕坊、“jemalloc11”和“tcmalloc”等幾種不同的內(nèi)存分配器,每個(gè)分配器在內(nèi)存分配和碎片上都有不同的實(shí)現(xiàn)燕酷。

修改Redis默認(rèn)內(nèi)存分配器籍凝,需要完全理解這幾種內(nèi)存分配器的差異周瞎,也需重新編譯Redis,因此饵蒂,不建議普通管理員修改声诸。通過(guò)這個(gè)方法可了解Redis內(nèi)存分配器所做的工作,改善內(nèi)存碎片問(wèn)題退盯。

Redis優(yōu)化總結(jié)

①根據(jù)業(yè)務(wù)需要選擇合適的數(shù)據(jù)類型彼乌,并為不同的應(yīng)用場(chǎng)景設(shè)置相應(yīng)的緊湊存儲(chǔ)參數(shù)。

②若業(yè)務(wù)場(chǎng)景不需要數(shù)據(jù)持久化渊迁,關(guān)閉持久化方式用以提高處理性能及內(nèi)存使用率囤攀。

③不要讓你的Redis所在機(jī)器物理內(nèi)存使用超過(guò)實(shí)際內(nèi)存總量的60%。

④默認(rèn)情況下宫纬,盡量不要讓Redis實(shí)例的客戶端連接數(shù)超出5000

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末焚挠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子漓骚,更是在濱河造成了極大的恐慌蝌衔,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝌蹂,死亡現(xiàn)場(chǎng)離奇詭異噩斟,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)孤个,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門剃允,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人齐鲤,你說(shuō)我怎么就攤上這事斥废。” “怎么了给郊?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵牡肉,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我淆九,道長(zhǎng)统锤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任炭庙,我火速辦了婚禮饲窿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘焕蹄。我一直安慰自己逾雄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嘲驾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪迹卢。 梳的紋絲不亂的頭發(fā)上辽故,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音腐碱,去河邊找鬼誊垢。 笑死,一個(gè)胖子當(dāng)著我的面吹牛症见,可吹牛的內(nèi)容都是我干的喂走。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼谋作,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼芋肠!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起遵蚜,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤帖池,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后吭净,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體睡汹,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年寂殉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了囚巴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡友扰,死狀恐怖彤叉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情村怪,我是刑警寧澤姆坚,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站实愚,受9級(jí)特大地震影響兼呵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜腊敲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一击喂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧碰辅,春花似錦懂昂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)沸柔。三九已至,卻和暖如春铲敛,著一層夾襖步出監(jiān)牢的瞬間褐澎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工伐蒋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留工三,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓先鱼,卻偏偏與公主長(zhǎng)得像俭正,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子焙畔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

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

  • 轉(zhuǎn)載:可能是目前最詳細(xì)的Redis內(nèi)存模型及應(yīng)用解讀 Redis是目前最火爆的內(nèi)存數(shù)據(jù)庫(kù)之一掸读,通過(guò)在內(nèi)存中讀寫數(shù)據(jù)...
    meng_philip123閱讀 1,434評(píng)論 1 22
  • 轉(zhuǎn)載:可能是目前最詳細(xì)的Redis內(nèi)存模型及應(yīng)用解讀 Redis是目前最火爆的內(nèi)存數(shù)據(jù)庫(kù)之一,通過(guò)在內(nèi)存中讀寫數(shù)據(jù)...
    jwnba24閱讀 621評(píng)論 0 4
  • 前言 Redis是目前最火爆的內(nèi)存數(shù)據(jù)庫(kù)之一宏多,通過(guò)在內(nèi)存中讀寫數(shù)據(jù)寺枉,大大提高了讀寫速度,可以說(shuō)Redis是實(shí)現(xiàn)網(wǎng)站...
    Java架構(gòu)閱讀 1,277評(píng)論 1 16
  • 前言 Redis是目前最火爆的內(nèi)存數(shù)據(jù)庫(kù)之一绷落,通過(guò)在內(nèi)存中讀寫數(shù)據(jù)姥闪,大大提高了讀寫速度,可以說(shuō)Redis是實(shí)現(xiàn)網(wǎng)站...
    小陳阿飛閱讀 804評(píng)論 0 1
  • 根據(jù)部分速讀的內(nèi)容砌烁,做出以下閱讀的思想輸出筐喳。 閱讀主題類的書籍表示看了好些本,有《超實(shí)用讀書筆記》《如何閱讀一本書...
    熊編輯閱讀 221評(píng)論 0 1